合同流程 前端
parent
6cf9459452
commit
dd0c111ebf
|
@ -204,20 +204,20 @@
|
||||||
<div>
|
<div>
|
||||||
<el-form-item v-if="isSalesContractMode" label="收款条件" prop="paymentTerms"
|
<el-form-item v-if="isSalesContractMode" label="收款条件" prop="paymentTerms"
|
||||||
:rules="[{ required: true, message: '收款条件不能为空'}]">
|
:rules="[{ required: true, message: '收款条件不能为空'}]">
|
||||||
<el-input type="textarea" :autosize="{ minRows: 3, maxRows: 10}" cols="90" maxlength="5000" show-word-limit
|
<el-input type="textarea" :autosize="{ minRows: 5, maxRows: 10}" cols="90" maxlength="5000" show-word-limit
|
||||||
v-model="processForm.paymentTerms" placeholder="请输入收款条件(限制5000字)"></el-input>
|
v-model="processForm.paymentTerms" placeholder="请输入收款条件(限制5000字)"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-if="isProcurementContractMode" label="付款条件" prop="paymentTerms"
|
<el-form-item v-if="isProcurementContractMode" label="付款条件" prop="paymentTerms"
|
||||||
:rules="[{ required: true, message: '付款条件不能为空'}]">
|
:rules="[{ required: true, message: '付款条件不能为空'}]">
|
||||||
<el-input type="textarea" :autosize="{ minRows: 3, maxRows: 10}" cols="90" maxlength="5000" show-word-limit
|
<el-input type="textarea" :autosize="{ minRows: 5, maxRows: 10}" cols="90" maxlength="5000" show-word-limit
|
||||||
v-model="processForm.paymentTerms" placeholder="请输入付款条件(限制5000字)"></el-input>
|
v-model="processForm.paymentTerms" placeholder="请输入付款条件(限制5000字)"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<el-form-item label="备注">
|
<el-form-item label="备注">
|
||||||
<el-input type="textarea" :autosize="{ minRows: 3, maxRows: 10}" maxlength="5000" show-word-limit
|
<el-input type="textarea" :autosize="{ minRows: 5, maxRows: 10}" maxlength="5000" show-word-limit
|
||||||
v-model="processForm.remark" placeholder="请输入备注(限制5000字)" cols="90"></el-input>
|
v-model="processForm.remark" placeholder="请输入备注(限制5000字)" cols="90"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
@ -261,7 +261,7 @@
|
||||||
<el-table-column prop="totalAmount" label="合计金额" width="160" align="center">
|
<el-table-column prop="totalAmount" label="合计金额" width="160" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-input-number size="mini" :precision="2" :step="0.1" :max="100" :min="0"
|
<el-input-number size="mini" :precision="2" :step="0.1" :max="100" :min="0"
|
||||||
v-model="scope.row.totalAmount"></el-input-number>
|
v-model="scope.row.totalAmount" controls-position="right"></el-input-number>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="serviceTerms" label="服务条款" width="180" align="center">
|
<el-table-column prop="serviceTerms" label="服务条款" width="180" align="center">
|
||||||
|
@ -277,7 +277,7 @@
|
||||||
<el-table-column prop="taxRate" label="税率(%)" width="160" align="center">
|
<el-table-column prop="taxRate" label="税率(%)" width="160" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-input-number size="mini" :precision="2" :step="0.1" :max="100" :min="0"
|
<el-input-number size="mini" :precision="2" :step="0.1" :max="100" :min="0"
|
||||||
v-model="scope.row.taxRate"></el-input-number>
|
v-model="scope.row.taxRate" controls-position="right"></el-input-number>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="remark" label="备注" align="center">
|
<el-table-column prop="remark" label="备注" align="center">
|
||||||
|
@ -292,32 +292,33 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="attachment" label="附件" align="center" width="150">
|
<el-table-column prop="attachment" label="附件" align="center" width="150">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag size="small" v-if="scope.row.attachment">
|
<el-upload :file-list="scope.row.fileList"
|
||||||
<a :href="scope.row.attachment.uri">
|
:limit="10" size="mini" name="files[]" action="${base}/file/upload"
|
||||||
<i class="el-icon-document"></i> {{scope.row.attachment.name}}
|
:on-remove="(_, fileList) => handleSupplierMaterialRemove(scope, fileList)"
|
||||||
</a>
|
:before-remove="(file, fileList) => beforeSupplierMaterialRemove(scope, file, fileList)"
|
||||||
</el-tag>
|
:on-success="(response, file, fileList) => handleSupplierMaterialFileUploaded(scope, response, file, fileList)"
|
||||||
<el-upload v-else class="upload-demo"
|
:on-exceed="(files, fileList) => handleSupplierMaterialExceed(scope, files, fileList)">
|
||||||
action="${base}/file/upload"
|
|
||||||
name="files[]"
|
|
||||||
:on-remove="handleRemove"
|
|
||||||
:before-remove="beforeRemove"
|
|
||||||
:on-success="handleFileUploaded"
|
|
||||||
:limit="1"
|
|
||||||
size="mini">
|
|
||||||
<el-button size="small" type="text">上传附件</el-button>
|
<el-button size="small" type="text">上传附件</el-button>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column width="49" fixed="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-popconfirm title="确定删除吗?填写的表单将丢弃" @confirm="removeSupplierMaterialRow(scope)">
|
||||||
|
<el-button slot="reference" type="danger" icon="el-icon-delete" circle size="mini"></el-button>
|
||||||
|
</el-popconfirm>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<el-button type="primary" icon="el-icon-plus" circle size="mini" @click="addSupplierRow"
|
<el-button type="primary" icon="el-icon-plus" circle size="mini" @click="addSupplierRow"
|
||||||
style="float: right;margin-top: 10px;"></el-button>
|
style="float: right;margin: 10px 10px 0 0"></el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-row>
|
<el-row class="am-u-sm-12 am-u-md-12" v-cloak>
|
||||||
<el-button type="info" @click="backLastPage">返回上一级</el-button>
|
<el-button type="info" @click="backLastPage">返回上一级</el-button>
|
||||||
<el-button type="primary" @click="saveDraft">保存草稿</el-button>
|
<el-button type="primary" @click="saveDraft">保存草稿</el-button>
|
||||||
<el-button type="success" @click="submitForm">提交</el-button>
|
<el-button type="success" @click="submitForm">提交</el-button>
|
||||||
|
@ -381,7 +382,7 @@
|
||||||
<el-table-column prop="amountAlready" label="已采购数量" width="100"></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 prop="amountCurrent" label="本次采购数量" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span v-if="scope.row.newRow">{{scope.row.parent.amountCurrent}}</span>
|
<span v-if="scope.row.newRow"></span>
|
||||||
<el-input-number v-else :precision="2" :step="0.1" :min="0" v-model="scope.row.amountCurrent"
|
<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"
|
:disabled="scope.row.amount - scope.row.amountAlready===0" size="mini"
|
||||||
:max="scope.row.amount - scope.row.amountAlready" controls-position="right">
|
:max="scope.row.amount - scope.row.amountAlready" controls-position="right">
|
||||||
|
@ -539,7 +540,7 @@
|
||||||
// 销售合同收入明细
|
// 销售合同收入明细
|
||||||
incomeDetails: [],
|
incomeDetails: [],
|
||||||
supplierMaterialsForm: [],
|
supplierMaterialsForm: [],
|
||||||
procurementDetailsRowKey: 0,
|
rowKeyCounter: 0,
|
||||||
procurementDetails: [],
|
procurementDetails: [],
|
||||||
filteredProcurementDetails: [],
|
filteredProcurementDetails: [],
|
||||||
}
|
}
|
||||||
|
@ -628,7 +629,10 @@
|
||||||
.then(checkStatus)
|
.then(checkStatus)
|
||||||
.then(parseJSON)
|
.then(parseJSON)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
const { incomeDetails, process, contract, procurementDetails, attachments, ...form } = data
|
const {
|
||||||
|
incomeDetails, process, supplierMaterials,
|
||||||
|
contract, procurementDetails, attachments, ...form
|
||||||
|
} = data
|
||||||
// 转换数据
|
// 转换数据
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
const computeType = type => {
|
const computeType = type => {
|
||||||
|
@ -662,6 +666,12 @@
|
||||||
name: item.name, url: item.uri
|
name: item.name, url: item.uri
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
this.supplierMaterialsForm = supplierMaterials && supplierMaterials.map(material => ({
|
||||||
|
...material, attachment: material.attachment && JSON.parse(material.attachment).map(item => ({
|
||||||
|
name: item.name, url: item.uri
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
|
||||||
let rowKey = 0
|
let rowKey = 0
|
||||||
|
|
||||||
const convertCommon = detail => {
|
const convertCommon = detail => {
|
||||||
|
@ -682,12 +692,13 @@
|
||||||
// mapChildren
|
// mapChildren
|
||||||
let { purchaseDetails } = parent
|
let { purchaseDetails } = parent
|
||||||
if (isNotEmpty(purchaseDetails)) {
|
if (isNotEmpty(purchaseDetails)) {
|
||||||
|
// 先取出第一个合并
|
||||||
|
const first = purchaseDetails.shift();
|
||||||
|
// 再处理剩余的子元素
|
||||||
purchaseDetails = purchaseDetails.map(purchase => ({
|
purchaseDetails = purchaseDetails.map(purchase => ({
|
||||||
...purchase, ...convertCommon(detail), parent, newRow: true
|
...purchase, ...convertCommon(detail), parent, newRow: true
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// 合并第一行到父级
|
// 合并第一行到父级
|
||||||
const first = purchaseDetails.shift();
|
|
||||||
Object.assign(parent, first)
|
Object.assign(parent, first)
|
||||||
delete parent['parent']
|
delete parent['parent']
|
||||||
delete parent['purchaseDetails']
|
delete parent['purchaseDetails']
|
||||||
|
@ -700,7 +711,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
this.procurementDetails = computeProcurementDetails(procurementDetails)
|
this.procurementDetails = computeProcurementDetails(procurementDetails)
|
||||||
this.procurementDetailsRowKey = rowKey
|
this.rowKeyCounter = rowKey
|
||||||
|
|
||||||
if (process.processType === saleContract) {
|
if (process.processType === saleContract) {
|
||||||
this.changeMode(saleContractProcess)
|
this.changeMode(saleContractProcess)
|
||||||
|
@ -711,10 +722,15 @@
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
parseJSON(err.response)
|
if (err.response) {
|
||||||
.then(json => {
|
parseJSON(err.response)
|
||||||
this.$message.error(json.message || "项目加载失败");
|
.then(json => {
|
||||||
})
|
this.$message.error(json.message || "项目加载失败");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.$message.error("项目加载失败")
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.finally(() => loading.close())
|
.finally(() => loading.close())
|
||||||
},
|
},
|
||||||
|
@ -735,116 +751,171 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
submit(needValid) {
|
submit(needValid) {
|
||||||
this.$refs["contractProcessForm"].validate((valid) => {
|
const processForm = this.processForm
|
||||||
if (valid || !needValid) {
|
const processType = this.processType
|
||||||
const fileList = this.fileList
|
const fileList = this.fileList
|
||||||
if (needValid && fileList.length === 0) {
|
let validStatus = !needValid
|
||||||
this.$message.error("未上传附件");
|
if (needValid) {
|
||||||
return false
|
// 校验表单
|
||||||
}
|
this.$refs["contractProcessForm"].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
const processType = this.processType
|
if (fileList.length === 0) {
|
||||||
const processForm = this.processForm
|
this.$message.error("未上传附件");
|
||||||
if (needValid && processType === procurementContract) {
|
return false
|
||||||
const { procurementMode } = processForm
|
}
|
||||||
|
if (processType === saleContract) {
|
||||||
// specify_purchase("指定采购"),
|
if (!this.checkExpirationDate()) {
|
||||||
// simple_price_comparison("简单比价"),
|
|
||||||
// price_comparison("比价"),
|
|
||||||
// competitive_evaluation("竞争性评估");
|
|
||||||
// 当“采购模式”为“指定采购”“简单比价”时,本模块为非必填模块,当为“比价”“竞争性评估”时,本模块为必填项(“备注”除外)
|
|
||||||
if (procurementMode === 'price_comparison'
|
|
||||||
|| procurementMode === 'competitive_evaluation') {
|
|
||||||
|
|
||||||
if (isEmpty(this.supplierMaterialsForm)) {
|
|
||||||
this.$message.error("供应商比选材料未填写")
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for (const item in this.supplierMaterialsForm) {
|
}
|
||||||
if (isEmpty(Object.keys(item))) {
|
|
||||||
this.$message.error("供应商比选材料未填写")
|
// 采购合同需要验证 供应商比选材料
|
||||||
|
if (processType === procurementContract) {
|
||||||
|
if (!this.checkProcurementDetails()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const { procurementMode } = processForm
|
||||||
|
|
||||||
|
// specify_purchase("指定采购"),
|
||||||
|
// simple_price_comparison("简单比价"),
|
||||||
|
// price_comparison("比价"),
|
||||||
|
// competitive_evaluation("竞争性评估");
|
||||||
|
// 当“采购模式”为“指定采购”“简单比价”时,本模块为非必填模块,当为“比价”“竞争性评估”时,本模块为必填项(“备注”除外)
|
||||||
|
if (procurementMode === 'price_comparison'
|
||||||
|
|| procurementMode === 'competitive_evaluation') {
|
||||||
|
|
||||||
|
if (isEmpty(this.supplierMaterialsForm)) {
|
||||||
|
this.$message.error("供应商比选材料未填写,请检查表单")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for (const [key, value] of Object.entries(item)) {
|
|
||||||
if (value) {
|
let idx = 0
|
||||||
if (typeof value === 'string') {
|
for (const item in this.supplierMaterialsForm) {
|
||||||
if (isBlank(value)) {
|
idx++
|
||||||
this.$message.error("有未填写的表单,请检查表单");
|
if (isEmptyObject(item)) {
|
||||||
return false
|
this.$message.error("供应商比选材料第'" + idx + "'行未填写,请检查表单")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for (const [key, value] of Object.entries(item)) {
|
||||||
|
if (value) {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
if (isBlank(value)) {
|
||||||
|
this.$message.error("供应商比选材料第'" + idx + "'行有数据未填写,请检查表单")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 没有值
|
||||||
|
if (key !== 'remark') {
|
||||||
|
this.$message.error("供应商比选材料第'" + idx + "'行有数据未填写,请检查表单")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// 没有值
|
|
||||||
if (key !== 'remark') {
|
|
||||||
this.$message.error("有未填写的表单,请检查表单");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (needValid && !processForm.applyDeptId) {
|
if (!processForm.applyDeptId) {
|
||||||
this.$message.error("申请部门还未选择");
|
this.$message.error("申请部门还未选择");
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证通过
|
||||||
|
validStatus = true
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const loading = this.$loading({
|
}
|
||||||
lock: true,
|
|
||||||
text: processForm.status === 'draft' ? '正在保存草稿' : "正在提交",
|
if (!validStatus) {
|
||||||
spinner: 'el-icon-loading',
|
return false
|
||||||
background: 'rgba(0, 0, 0, 0.7)'
|
}
|
||||||
|
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
text: processForm.status === 'draft' ? '正在保存草稿' : "正在提交",
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
|
||||||
|
const budgetCostIdMap = new Map()
|
||||||
|
this.procurementDetails.forEach(detail => {
|
||||||
|
budgetCostIdMap.set(detail.budgetCostId, detail)
|
||||||
|
})
|
||||||
|
|
||||||
|
const computePurchaseAmountDetail = budgetCostId => {
|
||||||
|
const detail = budgetCostIdMap.get(budgetCostId)
|
||||||
|
const ret = []
|
||||||
|
const map = detail => {
|
||||||
|
const ret = {}
|
||||||
|
procurementDetailProperties.forEach(property => {
|
||||||
|
ret[property] = detail[property]
|
||||||
})
|
})
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
const applyDeptId = processForm.applyDeptId.join(',') // (逗号分割)
|
ret.push(map(detail))
|
||||||
|
detail.children.forEach(detail => {
|
||||||
|
ret.push(map(detail))
|
||||||
|
})
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
const form = {
|
const form = {
|
||||||
...this.processForm,
|
...processForm,
|
||||||
applyDeptId,
|
processType,
|
||||||
attachments: fileList.map(file => {
|
applyDeptId: processForm.applyDeptId?.join(','), // (逗号分割),
|
||||||
if (file.url) {
|
attachments: fileList.map(file => {
|
||||||
return {
|
if (file.url) {
|
||||||
uri: file.url,
|
return { uri: file.url, name: file.name }
|
||||||
name: file.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
uri: file.response.data.url,
|
|
||||||
name: file.name
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
incomeDetails: this.incomeDetails.map(detail => ({
|
|
||||||
id: detail.id, expirationDate: detail.expirationDate
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
return { uri: file.response.data.url, name: file.name }
|
||||||
|
}),
|
||||||
|
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)
|
||||||
|
})),
|
||||||
|
supplierMaterials: this.supplierMaterialsForm.filter(hasProperties), // 剔除空行
|
||||||
|
}
|
||||||
|
|
||||||
fetch("${base}/process", {
|
fetch("${base}/process", {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify(form),
|
body: JSON.stringify(form),
|
||||||
}).then(response => {
|
}).then(checkStatus).then(data => {
|
||||||
if (response.ok) {
|
this.$message({
|
||||||
this.$message({
|
showClose: true,
|
||||||
showClose: true,
|
message: processForm.status === 'draft' ? '草稿保存成功' : "提交成功",
|
||||||
message: '提交成功',
|
type: 'success'
|
||||||
type: 'success'
|
})
|
||||||
|
}).catch(({ response }) => {
|
||||||
|
const defaultMessage = () => {
|
||||||
|
return processForm.status === 'draft' ? '草稿保存失败' : "项目提交失败"
|
||||||
|
}
|
||||||
|
if (response) {
|
||||||
|
parseJSON(response)
|
||||||
|
.then(json => {
|
||||||
|
this.$message.error(json.message || defaultMessage())
|
||||||
})
|
})
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Promise.reject("失败")
|
|
||||||
}
|
|
||||||
}).catch(err => {
|
|
||||||
this.$message.error("项目提交失败");
|
|
||||||
}).finally(() => loading.close())
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
this.$message.error(defaultMessage())
|
||||||
}
|
}
|
||||||
})
|
}).finally(() => loading.close())
|
||||||
},
|
},
|
||||||
|
|
||||||
submitToSaleContractProcess() {
|
submitToSaleContractProcess() {
|
||||||
|
@ -873,12 +944,36 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleSupplierMaterialRemove(scope, fileList) {
|
||||||
|
scope.row['attachment'] = fileList
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSupplierMaterialExceed(scope, files, fileList) {
|
||||||
|
this.$message.warning("当前限制选择只能选择10个文件");
|
||||||
|
scope.row['attachment'] = fileList
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeSupplierMaterialRemove(scope, file, fileList) {
|
||||||
|
return this.$confirm("确定移除 " + file.name + "?");
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSupplierMaterialFileUploaded(scope, response, file, fileList) {
|
||||||
|
if (response.success) {
|
||||||
|
scope.row['attachment'] = fileList
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.$message.warning("上传失败");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
indexMethod(index) {
|
indexMethod(index) {
|
||||||
return index * 1;
|
return index * 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
addSupplierRow() {
|
addSupplierRow() {
|
||||||
this.supplierMaterialsForm.push({})
|
this.supplierMaterialsForm.push({
|
||||||
|
rowKey: this.rowKeyCounter++,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
addProcurementDetailRow(scope) {
|
addProcurementDetailRow(scope) {
|
||||||
|
@ -886,7 +981,7 @@
|
||||||
const { children } = row
|
const { children } = row
|
||||||
const newRow = {
|
const newRow = {
|
||||||
...row,
|
...row,
|
||||||
rowKey: this.procurementDetailsRowKey++,
|
rowKey: this.rowKeyCounter++,
|
||||||
newRow: true,
|
newRow: true,
|
||||||
parent: row // 记录上一级元素,在删除的时候使用
|
parent: row // 记录上一级元素,在删除的时候使用
|
||||||
}
|
}
|
||||||
|
@ -916,6 +1011,11 @@
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
removeSupplierMaterialRow(scope) {
|
||||||
|
const { rowKey } = scope.row
|
||||||
|
this.supplierMaterialsForm = this.supplierMaterialsForm.filter(child => child.rowKey !== rowKey)
|
||||||
|
},
|
||||||
|
|
||||||
applyDeptSelected(value) {
|
applyDeptSelected(value) {
|
||||||
if (value.length === 0) {
|
if (value.length === 0) {
|
||||||
this.processForm['applyDept'] = null
|
this.processForm['applyDept'] = null
|
||||||
|
|
|
@ -341,11 +341,11 @@
|
||||||
<el-upload class="upload-demo"
|
<el-upload class="upload-demo"
|
||||||
action="${base}/file/upload"
|
action="${base}/file/upload"
|
||||||
name="files[]"
|
name="files[]"
|
||||||
:on-remove="handleRemove"
|
|
||||||
:before-remove="beforeRemove"
|
|
||||||
:on-success="handleFileUploaded"
|
|
||||||
:limit="10"
|
:limit="10"
|
||||||
:on-exceed="handleExceed">
|
:on-remove="handleRemove"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
:before-remove="beforeRemove"
|
||||||
|
:on-success="handleFileUploaded">
|
||||||
<el-button size="small" type="primary">点击上传</el-button>
|
<el-button size="small" type="primary">点击上传</el-button>
|
||||||
<div slot="tip" class="el-upload__tip">只能上传PDF、excel、word、图片、压缩包,且不超过50MB</div>
|
<div slot="tip" class="el-upload__tip">只能上传PDF、excel、word、图片、压缩包,且不超过50MB</div>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
|
@ -411,24 +411,30 @@
|
||||||
<i class="el-icon-document"></i> {{scope.row.attachment.name}}
|
<i class="el-icon-document"></i> {{scope.row.attachment.name}}
|
||||||
</a>
|
</a>
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-upload v-else class="upload-demo"
|
<el-upload v-else :limit="10" size="mini" name="files[]" action="${base}/file/upload"
|
||||||
action="${base}/file/upload"
|
:on-remove="(_, fileList) => handleSupplierMaterialRemove(scope, fileList)"
|
||||||
name="files[]"
|
:before-remove="(file, fileList) => beforeSupplierMaterialRemove(scope, file, fileList)"
|
||||||
:on-remove="handleRemove"
|
:on-success="(response, file, fileList) => handleSupplierMaterialFileUploaded(scope, response, file, fileList)"
|
||||||
:before-remove="beforeRemove"
|
:on-exceed="(files, fileList) => handleSupplierMaterialExceed(scope, files, fileList)"
|
||||||
:on-success="handleFileUploaded"
|
>
|
||||||
:limit="1"
|
|
||||||
size="mini">
|
|
||||||
<el-button size="small" type="text">上传附件</el-button>
|
<el-button size="small" type="text">上传附件</el-button>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column width="49" fixed="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-popconfirm title="确定删除吗?填写的表单将丢弃" @confirm="removeSupplierMaterialRow(scope)">
|
||||||
|
<el-button slot="reference" type="danger" icon="el-icon-delete" circle size="mini"></el-button>
|
||||||
|
</el-popconfirm>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<el-button type="primary" icon="el-icon-plus" circle size="mini" @click="addSupplierRow"
|
<el-button type="primary" icon="el-icon-plus" circle size="mini" @click="addSupplierRow"
|
||||||
style="float: right;margin-top: 10px;"></el-button>
|
style="float: right;margin: 10px 10px 0 0"></el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-row class="am-u-sm-12 am-u-md-12" v-cloak>
|
<el-row class="am-u-sm-12 am-u-md-12" v-cloak>
|
||||||
|
@ -624,6 +630,29 @@
|
||||||
return !isBlank(obj)
|
return !isBlank(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hasProperties = obj => {
|
||||||
|
return isNotEmpty(Object.keys(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
const isEmptyObject = obj => {
|
||||||
|
return isEmpty(Object.keys(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkStatus(response) {
|
||||||
|
if (response.status >= 200 && response.status < 300) {
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const error = new Error(response.statusText);
|
||||||
|
error.response = response
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseJSON(response) {
|
||||||
|
return response.json()
|
||||||
|
}
|
||||||
|
|
||||||
const data = () => {
|
const data = () => {
|
||||||
return {
|
return {
|
||||||
mode: "btn", // btn , procurementContractProcess
|
mode: "btn", // btn , procurementContractProcess
|
||||||
|
@ -641,7 +670,7 @@
|
||||||
processType: "",
|
processType: "",
|
||||||
procurementProjectSelectorVisible: false,
|
procurementProjectSelectorVisible: false,
|
||||||
procurementDetailSelectorVisible: false,
|
procurementDetailSelectorVisible: false,
|
||||||
procurementDetailsRowKey: 0,
|
rowKeyCounter: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,7 +896,7 @@
|
||||||
rowKey: rowKey++, children: []
|
rowKey: rowKey++, children: []
|
||||||
}))
|
}))
|
||||||
|
|
||||||
this.procurementDetailsRowKey = rowKey
|
this.rowKeyCounter = rowKey
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
@ -938,19 +967,22 @@
|
||||||
|| procurementMode === 'competitive_evaluation') {
|
|| procurementMode === 'competitive_evaluation') {
|
||||||
|
|
||||||
if (isEmpty(this.supplierMaterialsForm)) {
|
if (isEmpty(this.supplierMaterialsForm)) {
|
||||||
this.$message.error("供应商比选材料未填写")
|
this.$message.error("供应商比选材料未填写,请检查表单")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let idx = 0
|
||||||
for (const item in this.supplierMaterialsForm) {
|
for (const item in this.supplierMaterialsForm) {
|
||||||
if (isEmpty(Object.keys(item))) {
|
idx++
|
||||||
this.$message.error("供应商比选材料未填写")
|
if (isEmptyObject(item)) {
|
||||||
|
this.$message.error("供应商比选材料第'" + idx + "'行未填写,请检查表单")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for (const [key, value] of Object.entries(item)) {
|
for (const [key, value] of Object.entries(item)) {
|
||||||
if (value) {
|
if (value) {
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
if (isBlank(value)) {
|
if (isBlank(value)) {
|
||||||
this.$message.error("有未填写的表单,请检查表单");
|
this.$message.error("供应商比选材料第'" + idx + "'行有数据未填写,请检查表单")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -958,7 +990,7 @@
|
||||||
else {
|
else {
|
||||||
// 没有值
|
// 没有值
|
||||||
if (key !== 'remark') {
|
if (key !== 'remark') {
|
||||||
this.$message.error("有未填写的表单,请检查表单");
|
this.$message.error("供应商比选材料第'" + idx + "'行有数据未填写,请检查表单")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1000,7 +1032,6 @@
|
||||||
budgetCostIdMap.set(detail.budgetCostId, detail)
|
budgetCostIdMap.set(detail.budgetCostId, detail)
|
||||||
})
|
})
|
||||||
|
|
||||||
debugger
|
|
||||||
const computePurchaseAmountDetail = budgetCostId => {
|
const computePurchaseAmountDetail = budgetCostId => {
|
||||||
const detail = budgetCostIdMap.get(budgetCostId)
|
const detail = budgetCostIdMap.get(budgetCostId)
|
||||||
const ret = []
|
const ret = []
|
||||||
|
@ -1019,16 +1050,14 @@
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
const applyDeptId = processForm.applyDeptId?.join(',') // (逗号分割)
|
|
||||||
const form = {
|
const form = {
|
||||||
...processForm,
|
...processForm,
|
||||||
processType,
|
processType,
|
||||||
applyDeptId,
|
applyDeptId: processForm.applyDeptId?.join(','),// (逗号分割),
|
||||||
attachments: fileList.map(file => ({
|
attachments: fileList.map(file => ({
|
||||||
uri: file.response.data.url,
|
uri: file.response.data.url,
|
||||||
name: file.response.data.originName
|
name: file.response.data.originName
|
||||||
})),
|
})),
|
||||||
supplierMaterials: this.supplierMaterialsForm,
|
|
||||||
incomeDetails: this.incomeDetails.map(detail => ({
|
incomeDetails: this.incomeDetails.map(detail => ({
|
||||||
id: detail.id, expirationDate: detail.expirationDate
|
id: detail.id, expirationDate: detail.expirationDate
|
||||||
})),
|
})),
|
||||||
|
@ -1038,7 +1067,8 @@
|
||||||
amountAlready: detail.amountAlready,
|
amountAlready: detail.amountAlready,
|
||||||
amountCurrent: detail.amountCurrent,
|
amountCurrent: detail.amountCurrent,
|
||||||
details: computePurchaseAmountDetail(detail.budgetCostId)
|
details: computePurchaseAmountDetail(detail.budgetCostId)
|
||||||
}))
|
})),
|
||||||
|
supplierMaterials: this.supplierMaterialsForm.filter(hasProperties), // 剔除空行
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch("${base}/process", {
|
fetch("${base}/process", {
|
||||||
|
@ -1047,19 +1077,25 @@
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify(form),
|
body: JSON.stringify(form),
|
||||||
}).then(response => {
|
}).then(checkStatus).then(data => {
|
||||||
if (response.ok) {
|
this.$message({
|
||||||
this.$message({
|
showClose: true,
|
||||||
showClose: true,
|
message: processForm.status === 'draft' ? '草稿保存成功' : "提交成功",
|
||||||
message: '提交成功',
|
type: 'success'
|
||||||
type: 'success'
|
})
|
||||||
})
|
}).catch(({ response }) => {
|
||||||
|
const defaultMessage = () => {
|
||||||
|
return processForm.status === 'draft' ? '草稿保存失败' : "项目提交失败"
|
||||||
|
}
|
||||||
|
if (response) {
|
||||||
|
parseJSON(response)
|
||||||
|
.then(json => {
|
||||||
|
this.$message.error(json.message || defaultMessage())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Promise.reject("失败")
|
this.$message.error(defaultMessage())
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
|
||||||
this.$message.error("项目提交失败");
|
|
||||||
}).finally(() => loading.close())
|
}).finally(() => loading.close())
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1101,12 +1137,38 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleSupplierMaterialRemove(scope, fileList) {
|
||||||
|
scope.row['fileList'] = fileList
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSupplierMaterialExceed(scope, files, fileList) {
|
||||||
|
this.$message.warning("当前限制选择只能选择10个文件");
|
||||||
|
scope.row['fileList'] = fileList
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeSupplierMaterialRemove(scope, file, fileList) {
|
||||||
|
return this.$confirm("确定移除 " + file.name + "?");
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSupplierMaterialFileUploaded(scope, response, file, fileList) {
|
||||||
|
if (response.success) {
|
||||||
|
scope.row['fileList'] = fileList
|
||||||
|
|
||||||
|
this.fileListSupplierMaterial = fileList
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.$message.warning("上传失败");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
indexMethod(index) {
|
indexMethod(index) {
|
||||||
return index * 1;
|
return index * 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
addSupplierRow() {
|
addSupplierRow() {
|
||||||
this.supplierMaterialsForm.push({})
|
this.supplierMaterialsForm.push({
|
||||||
|
rowKey: this.rowKeyCounter++,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
addProcurementDetailRow(scope) {
|
addProcurementDetailRow(scope) {
|
||||||
|
@ -1114,7 +1176,7 @@
|
||||||
const { children } = row
|
const { children } = row
|
||||||
const newRow = {
|
const newRow = {
|
||||||
...row,
|
...row,
|
||||||
rowKey: this.procurementDetailsRowKey++,
|
rowKey: this.rowKeyCounter++,
|
||||||
newRow: true,
|
newRow: true,
|
||||||
parent: row // 记录上一级元素,在删除的时候使用
|
parent: row // 记录上一级元素,在删除的时候使用
|
||||||
}
|
}
|
||||||
|
@ -1131,8 +1193,8 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
removeProcurementDetailRow(scope) {
|
removeProcurementDetailRow(scope) {
|
||||||
const { rowKey, parent } = scope.row
|
const { rowKey } = scope.row
|
||||||
parent.children = parent.children.filter(child => child.rowKey !== rowKey)
|
.filter(child => child.rowKey !== rowKey)
|
||||||
},
|
},
|
||||||
|
|
||||||
// 区别子项
|
// 区别子项
|
||||||
|
@ -1144,6 +1206,11 @@
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
removeSupplierMaterialRow(scope) {
|
||||||
|
const { rowKey } = scope.row
|
||||||
|
this.supplierMaterialsForm = this.supplierMaterialsForm.filter(child => child.rowKey !== rowKey)
|
||||||
|
},
|
||||||
|
|
||||||
applyDeptSelected(value) {
|
applyDeptSelected(value) {
|
||||||
if (value.length === 0) {
|
if (value.length === 0) {
|
||||||
this.processForm['applyDept'] = null
|
this.processForm['applyDept'] = null
|
||||||
|
|
Loading…
Reference in New Issue