Files
laws-sinotruk-client/src/views/workCenter/standardProcurementProcess/StandardProcurementProcess.vue
T
2024-01-02 11:00:45 +08:00

620 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<internal-detail-page :content-padding="0" :title="pageTitle" :loading="loading">
<!-- 标题右侧tab -->
<template v-slot:titleRightCustom>
<div class="table-operator-tab">
<!--基础信息-->
<a class="switch-item" :class="switchValue === 'base' ? 'table-operator-tab-active' : ''"
@click="switchChange('base')">{{ $t('workCenter.basicInformation') }}
</a>
<!--人员信息-->
<a class="switch-item" :class="switchValue === 'user' ? 'table-operator-tab-active' : ''"
@click="switchChange('user')">{{ $t('workCenter.personalInformation') }}
</a>
</div>
</template>
<!--基本信息-->
<div class="detail-page-scroll-content" v-show="switchValue === 'base'">
<!--流程信息-->
<div class="process-part-title">{{ $t('processInformation') }}</div>
<a-form :form="processInfoForm">
<a-row>
<a-col :span="12">
<!--流程名称-->
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('processName')">
<a-input :placeholder="$t('pleaseEnter') + $t('processName')"
@change="event => event.target.value = event.target.value.trim()"
:maxLength="50"
:disabled="processInfoDisabled"
v-decorator="['processName', validatorRules.processName]" />
</a-form-item>
</a-col>
<a-col :span="12">
<!--截止日期-->
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('expirationDate')">
<a-date-picker class="box-input"
:placeholder="$t('pleaseSelect') + $t('expirationDate')"
:getCalendarContainer="(trigger) => trigger.parentNode"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
v-decorator="['processDueDate']"
:disabled="processInfoDisabled"
style="width: 100%" />
</a-form-item>
</a-col>
</a-row>
<!--流程说明-->
<a-form-item :labelCol="longLabelCol" :wrapperCol="longWrapperCol" :label="$t('processExplain')">
<a-input :placeholder="$t('pleaseEnter') + $t('processExplain')"
@change="event => event.target.value = event.target.value.trim()"
:maxLength="500"
type="textarea"
:disabled="processInfoDisabled"
v-decorator="['processDescription']" />
</a-form-item>
</a-form>
<!--业务基本信息-->
<div class="process-part-title">{{ $t('basicServiceInformation') }}</div>
<div class="table-operator">
<!-- 新增-->
<a-button icon="plus" type="primary" @click="handleAdd" v-if="canTableOperate">{{ $t('newlyAdded') }}</a-button>
<!-- 批量删除-->
<a-button type="primary" icon="delete" ghost @click="batchDel" v-if="canTableOperate">{{ $t('batchDelete') }}</a-button>
<a-button icon="upload" type="primary" ghost @click="handleExportXls" v-if="!canTableOperate">
{{ $t('export') }}
</a-button>
<div>
<j-table
:can-drag="true"
:scroll="{x: '100%'}"
ref="table"
:rowKey="(record, index) => {return index}"
:columns="columns"
:dataSource="dataSource"
:pagination="false"
:row-selection="rowSelection"
:loading="loading">
<template v-slot:action="{text, record, index}">
<a @click="handleEdit(record, index)">{{ $t('edit') }}</a>
<a-divider type="vertical" />
<a @click="handleDelete(index)">{{ $t('delete') }}</a>
</template>
</j-table>
</div>
</div>
<!--流程审批信息-->
<div class="process-part-title">{{ $t('processApprovalInformation') }}</div>
<a-form :form="approvalInfoForm">
<!--备注-->
<a-form-item :labelCol="longLabelCol" :wrapperCol="longWrapperCol" :label="$t('remarks')">
<a-input :placeholder="$t('pleaseEnter') + $t('remarks')"
@change="event => event.target.value = event.target.value.trim()"
:maxLength="500"
type="textarea"
v-decorator="['handleText', validatorRules.handleText]" />
</a-form-item>
<!--附件-->
<a-form-item :labelCol="longLabelCol" :wrapperCol="longWrapperCol" :label="$t('businessSupport.questionAnswer.attach')">
<j-upload v-decorator="['handleFile']" return-id />
</a-form-item>
</a-form>
</div>
<!--人员信息-->
<div class="detail-page-scroll-content p-0" v-show="switchValue === 'user'">
<process-detail-list :process-key="processKey">
<template #personnelInfo>
<personnel-info ref="personnelInfo" :data="personnelInfoData" :current-node="currentNode" />
</template>
</process-detail-list>
</div>
<!--底部按钮-->
<div class="detail-page-bottom-operate-box">
<!--转办 审批节点存在-->
<a-button type="primary" :loading="loading" ghost icon="arrow-up" v-if="btnList.includes('return')" @click="handleTurnTo">
{{ $t('turnTo') }}
</a-button>
<!--抄送-->
<a-button type="primary" :loading="loading" ghost v-if="btnList.includes('carbonCopy')" @click="handleCarbonCopy">
{{ $t('workCenter.standardProcurementProcess.carbonCopy') }}
</a-button>
<!--保存 发起节点审批节点都存在-->
<a-button type="primary" :loading="loading" ghost v-if="btnList.includes('save')" @click="handleSave">
<i class="iconfont icon-save" />{{ $t('preservation') }}
</a-button>
<!--提交 发起节点存在-->
<a-button type="primary" :loading="loading" @click="handleSubmit" v-if="btnList.includes('submit')" icon="upload">
{{ $t('submit') }}
</a-button>
<!--同意 审批节点存在-->
<a-button type="primary" :loading="loading" icon="check-circle" v-if="btnList.includes('agree')" @click="handleAgree">
{{ $t('agree') }}
</a-button>
<!--驳回 审批节点存在-->
<a-button type="primary" :loading="loading" icon="close-circle" v-if="btnList.includes('reject')" @click="handleReject">
{{ $t('reject') }}
</a-button>
</div>
<!--表格新增编辑表单-->
<table-form-modal ref="modalForm" @ok="modalFormOk" />
<!--转办选人-->
<user-select-modal ref="userSelectModal" check-required :type="isTransfer ? 'radio' : 'checkbox'" @change="handleSelectedUser" />
</internal-detail-page>
</template>
<script>
import InternalDetailPage from '../../../components/InternalDetailPage'
import { WorkCenterMixin } from '../../../mixins/WorkCenterMixin'
import PersonnelInfo from '../../../components/PersonnelInfo'
import ProcessDetailList from '../../../components/ProcessDetailList'
import { ProcessKey, ProcurementProcessNodes } from '../../../enums/commonEnums'
import JTable from '../../../components/jero/JTable'
import TableFormModal from './modules/TableFormModal'
import {
queryProcurementProcessInfo,
saveProcurementProcess,
initProcurementProcess,
agreeProcurementProcess,
rejectProcurementProcess,
transferProcurementProcess,
carbonCopyProcurementProcess,
getProcessNodeList
} from '../../../api/workCenter'
import UserSelection from '../../../components/selection/UserSelection'
import UserSelectModal from '../../../components/selection/UserSelectModal'
import { downFile } from '../../../api/manage'
import Vue from 'vue'
import { USER_INFO } from '../../../store/mutation-types'
export default {
name: 'StandardProcurementProcess',
components: { UserSelectModal, UserSelection, JTable, ProcessDetailList, PersonnelInfo, InternalDetailPage, TableFormModal },
mixins: [WorkCenterMixin],
data () {
return {
loading: false,
btnList: [],
// 流程信息表单
processInfoForm: this.$form.createForm(this),
processInfo: {},
// 审批信息的表单
approvalInfoForm: this.$form.createForm(this),
approvalInfo: {},
labelCol: {
xs: { span: 24 },
sm: { span: 4 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 20 }
},
longLabelCol: {
xs: { span: 24 },
sm: { span: 2 }
},
longWrapperCol: {
xs: { span: 24 },
sm: { span: 22 }
},
validatorRules: {
// 流程名称
processName: {
rules: [{ required: true, message: this.$t('pleaseEnter') + this.$t('processName') }],
validateTrigger: 'blur'
},
// 备注
handleText: {
rules: [{ required: false, message: this.$t('pleaseEnter') + this.$t('remarks') }],
validateTrigger: 'blur'
}
},
columns: [
{ // 标准编号
title: this.$t('standardNumber'),
width: 180,
dataIndex: 'standardNumber'
},
{ // 标准名称
title: this.$t('standardName'),
width: 180,
dataIndex: 'standardName'
},
{ // 采购理由
title: this.$t('workCenter.standardProcurementProcess.reasonForPurchase'),
width: 380,
dataIndex: 'purchaseReason'
}
],
// 操作
operateColumn: {
title: this.$t('operation'),
fixed: 'right',
width: 150,
scopedSlots: { customRender: 'action' }
},
dataSource: [],
selectedRowKeys: [],
currentNode: '',
isTransfer: true, // 是否转办
businessId: null
}
},
computed: {
pageTitle () {
const subTitle = this.$route.query.taskName || ProcurementProcessNodes.initiate.text
return `${this.$t('flowCenter')}${this.$route.meta.title}${subTitle}`
},
// 流程信息部分禁用
processInfoDisabled () {
return !(this.currentNode === ProcurementProcessNodes.initiate.value && !this.$route.query.processInstanceId)
},
// 表格是否可以增删改
canTableOperate () {
return this.currentNode === ProcurementProcessNodes.initiate.value
},
// 流程key
processKey () {
return ProcessKey.LEGAL_PROCUREMENT.value
},
// 表格可选
rowSelection () {
// 只有发起节点表格可以选择
if (this.currentNode === ProcurementProcessNodes.initiate.value) {
return { selectedRowKeys: this.selectedRowKeys, onChange: this.onSelectChange }
}
return null
}
},
created () {
if (this.$route.query.processInstanceId || this.$route.query.draftId) {
this.currentNode = this.$route.query.nodeId || ProcurementProcessNodes.initiate.value
this.initProcessInfo()
} else {
this.currentNode = ProcurementProcessNodes.initiate.value
}
if (this.currentNode === ProcurementProcessNodes.initiate.value) {
this.columns.push(this.operateColumn)
}
this.btnList = ProcurementProcessNodes.propertyOfValue('btn', this.currentNode)
this.getPersonInfoStructure(this.processKey, () => {
this.initPersonInfoData(this.currentNode === ProcurementProcessNodes.initiate.value)
})
},
methods: {
// 查询人员信息结构数据,callback用于获取完流程才可以初始化人员信息
getPersonInfoStructure (key, callback) {
const param = {}
param.processDefinitionKey = key
if (this.$route.query.processInstanceId) {
param.processInstanceId = this.$route.query.processInstanceId
}
getProcessNodeList(param).then(res => {
if (res.success) {
console.log(res.result)
// 处理人员信息数据,判断每个节点是否能选人
this.personnelInfoData = res.result.map(item => {
return {
...item,
chooseType: item.variableType === 'string' ? 'radio' : 'checkbox'
}
})
if (!this.$route.query.processInstanceId) {
// 说明是在新发起一个节点,初始化发起人员信息
this.personnelInfoData[0].linkUserIds = Vue.ls.get(USER_INFO).id
this.personnelInfoData[0].linkUserIds_dictText = Vue.ls.get(USER_INFO).realname + '(' + Vue.ls.get(USER_INFO).username + ')'
this.personnelInfoData[0].userList = Vue.ls.get(USER_INFO).realname + '(' + Vue.ls.get(USER_INFO).username + ')'
// 发起节点,最后一个节点也需要返回当前登陆人
const lastIndex = this.personnelInfoData.length - 1
this.personnelInfoData[lastIndex].linkUserIds = Vue.ls.get(USER_INFO).id
this.personnelInfoData[lastIndex].linkUserIds_dictText = Vue.ls.get(USER_INFO).realname + '(' + Vue.ls.get(USER_INFO).username + ')'
this.personnelInfoData[lastIndex].userList = Vue.ls.get(USER_INFO).realname + '(' + Vue.ls.get(USER_INFO).username + ')'
}
if (callback) {
callback()
}
}
})
},
onSelectChange (selectedRowKeys) {
this.selectedRowKeys = selectedRowKeys
},
handleAdd () {
this.$refs.modalForm.add()
},
batchDel () {
if (!this.selectedRowKeys || this.selectedRowKeys.length === 0) {
this.$message.warning(this.$t('selectARecord'))
return
}
this.$confirm({
title: this.$t('confirmBatchDeletion'),
content: this.$t('deleteAData'),
onOk: () => {
const data = JSON.parse(JSON.stringify(this.dataSource))
this.dataSource = data.map((tt, index) => {
return this.selectedRowKeys.includes(index) ? null : tt
}).filter(tt => !!tt)
this.selectedRowKeys = []
}
})
},
handleEdit (record, index) {
this.$refs.modalForm.edit(record, index)
},
handleDelete (index) {
this.$confirm({
title: this.$t('confirmDeletion'),
content: this.$t('areYouSure'),
onOk: () => {
this.dataSource.splice(index, 1)
}
})
},
modalFormOk (record, index) {
if (index || index === 0) {
this.$set(this.dataSource, index, record)
} else {
this.dataSource.unshift(record)
}
},
initProcessInfo () {
this.loading = true
const params = {
processInstanceId: this.$route.query.processInstanceId,
draftId: this.$route.query.draftId,
taskId: this.$route.query.taskId
}
queryProcurementProcessInfo(params).then(res => {
if (res.success) {
const { result } = res
this.businessId = result.businessId
this.processInfo = Object.assign({}, result.basicProcessInfoDTO || {})
this.dataSource = result.businessInfoDTO || []
this.approvalInfo = Object.assign({}, result.basicTaskInfoDTO || {})
this.$nextTick(() => {
this.processInfoForm.setFieldsValue(this.processInfo)
this.approvalInfoForm.setFieldsValue(this.approvalInfo)
})
}
}).finally(() => {
this.loading = false
})
},
dealFormData (isSave) {
let flag = true, formData = {}, processInfo = {}, approvalInfo = {}, businessInfo = [], userInfoMap = {}
if (isSave) {
processInfo = Object.assign(this.processInfo, this.processInfoForm.getFieldsValue())
businessInfo = this.dataSource
approvalInfo = Object.assign(this.approvalInfo, this.approvalInfoForm.getFieldsValue())
approvalInfo.taskId = approvalInfo.taskId || this.$route.query.taskId
userInfoMap = this.$refs.personnelInfo.getDataObj()
const params = { ...processInfo, ...businessInfo, ...approvalInfo, ...userInfoMap }
if (!Object.values(params).some(tt => !!tt || (tt && tt.length > 0))) {
// 提示至少填写一项
this.$message.warning(this.$t('pleaseFillInAtLeastOneItem'))
flag = false
}
} else {
// 流程信息
this.processInfoForm.validateFields((errors, values) => {
if (!errors) {
processInfo = Object.assign(this.processInfo, values)
} else {
flag = false
}
})
// 业务信息
if (!this.dataSource || this.dataSource.length === 0) {
this.$message.warning(this.$t('workCenter.standardProcurementProcess.addAtLeastOne'))
flag = false
}
businessInfo = this.dataSource
// 审批信息
this.approvalInfoForm.validateFields((errors, values) => {
if (!errors) {
approvalInfo = Object.assign(this.approvalInfo, values)
approvalInfo.taskId = approvalInfo.taskId || this.$route.query.taskId
} else {
flag = false
this.$message.warning(this.$t('pleaseEnterRemarks'))
}
})
const baseFlag = flag
// 人员信息
const userInfo = this.$refs.personnelInfo.getDataObjVerify()
userInfoMap = userInfo ? userInfo : flag = false
if (!flag && !baseFlag) {
this.switchValue = 'base'
} else if (!flag && !userInfo) {
this.switchValue = 'user'
}
}
formData = {
basicProcessInfoDTO: processInfo,
basicTaskInfoDTO: approvalInfo,
businessInfoDTO: businessInfo,
userInfoMap
}
return !flag ? flag : formData
},
/**
* 转办
*/
handleTurnTo () {
this.isTransfer = true
this.$refs.userSelectModal.open()
},
/**
* 抄送
*/
handleCarbonCopy () {
this.isTransfer = false
this.$refs.userSelectModal.open()
},
handleSelectedUser (userId) {
const params = {
taskId: this.$route.query.taskId,
userId
}
const func = this.isTransfer ? transferProcurementProcess : carbonCopyProcurementProcess
this.loading = true
func(params).then(res => {
if (res.success) {
this.$message.success(res.message)
if (this.isTransfer) {
this.goBack()
}
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
/**
* 保存
*/
handleSave () {
const formData = this.dealFormData(true)
this.loading = true
saveProcurementProcess(formData).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
/**
* 提交
*/
handleSubmit () {
const formData = this.dealFormData()
if (!formData) {
return
}
let submitFunc
if (this.currentNode === ProcurementProcessNodes.initiate.value && !this.$route.query.processInstanceId) {
submitFunc = initProcurementProcess
} else {
submitFunc = agreeProcurementProcess
}
this.loading = true
submitFunc(formData).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
/**
* 同意
*/
handleAgree () {
this.validatorRules.handleText.rules[0].required = false
if (!this.approvalInfoForm.getFieldValue('handleText')) {
this.approvalInfoForm.setFieldsValue({ handleText: '同意' })
}
const formData = this.dealFormData()
if (!formData) {
return
}
this.loading = true
agreeProcurementProcess(formData).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
/**
* 驳回
*/
handleReject () {
this.validatorRules.handleText.rules[0].required = true
const formData = this.dealFormData()
if (!formData) {
return
}
this.loading = true
rejectProcurementProcess(formData).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
handleExportXls () {
const fileName = this.$t('workCenter.standardProcurementProcess.legalProcurement') + '.xls'
const param = {
businessId: this.businessId
}
if (this.selectedRowKeys && this.selectedRowKeys.length > 0) {
const selectedRowsIds = this.dataSource.map((tt, index) => {
return this.selectedRowKeys.includes(index) ? tt.id : null
}).filter(tt => !!tt)
param.selections = selectedRowsIds.join(',')
}
console.log('导出参数', param)
// 加一个大的提示
const modalLoading = this.$info({
title: '提示',
content: <span>正在导出请稍候 <a-spin size="small" /></span>,
keyboard: false
})
// 把知道了这个按钮去掉
this.$nextTick(() => {
document.getElementsByClassName('ant-modal-confirm-btns')[0].style = 'display:none'
})
downFile('/process/fb/processFbStandardPurchase/exportXls', param).then((data) => {
if (!data) {
this.$message.warning('文件下载失败')
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data], { type: 'application/vnd.ms-excel' }), fileName)
} else {
const url = window.URL.createObjectURL(new Blob([data], { type: 'application/vnd.ms-excel' }))
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link) // 下载完成移除元素
window.URL.revokeObjectURL(url) // 释放掉blob对象
}
}).finally(() => {
// 销毁这个提示
modalLoading.destroy()
})
}
}
}
</script>
<style scoped lang="less">
@import '~@assets/less/common.less';
</style>