fourcal/src/main/resources/templates/admin/business/process-edit.ftl

808 lines
28 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<#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">
<style>
#businessPurchaseDetailsModal {
overflow: auto;
}
#businessPurchaseDetailsModal > table {
}
#newBusinessProcurementContractProcess {
overflow: auto;
}
.el-upload__input {
display: none !important;
}
.el-textarea .el-input__count {
line-height: 15px;
}
.admin-content-body {
margin-bottom: 100px;
}
.el-table__empty-block {
height: 60px !important;
}
.el-upload-list__item-name [class^="el-icon"] {
height: unset;
}
.el-checkbox {
margin-right: 10px;
}
</style>
<div class="admin-content" id="app">
<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> /
<small>{{subTitle}}</small></div>
</div>
<div class="am-g">
<#-- 新增销售合同流程 -->
<div class="am-u-sm-12 am-u-md-12" v-if="isSalesContractMode">
<el-form :inline="true" ref="saleContractProcessForm" :model="processForm" label-position="right" label-width="100px">
<div class="am-form-inline">
<el-form-item label="项目编号">
<span>{{processForm.projectNo}}</span>
</el-form-item>
<el-tooltip :disabled="!projectSelected" effect="light" :content="projectTitle" placement="top-start">
<el-form-item label="项目标题">
<span>{{projectTitle}}</span>
</el-form-item>
</el-tooltip>
<el-form-item label="申请时间">
<span>{{processForm.applyDate}}</span>
</el-form-item>
<el-form-item label="采购模式" v-if="isProcurementContractMode">
<el-select v-model="processForm.procurementMode" placeholder="请选择采购模式">
<#list procurementMode as item>
<el-option label="${item.description}" value="${sealType.name()}"></el-option>
</#list>
</el-select>
</el-form-item>
<el-form-item label="项目类型" v-if="isSalesContractMode">
<span>{{processForm.projectType}}</span>
</el-form-item>
<el-form-item label="合作类型">
<span>{{processForm.cooperationType}}</span>
</el-form-item>
</div>
<div>
<el-form-item label="申请部门" :rules="[{ required: true, message: '申请部门电话不能为空'}]" prop="applyDept">
<el-cascader :options="applySectorOptions" clearable v-model="processForm.applyDept"></el-cascader>
</el-form-item>
<el-form-item label="申请人">
<span>{{processForm.applyPersonName}}</span>
</el-form-item>
<el-form-item label="申请部门领导">
<span>{{processForm.applyDeptLeaderName}}</span>
</el-form-item>
<el-form-item label="申请人电话" :rules="[{ required: true, message: '申请人电话不能为空'}]" prop="applyPersonPhone">
<el-input placeholder="请输入内容" v-model="processForm.applyPersonPhone"></el-input>
</el-form-item>
</div>
<div>
<el-form-item label="合同编号" :rules="[{ required: true, message: '合同编号不能为空'}]" prop="contractNo">
<el-input placeholder="请输入合同编号" v-model="processForm.contractNo"></el-input>
</el-form-item>
<el-form-item v-if="isSalesContractMode" label="合同名称" :rules="[{ required: true, message: '合同名称不能为空'}]"
prop="contractName">
<el-input placeholder="请输入合同名称" v-model="processForm.contractName"></el-input>
</el-form-item>
<el-form-item v-if="isProcurementContractMode" label="采购合同名称"
:rules="[{ required: true, message: '采购合同名称不能为空'}]" prop="contractName">
<el-input placeholder="请输入采购合同名称" v-model="processForm.contractName"></el-input>
</el-form-item>
<el-form-item label="合同金额">
<span>{{processForm.contractAmount}}元</span>
</el-form-item>
</div>
<div>
<el-form-item v-if="isSalesContractMode" label="客户名称" :rules="[{ required: true, message: '客户名称不能为空'}]">
<el-input placeholder="请输入客户名称" v-model="processForm.clientName"></el-input>
</el-form-item>
<el-form-item v-if="isProcurementContractMode" label="供应商名称" :rules="[{ required: true, message: '供应商名称不能为空'}]">
<el-input placeholder="请输入供应商" v-model="processForm.supplierName"></el-input>
</el-form-item>
<el-form-item label="最终用户名称">
<span>{{processForm.terminalCustomer}}</span>
</el-form-item>
</div>
<div>
<el-form-item label="用印类型" :rules="[{ required: true, message: '用印类型不能为空'}]">
<el-checkbox-group v-model="processForm.sealTypes">
<#list sealTypes as sealType>
<el-checkbox label="${sealType.name()}" key="key-${sealType.name()}">${sealType.description}</el-checkbox>
</#list>
</el-checkbox-group>
</el-form-item>
</div>
<div>
<el-form-item label="税率" :rules="[{ required: true, message: '税率不能为空'}]" prop="taxRate">
<el-select v-model="processForm.taxRate" placeholder="请选择税率">
<#list taxRate as rate>
<el-option label="${rate}%" value="${rate}"></el-option>
</#list>
</el-select>
</el-form-item>
<el-form-item label="是否垫资">
<span>{{processForm.isPrepaid}}</span>
</el-form-item>
<el-form-item label="垫资金额">
<span>{{processForm.repaidAmount}}</span>
</el-form-item>
<el-form-item label="预算毛利率">
<span>{{processForm.budgetGrossMargin}}</span>
</el-form-item>
</div>
<div>
<el-form-item v-if="isSalesContractMode" label="收款条件" :rules="[{ required: true, message: '收款条件不能为空'}]"
prop="paymentTerms">
<el-input type="textarea" :autosize="{ minRows: 3, maxRows: 10}" cols="90" maxlength="5000" show-word-limit
v-model="processForm.paymentTerms" placeholder="请输入收款条件限制5000字"></el-input>
</el-form-item>
<el-form-item v-if="isProcurementContractMode" label="付款条件" :rules="[{ required: true, message: '付款条件不能为空'}]"
prop="paymentTerms">
<el-input type="textarea" :autosize="{ minRows: 3, maxRows: 10}" cols="90" maxlength="5000" show-word-limit
v-model="processForm.paymentTerms" placeholder="请输入付款条件限制5000字"></el-input>
</el-form-item>
</div>
<div>
<el-form-item label="备注">
<el-input type="textarea" :autosize="{ minRows: 3, maxRows: 10}" maxlength="5000" show-word-limit
v-model="processForm.remark" placeholder="请输入备注限制5000字" cols="90"></el-input>
</el-form-item>
</div>
<div>
<el-form-item label="上传附件" :rules="[{ required: true, message: '未上传附件'}]">
<el-upload class="upload-demo"
action="${base}/file/upload"
name="files[]"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:on-success="handleFileUploaded"
:limit="10" :file-list="fileList"
:on-exceed="handleExceed">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传PDF、excel、word、图片、压缩包且不超过50MB</div>
</el-upload>
</el-form-item>
</div>
<div>
<el-form-item label="合同清单明细">
<el-button type="text" @click="goToSaleContractDetail">详细清单</el-button>
</el-form-item>
</div>
<div v-if="isProcurementContractMode">
供应商比选材料
<div class="am-u-sm-12 am-u-md-12" v-if="isProcurementContractMode">
<el-table style="width: 100%" border>
<el-table-column type="index" :index="1" label="序号" fixed></el-table-column>
<el-table-column prop="fee" label="公司名称" width="180"></el-table-column>
<el-table-column prop="fee" label="合计金额" width="180"></el-table-column>
<el-table-column prop="fee" label="服务条款" width="180"></el-table-column>
<el-table-column prop="fee" label="付款条件" width="180"></el-table-column>
<el-table-column prop="fee" label="税率(%" width="180"></el-table-column>
<el-table-column prop="fee" label="备注"></el-table-column>
<el-table-column prop="fee" label="附件"></el-table-column>
</el-table>
</div>
</div>
</el-form>
<el-row>
<el-button type="info" @click="backLastPage">返回上一级</el-button>
<el-button type="primary" @click="saveDraft">保存草稿</el-button>
<el-button type="success" @click="submitForm">提交</el-button>
</el-row>
</div>
<#-- 销售合同清单明细 -->
<div class="am-u-sm-12 am-u-md-12" v-if="isSaleContractDetailMode">
<el-table border :data="incomeDetails">
<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="unit" label="单位"></el-table-column>
<el-table-column prop="amount" 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="税金"></el-table-column>
<el-table-column prop="expirationDate" label="质保期" fixed="right" width="150">
<template slot-scope="scope">
<el-input maxlength="5" size="mini" placeholder="请输入质保期"
v-model="scope.row.expirationDate"></el-input>
</template>
</el-table-column>
</el-table>
<el-row style="margin: 20px 0">
<el-button type="info" @click="goToSaleContractProcess">返回上一级</el-button>
<el-button type="primary" @click="submitToSaleContractProcess">保存并返回上一级</el-button>
</el-row>
</div>
<#-- 选择 业务采购清单明细 -->
<div class="am-u-sm-12 am-u-md-12" v-if="isProcurementContractMode">
<el-table style="width: 100%" border>
<el-table-column prop="fee" label="费用项目" width="180"></el-table-column>
<el-table-column prop="fee" label="采购类别" width="180"></el-table-column>
<el-table-column prop="fee" label="产品名称" width="180"></el-table-column>
<el-table-column prop="fee" label="单位" width="180"></el-table-column>
<el-table-column prop="fee" label="数量" width="180"></el-table-column>
<el-table-column prop="fee" label="预算单价" width="180"></el-table-column>
<el-table-column prop="fee" label="税率(%" width="180"></el-table-column>
<el-table-column prop="fee" label="含税总金额(元)" width="180"></el-table-column>
<el-table-column prop="fee" label="不含税金额(元)" width="180"></el-table-column>
<el-table-column prop="fee" label="税金(元)" width="180"></el-table-column>
<el-table-column prop="fee" label="是否垫资" width="180"></el-table-column>
<el-table-column prop="fee" label="支出时间" width="180"></el-table-column>
<el-table-column prop="fee" label="支出金额(元)" width="180"></el-table-column>
<el-table-column prop="fee" label="已采购数量" width="180"></el-table-column>
<el-table-column prop="fee" label="本次采购数量" width="180"></el-table-column>
<el-table-column prop="fee" label="未采购数量" width="180"></el-table-column>
<el-table-column prop="fee" label="供应商名称"></el-table-column>
<el-table-column prop="fee" label="设备厂商名称"></el-table-column>
<el-table-column prop="fee" label="对应采购清单"></el-table-column>
<el-table-column prop="fee" label="规格型号"></el-table-column>
<el-table-column prop="fee" label="对应采购数目"></el-table-column>
<el-table-column prop="fee" label="采购单价"></el-table-column>
<el-table-column prop="fee" label="含税总金额(元)"></el-table-column>
</el-table>
</div>
</div>
</div>
</div>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
const newBusinessProcurementContractProcess = "newBusinessProcurementContractProcess"
const saleContractProcess = "saleContractProcess"
const saleContractDetail = "saleContractDetail"
const BUTTON = "btn"
const isEmpty = (obj) => {
return !obj || (obj.length && obj.length === 0)
}
const isNotEmpty = (obj) => {
return !isEmpty(obj)
}
const isBlank = (obj) => {
return isEmpty(obj) || (obj.trim && isEmpty(obj.trim()))
}
const hasText = (obj) => {
return !isBlank(obj)
}
const data = () => {
return {
mode: "btn", // btn , newBusinessProcurementContractProcess
processForm: {
sealTypes: [],
},
processType: '',
projectSelected: false,
applySectorOptions: [
{
value: 'zhinan',
label: '指南',
children: [{
value: 'shejiyuanze',
label: '设计原则',
children: [{
value: 'yizhi',
label: '一致'
}, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, {
value: 'daohang',
label: '导航',
children: [{
value: 'cexiangdaohang',
label: '侧向导航'
}, {
value: 'dingbudaohang',
label: '顶部导航'
}]
}]
},
{
value: 'zujian',
label: '组件',
children: [{
value: 'basic',
label: 'Basic',
children: [{
value: 'layout',
label: 'Layout 布局'
}, {
value: 'color',
label: 'Color 色彩'
}, {
value: 'typography',
label: 'Typography 字体'
}, {
value: 'icon',
label: 'Icon 图标'
}, {
value: 'button',
label: 'Button 按钮'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio 单选框'
}, {
value: 'checkbox',
label: 'Checkbox 多选框'
}, {
value: 'input',
label: 'Input 输入框'
}, {
value: 'input-number',
label: 'InputNumber 计数器'
}, {
value: 'select',
label: 'Select 选择器'
}, {
value: 'cascader',
label: 'Cascader 级联选择器'
}, {
value: 'switch',
label: 'Switch 开关'
}, {
value: 'slider',
label: 'Slider 滑块'
}, {
value: 'time-picker',
label: 'TimePicker 时间选择器'
}, {
value: 'date-picker',
label: 'DatePicker 日期选择器'
}, {
value: 'datetime-picker',
label: 'DateTimePicker 日期时间选择器'
}, {
value: 'upload',
label: 'Upload 上传'
}, {
value: 'rate',
label: 'Rate 评分'
}, {
value: 'form',
label: 'Form 表单'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table 表格'
}, {
value: 'tag',
label: 'Tag 标签'
}, {
value: 'progress',
label: 'Progress 进度条'
}, {
value: 'tree',
label: 'Tree 树形控件'
}, {
value: 'pagination',
label: 'Pagination 分页'
}, {
value: 'badge',
label: 'Badge 标记'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert 警告'
}, {
value: 'loading',
label: 'Loading 加载'
}, {
value: 'message',
label: 'Message 消息提示'
}, {
value: 'message-box',
label: 'MessageBox 弹框'
}, {
value: 'notification',
label: 'Notification 通知'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu 导航菜单'
}, {
value: 'tabs',
label: 'Tabs 标签页'
}, {
value: 'breadcrumb',
label: 'Breadcrumb 面包屑'
}, {
value: 'dropdown',
label: 'Dropdown 下拉菜单'
}, {
value: 'steps',
label: 'Steps 步骤条'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog 对话框'
}, {
value: 'tooltip',
label: 'Tooltip 文字提示'
}, {
value: 'popover',
label: 'Popover 弹出框'
}, {
value: 'card',
label: 'Card 卡片'
}, {
value: 'carousel',
label: 'Carousel 走马灯'
}, {
value: 'collapse',
label: 'Collapse 折叠面板'
}]
}]
},
{
value: 'ziyuan',
label: '资源',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'jiaohu',
label: '组件交互文档'
}]
}
],
fileList: [],
// 销售合同收入明细
incomeDetails: [],
}
}
const methods = {
changeMode(mode) {
this.mode = mode
},
businessProcurementProcessClick() {
const that = this
},
backLastPage() {
window.history.back();
},
goToSaleContractProcess() {
this.changeMode(saleContractProcess)
},
goToSaleContractDetail() {
const { projectId } = this.processForm
if (projectId) {
this.changeMode(saleContractDetail)
}
else {
this.$message.warning("项目还未选择")
}
},
render(obj) {
console.log(obj)
},
initForm(form) {
this.processForm = { ...form }
console.log(form)
},
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 { incomeDetails, process, contract, ...form } = data
// 转换数据
// @formatter:off
const computeType = (type) => {
switch (type) {
case 1: return '设备'
case 2: return '工程'
case 3: return '服务'
default: return '未知'
}
}
// @formatter:on
const applyDept = process.applyDept.split(',')
this.initForm({ ...form, ...process, ...contract, applyDept })
this.projectSelected = true
this.processType = process.processType
this.incomeDetails = incomeDetails.map(detail => ({
...detail, type: computeType(detail.type)
}))
this.fileList = JSON.parse(process.attachmentUri).map(item => ({
name: item.name, url: item.uri
}))
if (process.processType === 'sale_contract') {
this.changeMode(saleContractProcess)
}
else if (process.processType === 'business_procurement') {
this.changeMode(newBusinessProcurementContractProcess)
}
})
.catch(err => {
this.$message.error("项目'" + name + "'加载失败");
})
.finally(() => loading.close())
},
clearProjectProcess() {
this.projectSelected = false
this.initForm({})
this.incomeDetails = []
},
saveDraft() {
this.processForm.status = 'draft'
this.submit()
},
submitForm() {
this.processForm.status = 'to_be_audit'
this.submit()
},
submit() {
this.$refs["saleContractProcessForm"].validate((valid) => {
if (valid) {
const fileList = this.fileList
if (fileList.length === 0) {
this.$message.error("未上传附件");
return false
}
const loading = this.$loading({
lock: true,
text: '正在提交',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
const form = {
...this.processForm,
attachments: fileList.map(file => {
if (file.url) {
return {
uri: file.url,
name: file.name
}
}
return {
uri: file.response.data.url,
name: file.name
}
}),
incomeDetails: this.incomeDetails.map(detail => ({
id: detail.id, expirationDate: detail.expirationDate
}))
}
fetch("${base}/process", {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(form),
}).then(response => {
if (response.ok) {
this.$message({
showClose: true,
message: '提交成功',
type: 'success'
})
}
else {
return Promise.reject("失败")
}
}).catch(err => {
this.$message.error("项目提交失败");
}).finally(() => loading.close())
}
else {
return false;
}
})
},
submitToSaleContractProcess() {
this.goToSaleContractProcess()
},
handleRemove(file, fileList) {
this.fileList = fileList
},
handleExceed(files, fileList) {
this.$message.warning("当前限制选择只能选择10个文件");
this.fileList = fileList
},
beforeRemove(file, fileList) {
return this.$confirm("确定移除 " + file.name + "");
},
handleFileUploaded(response, file, fileList) {
if (response.success) {
this.fileList = fileList
}
else {
this.$message.warning("上传失败");
}
},
indexMethod(index) {
return index * 1;
}
}
new Vue({
el: '#app',
data,
computed: {
projectTitle() {
const { projectNo, projectName, applyPersonName, applyDate } = this.processForm
if (projectNo && projectName) {
return projectNo.trim() + "-" + projectName.trim() + "-" + applyPersonName + "-" + applyDate
}
return ""
},
isButtonMode() {
return this.mode === BUTTON
},
isProcurementContractMode() {
return this.mode === newBusinessProcurementContractProcess
},
isSalesContractMode() {
return this.mode === saleContractProcess
},
isSaleContractDetailMode() {
return this.mode === saleContractDetail
},
subTitle() {
switch (this.mode) {
case BUTTON:
return "新增流程"
case saleContractProcess:
return "编辑销售合同流程"
case saleContractDetail:
return "销售合同清单明细"
case newBusinessProcurementContractProcess:
return "编辑业务采购合同流程"
}
}
},
methods,
mounted() {
const processId = ${processId}
this.loadProject(processId)
},
})
</script>
</@defaultLayout.layout>