From f9485760aac48e8a5f929d86accc862030dd04c3 Mon Sep 17 00:00:00 2001 From: Harry Yang <i.take.today@gmail.com> Date: Fri, 30 Dec 2022 00:57:24 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=90=88=E5=90=8C=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=20=E8=AF=A6=E6=83=85=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/backend/ProcessController.java | 72 ++--- .../model/process/ProjectProcessDetail.java | 38 +++ src/main/resources/sql/2.0.sql | 3 + .../admin/business/process-detail.ftl | 302 ++++++++++-------- 4 files changed, 234 insertions(+), 181 deletions(-) create mode 100644 src/main/java/cn/palmte/work/model/process/ProjectProcessDetail.java diff --git a/src/main/java/cn/palmte/work/controller/backend/ProcessController.java b/src/main/java/cn/palmte/work/controller/backend/ProcessController.java index 72308e4..b107991 100644 --- a/src/main/java/cn/palmte/work/controller/backend/ProcessController.java +++ b/src/main/java/cn/palmte/work/controller/backend/ProcessController.java @@ -64,6 +64,7 @@ import cn.palmte.work.model.process.BudgetPurchaseDetail; import cn.palmte.work.model.process.ProcessAttachment; import cn.palmte.work.model.process.ProcurementContract; import cn.palmte.work.model.process.ProjectProcess; +import cn.palmte.work.model.process.ProjectProcessDetail; import cn.palmte.work.model.process.ProjectProcessRepository; import cn.palmte.work.model.process.SaleContract; import cn.palmte.work.model.process.SealTypeArray; @@ -170,6 +171,8 @@ public class ProcessController { @GetMapping("/detail/{id}") public String detail(@PathVariable int id, Model model) { + model.addAttribute("processId", id); + ProjectProcess process = repository.findOne(id); model.addAttribute("process", process); @@ -320,48 +323,41 @@ public class ProcessController { */ @ResponseBody @GetMapping("/{id}") - public ProjectReturnValue get(@PathVariable int id) { + public ProjectProcessDetail get(@PathVariable int id) { + ProjectProcessDetail detail = new ProjectProcessDetail(); + detail.setProcessId(id); + ProjectProcess process = processService.getById(id); + detail.setProcess(process); + Project project = projectRepository.findById(process.getProjectId()); + detail.setProject(project); BigDecimal repaidAmount = getRepaidAmount(id); - Object contract; + detail.setRepaidAmount(repaidAmount); + Object contract = null; + List<SupplierMaterial> supplierMaterials = Collections.emptyList(); List<ProcurementDetail> procurementDetails = Collections.emptyList(); List<ProjectBudgetIncomeDetail> incomeDetails = Collections.emptyList(); - switch (process.getProcessType()) { - case sale_contract: { - contract = processService.findSaleContract(id); - incomeDetails = projectBudgetService.getBudgetIncomeDetail(project); - break; - } - case procurement_contract: { - contract = processService.findProcurementContract(id); - supplierMaterials = processService.getSupplierMaterials(id); - procurementDetails = processService.getProcurementDetails(project.getId(), id); - break; - } - default: - throw new UnsupportedOperationException("还不支持"); + if (process.getProcessType() == ProcessType.sale_contract) { + contract = processService.findSaleContract(id); + incomeDetails = projectBudgetService.getBudgetIncomeDetail(project); + } + else if (process.getProcessType() == ProcessType.procurement_contract) { + contract = processService.findProcurementContract(id); + supplierMaterials = processService.getSupplierMaterials(id); + procurementDetails = processService.getProcurementDetails(project.getId(), id); } - return ProjectReturnValue.builder() - .process(process) - .contract(contract) - .isPrepaid(isPrepaid(project)) - .projectId(project.getId()) - .incomeDetails(incomeDetails) - .projectName(project.getName()) - .repaidAmount(repaidAmount + "元") - .budgetGrossMargin(project.getGrossProfitMargin()) - .projectNo(project.getProjectNo()) - .supplierMaterials(supplierMaterials) - .procurementDetails(procurementDetails) - .contractAmount(project.getContractAmount()) - .applyPersonName(process.getApplyPersonName()) - .terminalCustomer(project.getTerminalCustomer()) - .projectType(Enumerable.of(ProjectType.class, project.getType()).getDescription()) - .cooperationType(Enumerable.of(CooperationType.class, project.getCooperateType()).getDescription()) - .build(); + detail.setContract(contract); + detail.setIncomeDetails(incomeDetails); + detail.setSupplierMaterials(supplierMaterials); + detail.setProcurementDetails(procurementDetails); + detail.setProjectType(Enumerable.of(ProjectType.class, project.getType())); + detail.setCooperationType(Enumerable.of(CooperationType.class, project.getCooperateType())); + List<ProcessAttachment> attachments = JSONArray.parseArray(process.getAttachmentUri(), ProcessAttachment.class); + detail.setAttachments(attachments); + return detail; } // 合同流程 @@ -441,13 +437,7 @@ public class ProcessController { purchaseAmount.setAmountLeft(amountLeft); } - // 复制 - if (purchaseAmount.getId() != null) { - entityManager.merge(purchaseAmount); - } - else { - entityManager.persist(purchaseAmount); - } + entityManager.persist(purchaseAmount); Integer amountId = purchaseAmount.getId(); // ID 自动生成或者使用之前已经有的 // 保存成本对应的 明细 diff --git a/src/main/java/cn/palmte/work/model/process/ProjectProcessDetail.java b/src/main/java/cn/palmte/work/model/process/ProjectProcessDetail.java new file mode 100644 index 0000000..f85c53e --- /dev/null +++ b/src/main/java/cn/palmte/work/model/process/ProjectProcessDetail.java @@ -0,0 +1,38 @@ +package cn.palmte.work.model.process; + +import java.math.BigDecimal; +import java.util.List; + +import cn.palmte.work.model.Project; +import cn.palmte.work.model.ProjectBudgetIncomeDetail; +import cn.palmte.work.model.enums.CooperationType; +import cn.palmte.work.model.enums.ProjectType; +import lombok.Data; + +/** + * @author <a href="https://github.com/TAKETODAY">Harry Yang</a> + * @since 2.0 2022/12/30 00:11 + */ +@Data +public class ProjectProcessDetail { + + private Integer processId; + + private Project project; + private ProjectProcess process; + private ProjectType projectType; + private CooperationType cooperationType; + + private List<ProcessAttachment> attachments; + + private String isPrepaid; + private BigDecimal repaidAmount; + + private Object contract; + + public List<ProjectBudgetIncomeDetail> incomeDetails; + + public List<SupplierMaterial> supplierMaterials; + public List<ProcurementDetail> procurementDetails; + +} diff --git a/src/main/resources/sql/2.0.sql b/src/main/resources/sql/2.0.sql index df76b96..ca73503 100644 --- a/src/main/resources/sql/2.0.sql +++ b/src/main/resources/sql/2.0.sql @@ -83,6 +83,9 @@ create table procurement_contract_budget_purchase_amount UNIQUE key (process_id, budget_cost_id) ) comment '采购合同流程预算采购明细的数量记录'; +alter table procurement_contract_budget_purchase_amount + add amount decimal(11, 2) comment '总共要采购数量' after id; + create table procurement_contract_budget_purchase_detail ( id int auto_increment primary key comment 'ID', diff --git a/src/main/resources/templates/admin/business/process-detail.ftl b/src/main/resources/templates/admin/business/process-detail.ftl index 82d0359..bc6eb40 100644 --- a/src/main/resources/templates/admin/business/process-detail.ftl +++ b/src/main/resources/templates/admin/business/process-detail.ftl @@ -27,9 +27,14 @@ .el-tag--small { margin-right: 5px; } + + [v-cloak] { + display: none; + } + </style> - <div class="admin-content" id="app"> + <div class="admin-content" id="app" v-cloak> <div class="admin-content-body"> <div class="am-cf am-padding"> <div class="am-fl am-cf"><strong class="am-text-primary am-text-lg">业务应用</strong> / @@ -40,23 +45,23 @@ <div class="am-u-sm-12 am-u-md-12"> <el-descriptions title="${process.processType.description}详情"> - <el-descriptions-item label="项目编号">${process.projectNo}</el-descriptions-item> - <el-descriptions-item label="项目标题">${process.projectTitle}</el-descriptions-item> - <el-descriptions-item label="申请时间">${process.applyDate}</el-descriptions-item> + <el-descriptions-item label="项目编号">{{process.projectNo}}</el-descriptions-item> + <el-descriptions-item label="项目标题">{{process.projectTitle}}</el-descriptions-item> + <el-descriptions-item label="申请时间">{{process.applyDate}}</el-descriptions-item> <el-descriptions-item label="项目类型">${projectType}</el-descriptions-item> <el-descriptions-item label="合作类型">${cooperationType}</el-descriptions-item> - <el-descriptions-item label="申请部门">${process.applyDept}</el-descriptions-item> - <el-descriptions-item label="申请人">${process.applyPersonName}</el-descriptions-item> - <el-descriptions-item label="申请部门领导">${process.applyDeptLeaderName}</el-descriptions-item> - <el-descriptions-item label="申请人电话">${contract.applyPersonPhone}</el-descriptions-item> + <el-descriptions-item label="申请部门">{{process.applyDept}}</el-descriptions-item> + <el-descriptions-item label="申请人">{{process.applyPersonName}}</el-descriptions-item> + <el-descriptions-item label="申请部门领导">{{process.applyDeptLeaderName}}</el-descriptions-item> + <el-descriptions-item label="申请人电话">{{contract?.applyPersonPhone}}</el-descriptions-item> - <el-descriptions-item label="合同编号">${process.contractNo}</el-descriptions-item> - <el-descriptions-item label="合同名称">${process.contractName}</el-descriptions-item> - <el-descriptions-item label="合同金额">${project.contractAmount}</el-descriptions-item> + <el-descriptions-item label="合同编号">{{process.contractNo}}</el-descriptions-item> + <el-descriptions-item label="合同名称">{{process.contractName}}</el-descriptions-item> + <el-descriptions-item label="合同金额">{{project.contractAmount}}</el-descriptions-item> - <el-descriptions-item label="客户名称">${contract.clientName}</el-descriptions-item> - <el-descriptions-item label="最终用户名称">${project.terminalCustomer}</el-descriptions-item> + <el-descriptions-item label="客户名称">{{contract.clientName}}</el-descriptions-item> + <el-descriptions-item label="最终用户名称">{{project.terminalCustomer}}</el-descriptions-item> <el-descriptions-item label="用印类型"> <#list process.sealTypes.list as item> @@ -64,155 +69,112 @@ </#list> </el-descriptions-item> - <el-descriptions-item label="税率">${process.taxRate}%</el-descriptions-item> - <el-descriptions-item label="是否垫资">${isPrepaid}</el-descriptions-item> + <el-descriptions-item label="税率">{{process.taxRate}}%</el-descriptions-item> + <el-descriptions-item label="是否垫资">{{isPrepaid}}</el-descriptions-item> <el-descriptions-item label="垫资金额">${repaidAmount}元</el-descriptions-item> - <el-descriptions-item label="预算毛利率">${project.grossProfitMargin}</el-descriptions-item> + <el-descriptions-item label="预算毛利率">{{project.grossProfitMargin}}</el-descriptions-item> - <el-descriptions-item label="收款条件">${contract.paymentTerms}</el-descriptions-item> - <el-descriptions-item label="备注">${process.remark}</el-descriptions-item> + <el-descriptions-item label="收款条件">{{contract.paymentTerms}}</el-descriptions-item> + <el-descriptions-item label="备注">{{process.remark}}</el-descriptions-item> <el-descriptions-item label="附件"> - <#list attachments as attachment> - <el-tag size="small"> - <a href="${attachment.uri}"> - <i class="el-icon-document"></i> ${attachment.name} - </a> - </el-tag> - </#list> + <el-tag size="small" v-for="attachment in attachments"> + <a :href="attachment.uri"> + <i class="el-icon-document"></i> {{attachment.name}} + </a> + </el-tag> </el-descriptions-item> </el-descriptions> - <#-- - <el-form :inline="true" ref="saleContractProcessForm" :model="processForm" label-position="right" label-width="100px"> + <#-- 项目预算收入明细表 --> + <div> + <el-alert title="项目预算收入明细" type="success" center :closable="false"></el-alert> - <div class="am-form-inline"> + <el-table border :data="incomeDetails" empty-text="暂无"> + <el-table-column type="index" :index="1" label="序号" fixed></el-table-column> + <el-table-column prop="name" label="名称" fixed width="120"></el-table-column> + <el-table-column prop="type" label="类别"></el-table-column> + <el-table-column prop="spec" label="规格型号"></el-table-column> + <el-table-column prop="param" label="参数"></el-table-column> + <el-table-column prop="amount" label="数量"></el-table-column> + <el-table-column prop="unit" label="单位"></el-table-column> + <el-table-column prop="price" label="单价(元)" width="120"></el-table-column> + <el-table-column prop="taxRate" label="税率(%)"></el-table-column> + <el-table-column prop="totalTaxInclude" label="含税金额(元)" width="120"></el-table-column> + <el-table-column prop="totalTaxExclude" label="不含税金额(元)" width="120"></el-table-column> + <el-table-column prop="totalTax" label="税金(元)" width="120"></el-table-column> + <el-table-column prop="expirationDate" label="质保期" width="150"></el-table-column> - <el-form-item label="项目编号"> - <span>${process.projectNo}</span> - </el-form-item> + </el-table> - <el-tooltip effect="light" :content="projectTitle" placement="top-start"> - <el-form-item label="项目标题"> - <span>${process.projectTitle}</span> - </el-form-item> - </el-tooltip> + </div> - <el-form-item label="申请时间"> - <span>${process.applyDate}</span> - </el-form-item> + <#-- 供应商比选材料 --> - <el-form-item label="项目类型"> - <span>${projectType}</span> - </el-form-item> + <div> + <el-alert title="供应商比选材料" type="success" center :closable="false"></el-alert> + <el-table border :data="supplierMaterials" empty-text="暂无"> + <el-table-column type="index" :index="1" label="序号" fixed></el-table-column> - <el-form-item label="合作类型"> - <span>${cooperationType}</span> - </el-form-item> + <el-table-column prop="companyName" label="公司名称" width="180" align="center"></el-table-column> + <el-table-column prop="totalAmount" label="合计金额" width="160" align="center"></el-table-column> + <el-table-column prop="serviceTerms" label="服务条款" width="180" align="center"></el-table-column> + <el-table-column prop="paymentTerms" label="付款条件" align="center"></el-table-column> + <el-table-column prop="taxRate" label="税率(%)" width="160" align="center"></el-table-column> + <el-table-column prop="remark" label="备注" align="center"></el-table-column> + <el-table-column prop="attachment" label="附件" align="center" width="150"> + <template slot-scope="scope"> + <el-tag size="small" v-if="scope.row.attachment"> + <a :href="scope.row.attachment.uri"> + <i class="el-icon-document"></i> {{scope.row.attachment.name}} + </a> + </el-tag> + </template> + </el-table-column> - </div> + </el-table> - <div> + </div> - <el-form-item label="申请部门"> - <span>${process.applyDept}</span> - </el-form-item> + <#-- 采购详情 --> + <div> + <el-alert title="采购清单" type="success" center :closable="false"></el-alert> - <el-form-item label="申请人"> - <span>${process.applyPersonName}</span> - </el-form-item> + <el-table border :data="procurementDetails" empty-text="暂无"> + <el-table-column type="index" :index="1" label="序号" fixed></el-table-column> + <el-table-column prop="feeType" label="费用项目" fixed width="80"></el-table-column> + <el-table-column prop="name" label="产品名称" fixed></el-table-column> + <el-table-column prop="category" label="采购类别" fixed></el-table-column> - <el-form-item label="申请部门领导"> - <span>${process.applyDeptLeaderName}</span> - </el-form-item> + <el-table-column prop="amount" label="数量"></el-table-column> + <el-table-column prop="unit" label="单位"></el-table-column> + <el-table-column prop="price" label="预算单价" width="100"></el-table-column> + <el-table-column prop="taxRate" label="税率(%)"></el-table-column> + <el-table-column prop="totalTaxInclude_" label="含税总金额(元)" width="120"></el-table-column> + <el-table-column prop="totalTaxExclude" label="不含税金额(元)" width="120"></el-table-column> + <el-table-column prop="totalTax" label="税金(元)" width="110"></el-table-column> + <el-table-column prop="isUnderwritten" label="是否垫资"></el-table-column> + <el-table-column prop="payTime" label="支出时间" width="160"></el-table-column> + <el-table-column prop="payAmount" label="支出金额(元)" width="120"></el-table-column> + <el-table-column prop="amountAlready" label="已采购数量" width="100"></el-table-column> + <el-table-column prop="amountCurrent" label="本次采购数量" width="180"></el-table-column> + <el-table-column prop="amountLeft" label="未采购数量" width="100"></el-table-column> - <el-form-item label="申请人电话" prop="applyPersonPhone"> - <span>${contract.applyPersonPhone}</span> - </el-form-item> + <el-table-column prop="supplierName" label="供应商名称" width="200"></el-table-column> + <el-table-column prop="manufacturerName" label="设备厂商名称" width="200"></el-table-column> + <el-table-column prop="purchaseList" label="对应采购清单" width="200"></el-table-column> + <el-table-column prop="spec" label="规格型号" width="200"></el-table-column> + <el-table-column prop="procurementAmount" label="对应采购数目" width="200"></el-table-column> + <el-table-column prop="procurementPrice" label="采购单价" width="200"></el-table-column> + <el-table-column prop="totalTaxInclude" label="含税总金额(元)" width="200"></el-table-column> - </div> + </el-table> - <div> + </div> - <el-form-item label="合同编号"> - <span>${process.contractNo}</span> - </el-form-item> - - <el-form-item label="合同名称"> - <span>${process.contractName}</span> - </el-form-item> - - <el-form-item label="合同金额"> - <span>${project.contractAmount}</span> - </el-form-item> - - </div> - - <div> - <el-form-item label="客户名称"> - <span>${contract.clientName}</span> - </el-form-item> - - <el-form-item label="最终用户名称"> - <span>${project.terminalCustomer}</span> - </el-form-item> - </div> - - <div> - <el-form-item label="用印类型"> - <#list process.sealTypes.sealTypes as item> - <el-tag size="small">${item.description}</el-tag> - </#list> - </el-form-item> - </div> - - <div> - - <el-form-item label="税率"> - <span>${process.taxRate}%</span> - </el-form-item> - - <el-form-item label="是否垫资"> - <span>${isPrepaid}</span> - </el-form-item> - - <el-form-item label="垫资金额"> - <span>${repaidAmount}元</span> - </el-form-item> - - <el-form-item label="预算毛利率"> - <span>${project.grossProfitMargin}</span> - </el-form-item> - - </div> - - <div> - <el-form-item label="收款条件"> - <div>${contract.paymentTerms}</div> - </el-form-item> - </div> - - <div> - <el-form-item label="备注"> - <div>${process.remark}</div> - </el-form-item> - </div> - - <div> - <el-form-item label="附件"> - <#list attachments as attachment> - <a href="${attachment.uri}"> - <i class="el-icon-document"></i> ${attachment.name} - </a> - </#list> - </el-form-item> - </div> - - </el-form> ---> <el-row> - <el-button type="info" @click="backLastPage">返回上一级</el-button> + <el-button style="margin-top: 30px" type="info" @click="backLastPage">返回上一级</el-button> </el-row> </div> @@ -245,19 +207,79 @@ } const data = () => { - return {} + return { + process: {}, + project: {}, + supplierMaterials: [] + } } const methods = { backLastPage() { window.history.back(); - } + }, + loadProject(id) { + const loading = this.$loading({ + lock: true, + text: '正在加载项目', + spinner: 'el-icon-loading', + background: 'rgba(0, 0, 0, 0.7)' + }) + + fetch("${base}/process/" + id) + .then(res => res.json()) + .then(data => { + const { + attachments, processId, isPrepaid, repaidAmount, + incomeDetails, process, projectType, cooperationType, + contract, supplierMaterials, procurementDetails, project + } = data + // 转换数据 + // @formatter:off + const computeType = (type) => { + switch (type) { + case 1: return '设备' + case 2: return '工程' + case 3: return '服务' + default: return '未知' + } + } + // @formatter:on + + this.incomeDetails = incomeDetails.map(detail => ({ + ...detail, type: computeType(detail.type) + })) + + this.process = process + this.project = project + this.isPrepaid = isPrepaid + this.repaidAmount = repaidAmount + this.contract = contract + this.processId = processId + this.projectType = projectType + this.cooperationType = cooperationType + this.supplierMaterials = supplierMaterials + this.procurementDetails = procurementDetails + + this.attachments = attachments + }) + .catch(err => { + this.$message.error("项目加载失败"); + }) + .finally(() => loading.close()) + }, + } new Vue({ el: '#app', data, methods, + + mounted() { + const processId = ${processId} + this.loadProject(processId) + }, }) </script>