Files
laws-sinotruk-client/src/views/workCenter/enterpriseStandardInspectionPlan/EnterpriseStandardInspectionPlanFlow.vue
T
2024-01-18 16:32:59 +08:00

647 lines
23 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 :title="pageTitle" :content-padding="0" :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('basicInformation') }}
</a>
<!-- 人员信息 -->
<a class="switch-item" :class="switchValue === 'user' ? 'table-operator-tab-active' : ''"
@click="switchChange('user')">{{ $t('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()"
:disabled="disabled || processDisabled"
:maxLength="50"
v-decorator="['prcName', validatorRules.processName]" />
</a-form-item>
</a-col>
<a-col :span="12">
<!-- 截止日期 -->
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('expirationDate')">
<a-date-picker :placeholder="$t('pleaseSelect') + $t('expirationDate')"
style="width: 100%"
:disabled="disabled || processDisabled"
value-format="YYYY-MM-DD hh:mm:ss"
v-decorator="['dueTime']" />
</a-form-item>
</a-col>
<a-col :span="24">
<!-- 流程说明 -->
<a-form-item :labelCol="longLabelCol" :wrapperCol="longWrapperCol" :label="$t('processExplain')">
<a-textarea :placeholder="$t('pleaseEnter') + $t('processExplain')"
:maxLength="500"
:rows="4"
:disabled="disabled || processDisabled"
v-decorator="['prcMes']" />
</a-form-item>
</a-col>
</a-row>
</a-form>
<!-- 业务基本信息 -->
<div class="process-part-title">{{ $t('basicServiceInformation') }}</div>
<inspection-plan-table style="margin-bottom: 40px;" ref="inspectionPlanTable" :current-node="currentNode" :project-id="projectId"/>
<!-- 会签表单 -->
<a-form :form="countersignForm" v-if="currentNode === EsInspectionPlan.liaisonCollect.value">
<div class="form-flex-box">
<div class="form-flex-item custom-flex-form-item">
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('workCenter.esInspectionPlan.isCountersign')">
<j-dict-select-tag :placeholder="$t('pleaseSelect') + $t('workCenter.esInspectionPlan.isCountersign')"
type="radio"
dictCode="yn"
@change="changeIsCountersign"
v-decorator="['countersignTag', validatorRules.isCountersign]" />
</a-form-item>
</div>
<div class="form-flex-item custom-flex-form-item">
<a-form-item v-if="isCountersign" :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('workCenter.esInspectionPlan.countersignRelevantPersonnel')">
<user-selection :placeholder="$t('pleaseSelect') + $t('workCenter.esInspectionPlan.countersignRelevantPersonnel')"
type="checkbox" :nameStr="info.countersignDictText"
v-decorator="['involveList', validatorRules.countersignRelevantPersonnel]" />
</a-form-item>
</div>
</div>
</a-form>
<!-- 流程审批信息 -->
<div class="process-part-title">{{ $t('processApprovalInformation') }}</div>
<a-form :form="approvalInfoForm">
<!--备注-->
<a-form-item :labelCol="longLabelCol" :wrapperCol="longWrapperCol" :label="$t('remarks')">
<a-textarea :placeholder="$t('pleaseEnter') + $t('remarks')"
:maxLength="500"
:rows="4"
v-decorator="['commitText', validatorRules.remarks]" />
</a-form-item>
<!--附件-->
<a-form-item :labelCol="longLabelCol" :wrapperCol="longWrapperCol" :label="$t('businessSupport.questionAnswer.attach')">
<j-upload v-decorator="['commitFile']" return-id />
</a-form-item>
</a-form>
</div>
<!-- 人员信息 -->
<div v-show="switchValue === 'user'" class="detail-page-scroll-content p-0">
<process-detail-list :process-key="processKey">
<template #personnelInfo>
<personnel-info ref="personnelInfo" :data="personnelInfoData" :current-node="currentNodeName" />
</template>
</process-detail-list>
</div>
<div class="detail-page-bottom-operate-box">
<!--转办-->
<a-button v-if="btn.includes('transfer')" type="primary" :loading="loading" @click="handleTurnTo" ghost icon="arrow-up">{{ $t('turnTo') }}</a-button>
<!--保存-->
<a-button v-if="btn.includes('save')" type="primary" :loading="loading" @click="handleSave" ghost><i class="iconfont icon-save" />{{ $t('preservation') }}</a-button>
<!--提交-->
<a-button v-if="btn.includes('submit')" type="primary" :loading="loading" @click="handleSubmit" icon="upload">{{ $t('submit') }}</a-button>
<!--同意-->
<a-button v-if="btn.includes('agree')" type="primary" :loading="loading" @click="handleAgree" icon="check-circle">{{ $t('agree') }}</a-button>
<!--驳回-->
<a-button v-if="btn.includes('reject')" type="primary" :loading="loading" @click="handleReject" icon="close-circle">{{ $t('reject') }}</a-button>
</div>
<!--转办选人-->
<user-select-modal ref="userSelectModal" check-required @change="continueTurnTo" />
</internal-detail-page>
</template>
<script>
import '@assets/less/common.less'
import InternalDetailPage from '@comp/InternalDetailPage'
import PersonnelInfo from '@comp/PersonnelInfo'
import ProcessDetailList from '@comp/ProcessDetailList'
import InspectionPlanTable from '@views/workCenter/enterpriseStandardInspectionPlan/modules/InspectionPlanTable'
import UserSelection from '@comp/selection/UserSelection'
import { WorkCenterMixin } from '@/mixins/WorkCenterMixin'
import { ApprovalOpinions, EsInspectionPlan, ProcessKey } from '@/enums/commonEnums'
import {
approvalInspectPlan,
getInspectPlanDetail,
getInspectPlanProjectId, rejectInspectPlan,
saveInspectPlan,
startInspectPlan, transferInspectPlan
} from '@api/workCenter'
import UserSelectModal from '@comp/selection/UserSelectModal'
export default {
name: 'EnterpriseStandardInspectionPlanFlow',
components: { UserSelectModal, UserSelection, InspectionPlanTable, ProcessDetailList, PersonnelInfo, InternalDetailPage },
mixins: [WorkCenterMixin],
data () {
return {
loading: false,
switchValue: 'base',
disabled: false,
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 }
},
// 流程key
processKey: ProcessKey.ES_INSPECTION_PLAN.value,
// 当前流程信息
EsInspectionPlan,
info: {},
currentNode: '',
currentNodeName: '',
// 项目id
projectId: '',
btn: [],
validatorRules: {
// 流程名称
processName: {
rules: [
{ required: true, message: this.$t('pleaseEnter') + this.$t('processName') }
],
validateTrigger: 'blur'
},
// 备注
remarks: {
rules: [
{ required: false, message: this.$t('pleaseEnter') + this.$t('remarks') }
],
validateTrigger: 'blur'
},
// 是否会签
isCountersign: {
rules: [
{ required: true, message: this.$t('pleaseSelect') + this.$t('workCenter.esInspectionPlan.isCountersign') }
],
validateTrigger: 'change'
},
countersignRelevantPersonnel: {
rules: [
{ required: true, message: this.$t('pleaseSelect') + this.$t('workCenter.esInspectionPlan.countersignRelevantPersonnel') }
],
validateTrigger: 'change'
}
},
// 流程表单
processInfoForm: this.$form.createForm(this),
// 会签表单
countersignForm: this.$form.createForm(this),
// 流程审批信息表单
approvalInfoForm: this.$form.createForm(this),
// 是否会签
isCountersign: null
}
},
computed: {
pageTitle () {
return this.$t('flowCenter') + this.$route.meta.title + '(' + this.nodeTitle + ')'
},
// 节点标题
nodeTitle () {
return this.$route.query.taskName || EsInspectionPlan.initiate.text
},
processDisabled () {
return this.currentNode !== EsInspectionPlan.initiate.value
},
// 是否发起节点
isInitiate () {
return this.currentNode === EsInspectionPlan.initiate.value
}
},
created () {
const { projectId, nodeId, taskName } = this.$route.query
// 发起、草稿进来没有nodeId,就默认发起节点
this.currentNode = nodeId || EsInspectionPlan.initiate.value
this.currentNodeName = taskName || EsInspectionPlan.initiate.text
this.projectId = projectId || ''
this.btn = EsInspectionPlan.propertyOfValue('btn', this.currentNode) || []
// 如果有nodeId,但是匹配不到任何节点,就是是增加的审批节点
if (nodeId && !EsInspectionPlan.keyOfValue(nodeId)) {
// 同意按钮
this.btn = ['agree']
}
// 查询人员信息
this.getPersonInfoStructure(this.processKey, () => {
this.initPersonInfoData(this.isInitiate)
})
// 如果是待办或草稿进来,就获取详情数据
if (this.$route.query.projectId) {
this.loadPage()
return
}
// 如果是新建进来,就获取项目id
this.getProjectId()
},
methods: {
/**
* 获取项目id
*/
getProjectId () {
this.loading = true
// 否则就是创建一个新的流程
getInspectPlanProjectId().then(res => {
if (res) {
this.projectId = res + ''
}
}).finally(() => {
this.loading = false
})
},
/**
* 获取页面详情
*/
loadPage () {
const { projectId, taskId, draftId } = this.$route.query
this.loading = true
getInspectPlanDetail({
projectId,
taskId
}).then(res => {
if (res.success) {
const data = res.result || {}
const processAll = data.processAll || {}
const processApprovalRecord = data.processApprovalRecord || {}
this.info = data
this.$refs.inspectionPlanTable.setData(data.processEsInspectPlanList || [])
// 页面回显
this.processInfoForm && this.processInfoForm.setFieldsValue({
prcName: processAll.prcName,
dueTime: processAll.dueTime,
prcMes: processAll.prcMes
})
this.approvalInfoForm && this.approvalInfoForm.setFieldsValue({
commitText: processApprovalRecord.commitText,
commitFile: processApprovalRecord.commitFile
})
// 回显会签表单
this.$nextTick(() => {
this.countersignForm && this.countersignForm.setFieldsValue({
countersignTag: data.countersignTag,
involveList: data.countersign || ''
})
})
// 触发会签改变
this.changeIsCountersign(data.countersignTag)
// 草稿状态回显
if (draftId) {
const infoJson = JSON.parse(data.infoJsonStr || '{}')
console.log('草稿回显', JSON.parse(data.infoJsonStr || '{}'), infoJson.draftData, infoJson.personInfo)
// 节点1 回显人员信息
if (this.isInitiate) {
this.draftInitPersonInfo(infoJson.personInfo)
}
// 回显业务信息,如果有标识属性就是强制撤回
if (Object.hasOwnProperty.call(infoJson, 'revocation')) {
this.$refs.inspectionPlanTable.setData(infoJson.draftData)
}
}
}
}).finally(() => {
this.loading = false
})
},
// 获取人员信息
getPersonInfo (isValidate = true) {
let personnelObj = {}
const funName = isValidate ? 'getDataObjVerify' : 'getDataObj'
// 节点1:所有的人员信息
if (this.isInitiate) {
// 人员信息的数据, 处理成对象
personnelObj = this.$refs.personnelInfo[funName]()
if (!personnelObj) {
return false
}
// List拆成数组
for (const key in personnelObj) {
if (personnelObj[key] && key.includes('List')) {
personnelObj[key] = personnelObj[key].split(',')
}
}
// 发起节点:通过表格中的员获取所属部门人稽查征求意见对象
if (this.isInitiate) {
const userList = this.$refs.inspectionPlanTable.dataSource.map(item => item.objectOfConsultation.split(',')).flat(Infinity)
personnelObj.opinionFillList = Array.from(new Set(userList)).filter(item => item)
}
}
return personnelObj
},
// 获取页面参数
async getPageParams (isValidate = true) {
// 去除备注必填
this.validatorRules.remarks.rules[0].required = false
if (isValidate && this.$refs.inspectionPlanTable.dataSource.length === 0) {
this.$message.warning(this.$t('addAtLeastOneRowOfData'))
throw new Error('base')
}
// 节点2,验证所有数据意见是否都已填写
if (isValidate && this.currentNode === EsInspectionPlan.fillInComments.value) {
// 当前登录用户,查找意见为空的数据
const currentUserName = this.$store.getters.userInfo.username
const opinionHasEmpty = this.$refs.inspectionPlanTable.dataSource.some(item => {
// 自己的数据就不用填写意见
if (item.createBy === currentUserName) {
return false
}
// 如果没有意见内容,就是有没填的
if (!item.processEsInspectPlanOpinion || !item.processEsInspectPlanOpinion.opinion) {
return true
}
})
if (opinionHasEmpty) {
this.$message.warning(this.$t('pleaseCompleteTableInfo'))
throw new Error('base')
}
}
const params = {}
// 业务表信息
params.processEsInspectPlanList = this.$refs.inspectionPlanTable.dataSource.map(item => {
delete item.createTime
return item
})
// 获取删除业务信息的ids列表
params.processAllDelIds = this.$refs.inspectionPlanTable.getDelIds()
// 收集所有表单信息
let formDataList = []
if (isValidate) {
formDataList = await this.validateFormList(this.processInfoForm, this.countersignForm, this.approvalInfoForm)
} else {
formDataList = [
this.processInfoForm.getFieldsValue(),
this.countersignForm.getFieldsValue(),
this.approvalInfoForm.getFieldsValue()
]
// 保存清空校验
this.approvalInfoForm.validateFields(['commitText'], { force: true }, () => {})
}
// 收集人员信息
const personInfo = this.getPersonInfo(isValidate)
if (!personInfo) {
throw new Error('user')
}
// 开始处理信息
// 流程信息
params.processAll = Object.assign({}, this.info.processAll, formDataList[0], {
projectId: this.projectId,
nodeId: this.$route.query.nodeId,
taskId: this.$route.query.taskId,
prcType: 16
})
// 处理其他参数
params.map = Object.assign({}, formDataList[1], personInfo)
// 节点三:会签表单放到对象最外层单独存储业务信息,params.map里是流程用的
if (this.currentNode === EsInspectionPlan.liaisonCollect.value && Object.hasOwnProperty.call(params.map, 'countersignTag')) {
params.countersignTag = params.map.countersignTag
// params.map.pass = this.convertPass(params.map.pass)
}
if (params.map.involveList && typeof params.map.involveList === 'string') {
params.countersign = params.map.involveList
params.map.involveList = params.map.involveList.split(',')
}
// 流程审批信息
params.processApprovalRecord = Object.assign({}, this.info.processApprovalRecord, formDataList[2], {
projectId: this.projectId
})
// 保存草稿信息
params.infoJsonStr = JSON.stringify({
// 人员信息(要重新获取,流程里的信息不能直接用,后端需要多选人员处理成数组了)
personInfo: this.$refs.personnelInfo.getDataObj(),
// 业务表格数据,用于强制撤回后回显
draftData: params.processEsInspectPlanList
})
return params
},
/**
* 转办弹框
*/
handleTurnTo () {
this.$refs.userSelectModal.open()
},
/**
* 转办
*/
continueTurnTo (userId) {
if (this.loading) return
this.loading = true
const params = {
taskId: this.$route.query.taskId,
userId
}
transferInspectPlan(params).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warn(res.message)
}
}).finally(() => {
this.loading = false
})
},
/**
* 保存
*/
handleSave () {
if (this.loading) return
this.loading = true
this.getPageParams(false).then(res => {
// 1待办 2草稿
res.saveSource = (this.$route.query.draftId || !this.$route.query.projectId) ? 2 : 1
console.log(res)
return saveInspectPlan(res)
}).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warn(res.message)
}
}).catch((err) => {
console.log(err)
}).finally(() => {
this.loading = false
})
},
/**
* 提交
*/
handleSubmit () {
if (this.loading) return
// 有taskId说明已经发起过,调审批接口,否则调发起接口
if (this.$route.query.taskId) {
this.handleAgree(true)
return
}
this.loading = true
this.getPageParams().then(res => {
console.log(res)
return startInspectPlan(res)
}).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warn(res.message)
}
}).catch((err) => {
this.switchChange(err.message)
}).finally(() => {
this.loading = false
})
},
/**
* 同意
* @param isSubmitBtn - 是否提交按钮(提交按钮除了发起也走同意接口)
*/
handleAgree (isSubmitBtn) {
if (this.loading) return
this.loading = true
this.getPageParams().then(res => {
// 节点三,pass决定是否跳过会签
if (this.currentNode === EsInspectionPlan.liaisonCollect.value) {
res.map.pass = this.convertPass(res.map.countersignTag)
} else {
// 其他情况一直传true
res.map.pass = true
}
// 不是提交按钮
if (isSubmitBtn !== true) {
// 没有填写注释,就默认同意
if (!res.processApprovalRecord.commitText) {
res.processApprovalRecord.commitText = '同意'
}
}
// 审批意见
res.processApprovalRecord.commitFlag = ApprovalOpinions.AGREE.value
return approvalInspectPlan(res)
}).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warn(res.message)
}
}).catch((err) => {
this.switchChange(err.message)
}).finally(() => {
this.loading = false
})
},
/**
* 驳回
*/
handleReject () {
if (this.loading) return
// 备注设置必填并校验(校验第一次正常,第二次校验就不提示,force配置项解决问题)
this.validatorRules.remarks.rules[0].required = true
this.$nextTick(() => {
this.approvalInfoForm.validateFields(['commitText'], { force: true }, (err) => {
if (err) {
this.switchChange('base')
}
})
})
// 驳回需要填写备注
if (!this.approvalInfoForm.getFieldValue('commitText')) {
this.$message.warning(this.$t('pleaseEnterRemarks'))
return
}
this.loading = true
this.getPageParams().then(res => {
res.map.pass = false
// 审批意见
res.processApprovalRecord.commitFlag = ApprovalOpinions.REJECT.value
return rejectInspectPlan(res)
}).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warn(res.message)
}
}).catch((err) => {
this.switchChange(err.message)
}).finally(() => {
this.loading = false
})
},
// 是否会签改变
changeIsCountersign (val) {
if (val === '1') {
this.isCountersign = true
} else {
// 清空会签人员
this.countersignForm.setFieldsValue({ involveList: undefined })
this.info.countersignDictText = ''
this.isCountersign = false
}
},
// pass数据字典值和布尔值互相转换
convertPass (pass) {
switch (pass + '') {
case '1':
return true
case '0':
return false
case 'true':
return '1'
case 'false':
return '0'
default:
return null
}
},
/**
* 验证所有表单
* @param formList - 多个需要校验的表单实例
*/
validateFormList (...formList) {
const promiseList = []
for (const form of formList) {
promiseList.push(
new Promise((resolve, reject) => {
form.validateFields({ force: true }, (err, val) => {
if (!err) {
resolve(val)
} else {
reject(err)
}
})
})
)
}
return Promise.all(promiseList).catch(() => {
throw new Error('base')
})
}
}
}
</script>
<style scoped>
</style>