采购合同流程 前端

前端使用本地 vuejs element-ui
采购合同流程界面
master
Harry Yang 2022-12-29 22:36:54 +08:00
parent 2871a53d95
commit ff9cd81155
11 changed files with 12121 additions and 41 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
<#assign base=request.contextPath />
<#import "../../common/defaultLayout.ftl" as defaultLayout>
<@defaultLayout.layout>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<link rel="stylesheet" href="${base}/element-ui/element-ui.css">
<style>
.el-upload__input {
@ -148,8 +148,8 @@
</div>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="${base}/vue/vue.js"></script>
<script src="${base}/element-ui/element-ui.js"></script>
<script>

View File

@ -1,7 +1,7 @@
<#assign base=request.contextPath />
<#import "../../common/defaultLayout.ftl" as defaultLayout>
<@defaultLayout.layout>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<link rel="stylesheet" href="${base}/element-ui/element-ui.css">
<style>
.el-upload__input {
@ -223,8 +223,8 @@
</div>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="${base}/vue/vue.js"></script>
<script src="${base}/element-ui/element-ui.js"></script>
<script>

View File

@ -1,8 +1,7 @@
<#assign base=request.contextPath />
<#import "../../common/defaultLayout.ftl" as defaultLayout>
<@defaultLayout.layout>
<#-- <link rel="stylesheet" href="../assets/css/amazeui.switch.css"/>-->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<link rel="stylesheet" href="${base}/element-ui/element-ui.css">
<style>
#businessPurchaseDetailsModal {
@ -393,8 +392,8 @@
</div>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="${base}/vue/vue.js"></script>
<script src="${base}/element-ui/element-ui.js"></script>
<script>

View File

@ -1,8 +1,7 @@
<#assign base=request.contextPath />
<#import "../../common/defaultLayout.ftl" as defaultLayout>
<@defaultLayout.layout>
<#-- <link rel="stylesheet" href="../assets/css/amazeui.switch.css"/>-->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<link rel="stylesheet" href="${base}/element-ui/element-ui.css">
<style>
#businessPurchaseDetailsModal {
@ -60,6 +59,15 @@
.supplierChoose .el-alert {
border-radius: unset;
}
.el-table .warning-row {
background: oldlace;
}
.el-table .child-row {
background: #f0f9eb;
}
</style>
<div class="admin-content" id="app">
@ -101,7 +109,7 @@
</div>
</el-dialog>
<el-dialog title="预算采购明细" :visible="procurementDetailSelectorVisible" v-cloak width="90%" :close-on-click-modal="false">
<el-dialog title="预算采购明细" :visible="procurementDetailSelectorVisible" v-cloak width="90%" :close-on-click-modal="false">
<el-table border :data="procurementDetails">
<el-table-column type="index" :index="1" label="序号" fixed></el-table-column>
@ -138,7 +146,7 @@
</el-table>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="saveProcurementDetail">下一步</el-button>
<el-button type="primary" @click="filterProcurementDetails">下一步</el-button>
</div>
</el-dialog>
@ -469,9 +477,9 @@
<#-- 选择 业务采购清单明细 -->
<div v-cloak class="am-u-sm-12 am-u-md-12" v-if="isProcurementContractDetailMode">
<el-table style="width: 100%" border :data="procurementDetails">
<el-table border :data="procurementDetails" row-key="rowKey" default-expand-all :row-class-name="procurementDetailRowClassName">
<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="feeType" label="费用项目" width="100" fixed></el-table-column>
<el-table-column prop="name" label="产品名称" fixed></el-table-column>
<el-table-column prop="category" label="采购类别" fixed></el-table-column>
@ -488,7 +496,8 @@
<el-table-column prop="amountAlready" label="已采购数量" width="100"></el-table-column>
<el-table-column prop="amountCurrent" label="本次采购数量" width="180">
<template slot-scope="scope">
<el-input-number :precision="2" :step="0.1" :min="0" v-model="scope.row.amountCurrent"
<span v-if="scope.row.newRow">{{scope.row.parent.amountCurrent}}</span>
<el-input-number v-else :precision="2" :step="0.1" :min="0" v-model="scope.row.amountCurrent"
:disabled="scope.row.amount - scope.row.amountAlready===0" size="mini"
:max="scope.row.amount - scope.row.amountAlready" controls-position="right">
</el-input-number>
@ -540,11 +549,23 @@
</template>
</el-table-column>
<el-table-column width="49" fixed="right">
<template slot-scope="scope">
<el-popconfirm v-if="scope.row.newRow" title="确定删除吗?填写的表单将丢弃" @confirm="removeProcurementDetailRow(scope)">
<el-button slot="reference" type="danger" icon="el-icon-delete" circle size="mini"></el-button>
</el-popconfirm>
<el-button v-else type="primary" icon="el-icon-plus" circle size="mini"
@click="addProcurementDetailRow(scope)"></el-button>
</template>
</el-table-column>
</el-table>
<el-row style="margin: 20px 0">
<el-button type="info" @click="goToProcurementContract">返回上一级</el-button>
<el-button type="primary" @click="goToProcurementContract">保存并返回上一级</el-button>
<el-button type="primary" @click="saveProcurementContractDetail">保存并返回上一级</el-button>
</el-row>
</div>
@ -555,8 +576,8 @@
</div>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="${base}/vue/vue.js"></script>
<script src="${base}/element-ui/element-ui.js"></script>
<script>
@ -568,8 +589,28 @@
const saleContract = "sale_contract"
const procurementContract = "procurement_contract"
const procurementDetailProperties = [
"spec",
"amount",
"purchaseList",
"amountAlready",
"amountCurrent",
"supplierName",
"totalTaxInclude",
"manufacturerName",
"procurementPrice",
"procurementAmount"
]
const isEmpty = (obj) => {
return !obj || (obj.length && obj.length === 0)
if (!obj) {
return true
}
if (obj.hasOwnProperty('length')) {
return obj.length === 0
}
return false
}
const isNotEmpty = (obj) => {
@ -597,9 +638,11 @@
// 销售合同收入明细
incomeDetails: [],
procurementDetails: [],
filteredProcurementDetails: [],
processType: "",
procurementProjectSelectorVisible: false,
procurementDetailSelectorVisible: false
procurementDetailSelectorVisible: false,
procurementDetailsRowKey: 0,
}
}
@ -626,17 +669,20 @@
}
},
saveProcurementDetail() {
/**
* 过滤本次流程要填写的采购清单
*/
filterProcurementDetails() {
this.procurementDetailSelectorVisible = false
this.changeMode(procurementContractProcess)
this.processType = procurementContract
this.procurementDetails = this.procurementDetails.filter(detail => {
if (detail.amountCurrent) {
return detail.amountCurrent !== 0;
}
return false
const procurementDetails = this.procurementDetails.filter(detail => {
return detail.amountCurrent && detail.amountCurrent !== 0;
})
this.procurementDetails = procurementDetails
// 保留副本,提交订单的时候构建表单的时候用
this.filteredProcurementDetails = [...procurementDetails]
},
goToHome() {
@ -672,6 +718,32 @@
this.processType = procurementContract
},
/**
* 校验不通过提示
* @returns {boolean} 校验通过否
*/
checkProcurementDetails() {
const emptyRows = this.procurementDetails.filter(detail => {
return isNotEmpty(procurementDetailProperties.filter(property => isBlank(detail[property])))
})
console.log(emptyRows)
if (isNotEmpty(emptyRows)) {
const row = emptyRows[0]
this.$message.error("合同清单明细 费用项目为:'" + row.feeType + "' 采购类别为:'" + row.category + "' 的数据未填写")
return false
}
return true
},
/**
* 保存 业务采购合同清单明细,并验证表单是否填写完整,
* 如果完整就到流程表单界面
*/
saveProcurementContractDetail() {
if (this.checkProcurementDetails()) {
this.goToProcurementContract()
}
},
goToContractDetail() {
const { projectId } = this.processForm
if (projectId) {
@ -701,7 +773,11 @@
initForm(form) {
this.processForm = { ...form, sealTypes: [], projectTitle: this.computeProjectTitle(form) }
},
/**
* 搜索项目
* @param q 用户输入的字符串
* @param callback 查询成功的回调
*/
queryProject(q, callback) {
if (isBlank(q)) {
callback([])
@ -722,8 +798,11 @@
this.$message.error('项目搜索失败');
})
},
handleSelectProject(selected) {
const { id, name } = selected
/**
* 加载选择的项目数据,填写表单需要一些初始数据
* @param selected 选择的项目信息包含IDname 字段
*/
handleSelectProject({ id, name }) {
if (!id) {
this.initForm(this.processForm)
return
@ -735,7 +814,7 @@
background: 'rgba(0, 0, 0, 0.7)'
})
fetch("${base}/process/projects/" + id)
fetch("${base}/process/projects/" + id + "?processType=" + this.processType)
.then(res => res.json())
.then(data => {
const { incomeDetails, procurementDetails, ...form } = data
@ -763,16 +842,20 @@
this.initForm(form)
this.projectSelected = true
this.incomeDetails = incomeDetails.map(detail => ({
this.incomeDetails = incomeDetails && incomeDetails.map(detail => ({
...detail, type: computeType(detail.type)
}))
this.procurementDetails = procurementDetails.map(detail => ({
let rowKey = 0
this.procurementDetails = procurementDetails && procurementDetails.map(detail => ({
...detail, feeType: computeFeeType(detail.type),
totalTaxInclude_: detail.totalTaxInclude, totalTaxInclude: null, // 存在相同字段转换一下
isUnderwritten: detail.isUnderwritten === 1 ? "是" : "否"
totalTaxInclude_: detail.totalTaxInclude, totalTaxInclude: undefined, // 存在相同字段转换一下
isUnderwritten: detail.isUnderwritten === 1 ? "是" : "否",
rowKey: rowKey++, children: []
}))
this.procurementDetailsRowKey = rowKey
if (!form.projectNo || !form.projectName) {
this.$message.warning("当前选择的项目没有编号或者名称");
}
@ -816,6 +899,7 @@
}
let validStatus = !needValid
if (needValid) {
// 校验表单
this.$refs["contractProcessForm"].validate((valid) => {
if (valid) {
if (fileList.length === 0) {
@ -823,11 +907,16 @@
return false
}
if (processType === saleContract) {
this.checkExpirationDate()
if (!this.checkExpirationDate()) {
return false
}
}
// 采购合同需要验证 供应商比选材料
if (processType === procurementContract) {
if (!this.checkProcurementDetails()) {
return false
}
const { procurementMode } = processForm
// specify_purchase("指定采购"),
@ -872,6 +961,8 @@
this.$message.error("申请部门还未选择");
return false
}
// 验证通过
validStatus = true
return true;
}
@ -885,6 +976,7 @@
if (!validStatus) {
return false
}
// 提交
const loading = this.$loading({
lock: true,
@ -893,6 +985,30 @@
background: 'rgba(0, 0, 0, 0.7)'
})
const budgetCostIdMap = new Map()
this.procurementDetails.forEach(detail => {
budgetCostIdMap.set(detail.budgetCostId, detail)
})
debugger
const computePurchaseAmountDetail = budgetCostId => {
const detail = budgetCostIdMap.get(budgetCostId)
const ret = []
const map = detail => {
const ret = {}
procurementDetailProperties.forEach(property => {
ret[property] = detail[property]
})
return ret
}
ret.push(map(detail))
detail.children.forEach(detail => {
ret.push(map(detail))
})
return ret
}
const applyDeptId = processForm.applyDeptId?.join(',') // (逗号分割)
const form = {
...processForm,
@ -905,6 +1021,13 @@
supplierMaterials: this.supplierMaterialsForm,
incomeDetails: this.incomeDetails.map(detail => ({
id: detail.id, expirationDate: detail.expirationDate
})),
purchaseAmount: this.filteredProcurementDetails.map(detail => ({
amount: detail.amount,
budgetCostId: detail.budgetCostId,
amountAlready: detail.amountAlready,
amountCurrent: detail.amountCurrent,
details: computePurchaseAmountDetail(detail.budgetCostId)
}))
}
@ -934,7 +1057,7 @@
const emptyRows = this.incomeDetails.filter(detail => isBlank(detail.expirationDate))
if (isNotEmpty(emptyRows)) {
const row = emptyRows[0]
this.$message.error("名称为:'" + row.name + "' 类别为:'" + row.type + "' 的质保期未填写")
this.$message.error("合同清单明细 名称为:'" + row.name + "' 类别为:'" + row.type + "' 的质保期未填写")
return false
}
return true
@ -976,6 +1099,41 @@
this.supplierMaterialsForm.push({})
},
addProcurementDetailRow(scope) {
const { row } = scope
const { children } = row
const newRow = {
...row,
rowKey: this.procurementDetailsRowKey++,
newRow: true,
parent: row // 记录上一级元素,在删除的时候使用
}
delete newRow['children']
if (children) {
row['children'].push(newRow)
}
else {
row['children'] = [newRow]
}
scope.store.table.toggleRowExpansion(row, true)
},
removeProcurementDetailRow(scope) {
const { rowKey, parent } = scope.row
parent.children = parent.children.filter(child => child.rowKey !== rowKey)
},
// 区别子项
procurementDetailRowClassName({ row, rowIndex }) {
if (row.parent) {
// 有父项说明就是子项
return 'child-row';
}
return '';
},
applyDeptSelected(value) {
if (value.length === 0) {
this.processForm['applyDept'] = null
@ -1053,6 +1211,7 @@
methods,
mounted() {
this.processType = procurementContract
this.handleSelectProject({ id: 135 })
this.applyDeptSectorOptions = JSON.parse('${applyDeptSectorOptions}')
},

View File

@ -1,7 +1,7 @@
<#assign base=request.contextPath />
<#import "../../common/defaultLayout.ftl" as defaultLayout>
<@defaultLayout.layout>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<link rel="stylesheet" href="${base}/element-ui/element-ui.css">
<style>
.el-upload__input {
@ -137,8 +137,8 @@
</div>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="${base}/vue/vue.js"></script>
<script src="${base}/element-ui/element-ui.js"></script>
<script>