销售合同流程 前端展示优化

master
Harry Yang 2022-12-14 16:07:26 +08:00
parent 3204b10b5f
commit df5373799f
8 changed files with 271 additions and 33 deletions

View File

@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.LocalDate;
@ -22,13 +23,19 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import cn.palmte.work.model.Admin;
import cn.palmte.work.model.DeptRepository;
import cn.palmte.work.model.Project;
import cn.palmte.work.model.ProjectBudgetIncomeDetail;
import cn.palmte.work.model.ProjectRepository;
import cn.palmte.work.model.enums.CooperationType;
import cn.palmte.work.model.enums.Enumerable;
import cn.palmte.work.model.enums.ProcessStatus;
import cn.palmte.work.model.enums.ProjectType;
import cn.palmte.work.model.enums.SealType;
import cn.palmte.work.service.ProjectBudgetService;
import cn.palmte.work.utils.InterfaceUtil;
import lombok.Builder;
import lombok.Setter;
/**
@ -113,32 +120,53 @@ public class ProcessController {
.collect(Collectors.toList());
}
@Builder
public static class ProjectReturnValue {
public final String applyDate = LocalDate.now().format(formatter);
public String projectNo;
public Integer projectId;
public String projectName;
// 申请人
public String applyPersonName;
// 项目类型
public String projectType;
// 合作类型
public String cooperationType;
// 合同金额
public String contractAmount;
public BigDecimal contractAmount;
// FIXME 垫资
// 是否垫资
public final String isPrepaid = "是";
// 垫资金额
public final String repaidAmount = "50000元";
// 预算毛利率
public final String budgetGrossMargin = "3.9%";
}
@ResponseBody
@GetMapping("/projects/{id}")
public Project query(@PathVariable int id) {
Project byId = projectRepository.findById(id);
public ProjectReturnValue query(@PathVariable int id) {
Project project = projectRepository.findById(id);
Admin admin = InterfaceUtil.getAdmin();
// projectType
// cooperationType
return byId;
// 可以在对应表数据查询 是否存在再启用
return ProjectReturnValue.builder()
.projectId(project.getId())
.projectName(project.getName())
.projectNo(project.getProjectNo())
.applyPersonName(admin.getRealName())
.contractAmount(project.getContractAmount())
.projectType(Enumerable.of(ProjectType.class, project.getType()).getDescription())
.cooperationType(Enumerable.of(CooperationType.class, project.getCooperateType()).getDescription())
.build();
}
// 销售合同流程
@ -188,8 +216,6 @@ public class ProcessController {
// 税率
public String taxRate;
// 是否垫资
// 收款条件
public String paymentTerms;

View File

@ -0,0 +1,30 @@
package cn.palmte.work.model.enums;
/**
* 12
*
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
* @since 1.0 2022/12/14 15:20
*/
public enum CooperationType implements Enumerable<Integer> {
STRATEGIC_COOPERATION(1, "战略合作"),
NOT_STRATEGIC_COOPERATION(2, "战略合作");
private final int value;
private final String description;
CooperationType(int value, String description) {
this.value = value;
this.description = description;
}
public String getDescription() {
return description;
}
@Override
public Integer getValue() {
return value;
}
}

View File

@ -0,0 +1,12 @@
package cn.palmte.work.model.enums;
/**
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
*/
public interface Descriptive {
/**
* Return a description
*/
String getDescription();
}

View File

@ -0,0 +1,106 @@
package cn.palmte.work.model.enums;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
/**
* Enumerable for {@link Enum}
*
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
*/
public interface Enumerable<V> extends Descriptive {
@SuppressWarnings("unchecked")
default V getValue() {
return (V) name();
}
@Override
default String getDescription() {
return name();
}
/**
* The default name of the enumeration, this method does not need
* to be implemented, the enumeration class is automatically inherited
*/
String name();
/**
* Returns Enumerable by {@link Enumerable#getValue() enum value}
*
* @param enumerable enum
* @param value enumeration value
* @param <T> enumeration type
* @param <V> enumeration value type
* @return enumeration instance
* @throws NullPointerException if enumerable is {@code null}
* @see Enumerable#getValue()
*/
// @Nullable
static <T extends Enumerable<V>, V> T of(Class<T> enumerable, /*@Nullable*/ V value) {
if (value != null) {
T[] enumConstants = enumerable.getEnumConstants();
if (enumConstants != null) {
for (T constant : enumConstants) {
if (Objects.equals(value, constant.getValue())) {
return constant;
}
}
}
}
return null;
}
/**
* Get the value corresponding to the name
*
* @param enumerable enumeration class
* @param name enumeration name
* @param <T> enum type
* @param <V> enumeration value type
* @return enumeration value
* @see Enumerable#getValue()
*/
// @Nullable
static <T extends Enumerable<V>, V> V getValue(Class<T> enumerable, String name) {
T[] enumConstants = enumerable.getEnumConstants();
if (enumConstants != null) {
for (T constant : enumConstants) {
if (Objects.equals(name, constant.name())) {
return constant.getValue();
}
}
}
return null;
}
/**
* @param <T> enum type
* @param <V> enumeration value type
* @param defaultValue default value
* @see #of(Class, V)
*/
static <T extends Enumerable<V>, V> T of(Class<T> enumerable, V value, Supplier<T> defaultValue) {
return find(enumerable, value).orElseGet(defaultValue);
}
/**
* @param defaultValue default value
* @param <T> enum type
* @param <V> enumeration value type
* @see #of(Class, V)
*/
static <T extends Enumerable<V>, V> T of(Class<T> enumerable, V value, T defaultValue) {
return find(enumerable, value).orElse(defaultValue);
}
/**
* @return Optional of T
*/
static <T extends Enumerable<V>, V> Optional<T> find(Class<T> enumerable, V value) {
return Optional.ofNullable(of(enumerable, value));
}
}

View File

@ -4,9 +4,20 @@ package cn.palmte.work.model.enums;
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
* @since 1.0 2022/12/13 16:12
*/
public enum ProcessStatus {
public enum ProcessStatus implements Enumerable<String> {
draft("草稿"),
completed("完成");
private final String description;
ProcessStatus(String description) {
this.description = description;
}
@Override
public String getDescription() {
return description;
}
draft,
completed
;
}

View File

@ -0,0 +1,32 @@
package cn.palmte.work.model.enums;
/**
* 1 23
*
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
* @since 1.0 2022/12/14 15:10
*/
public enum ProjectType implements Enumerable<Integer> {
ENGINEERING_INTEGRATION(1, "工程集成"),
DEVICE_INTEGRATION(2, "设备集成"),
STRATEGIC_COOPERATION(3, "战略合作");
private final int value;
private final String description;
ProjectType(int value, String description) {
this.value = value;
this.description = description;
}
public String getDescription() {
return description;
}
@Override
public Integer getValue() {
return value;
}
}

View File

@ -6,7 +6,7 @@ package cn.palmte.work.model.enums;
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
* @since 1.0 2022/12/13 15:25
*/
public enum SealType {
public enum SealType implements Enumerable<String> {
// "公章"
// "法人章"
@ -34,6 +34,7 @@ public enum SealType {
this.description = description;
}
@Override
public String getDescription() {
return description;
}

View File

@ -76,26 +76,33 @@
<div class="am-form-inline">
<el-tooltip :disabled="projectSelected" effect="light" content="项目编号或名称,支持模糊查询" placement="top-end">
<el-form-item label="项目编号">
<el-autocomplete v-model="processForm.projectNo" :fetch-suggestions="queryProject"
value-key="name" placeholder="请输入项目编号或名称" @select="handleSelectProject">
<el-autocomplete v-model="processForm.projectNo" :fetch-suggestions="queryProject" clearable
value-key="name" placeholder="请输入项目编号或名称" @select="handleSelectProject"
@clear="clearProjectProcess">
</el-autocomplete>
</el-form-item>
</el-tooltip>
<el-form-item label="项目标题">
<el-input placeholder="请输入内容" :disabled="projectSelected" :value="projectTitle" clearable></el-input>
</el-form-item>
<el-tooltip :disabled="!projectSelected" effect="light" :content="projectTitle" placement="top-start">
<el-form-item label="项目标题">
<span v-if="projectSelected">{{projectTitle}}</span>
<span v-else>未选择项目</span>
</el-form-item>
</el-tooltip>
<el-form-item label="申请时间">
<el-input placeholder="请输入内容" :disabled="projectSelected" v-model="processForm.applyDate"></el-input>
<span v-if="projectSelected">{{processForm.applyDate}}</span>
<span v-else>未选择项目</span>
</el-form-item>
<el-form-item label="项目类型">
<el-input placeholder="请输入内容" :disabled="projectSelected" v-model="processForm.projectType"></el-input>
<span v-if="projectSelected">{{processForm.projectType}}</span>
<span v-else>未选择项目</span>
</el-form-item>
<el-form-item label="合作类型">
<el-input placeholder="请输入内容" :disabled="projectSelected" v-model="processForm.cooperationType"></el-input>
<span v-if="projectSelected">{{processForm.cooperationType}}</span>
<span v-else>未选择项目</span>
</el-form-item>
</div>
@ -107,11 +114,13 @@
</el-form-item>
<el-form-item label="申请人">
<el-input placeholder="请输入内容" :disabled="projectSelected" v-model="processForm.cooperateTypeStr"></el-input>
<span v-if="projectSelected">{{processForm.applyPersonName}}</span>
<span v-else>未选择项目</span>
</el-form-item>
<el-form-item label="申请部门领导">
<el-input placeholder="请输入内容" :disabled="projectSelected" v-model="processForm.cooperateTypeStr"></el-input>
<span v-if="projectSelected">{{processForm.applyDeptLeaderName}}</span>
<span v-else>未选择部门</span>
</el-form-item>
<el-form-item label="申请人电话" :rules="[{ required: true, message: '申请人电话不能为空'}]" prop="applyPersonPhone">
@ -131,18 +140,21 @@
</el-form-item>
<el-form-item label="合同金额">
<el-input placeholder="请输入内容" :disabled="projectSelected" v-model="processForm.contractAmount"></el-input>
<span v-if="projectSelected">{{processForm.contractAmount}}元</span>
<span v-else>未选择项目</span>
</el-form-item>
</div>
<div>
<el-form-item label="客户名称" :rules="[{ required: true, message: '客户名称不能为空'}]">
<el-input placeholder="请输入客户名称" v-model="processForm.contractNumber"></el-input>
<el-input placeholder="请输入客户名称" v-model="processForm.clientName"></el-input>
</el-form-item>
<el-form-item label="最终用户名称">
<el-input placeholder="请输入最终用户名称" v-model="processForm.contractName"></el-input>
<#--TODO 最终用户名称-->
<span v-if="projectSelected">{{processForm.finalUserName}}</span>
<span v-else>未选择项目</span>
</el-form-item>
</div>
@ -167,15 +179,18 @@
</el-form-item>
<el-form-item label="是否垫资">
<el-input placeholder="请输入最终用户名称" v-model="processForm.contractName"></el-input>
<span v-if="projectSelected">{{processForm.isPrepaid}}</span>
<span v-else>未选择项目</span>
</el-form-item>
<el-form-item label="垫资金额">
<el-input value="50000元"></el-input>
<span v-if="projectSelected">{{processForm.repaidAmount}}</span>
<span v-else>未选择项目</span>
</el-form-item>
<el-form-item label="预算毛利率">
<el-input value="3.91%"></el-input>
<span v-if="projectSelected">{{processForm.budgetGrossMargin}}</span>
<span v-else>未选择项目</span>
</el-form-item>
</div>
@ -715,6 +730,12 @@
})
.finally(() => loading.close())
},
clearProjectProcess() {
this.projectSelected = false
this.processForm = {
sealType: []
}
},
saveDraft() {
this.processForm.status = 'draft'
@ -807,9 +828,9 @@
data,
computed: {
projectTitle() {
const { projectNo, name, applyPerson, applyDate } = this.processForm
if (projectNo && name) {
return projectNo.trim() + "-" + name.trim() + "-" + applyPerson + "-" + applyDate
const { projectNo, projectName, applyPersonName, applyDate } = this.processForm
if (projectNo && projectName) {
return projectNo.trim() + "-" + projectName.trim() + "-" + applyPersonName + "-" + applyDate
}
return ""
},
@ -848,7 +869,6 @@
this.processForm = {
sealType: [],
projectId: 135,
applyDate: new Date().toLocaleDateString(),
...data
}
this.projectSelected = true