Files
laws-sinotruk-client/src/views/workCenter/noMatchTrackingProcess/NoMatchTrackingProcess.vue
T

696 lines
24 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
v-decorator="['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="disabledProcessInfo"
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="disabledProcessInfo"
v-decorator="['processDescription']" />
</a-form-item>
</a-form>
<!--业务基本信息-->
<div class="process-part-title">{{ $t('basicServiceInformation') }}</div>
<a-form :form="businessInfoForm" v-if="showSelectStandardForm">
<div class="form-flex-box">
<!--标准编号/标准名称-->
<div class="form-flex-item custom-flex-form-item">
<a-form-item :label="$t('projectLibrary.vehicleItemLibrary.standardNumberStandardName')">
<a-input :placeholder="$t('pleaseEnter') + $t('projectLibrary.vehicleItemLibrary.standardNumberStandardName')"
@change="event => event.target.value = event.target.value.trim()"
:maxLength="50"
v-decorator="['standardNumberOrName', validatorRules.standardNumberOrName]" />
</a-form-item>
</div>
<!--项目名称-->
<div class="form-flex-item custom-flex-form-item">
<a-form-item :label="$t('projectLibrary.projectName')">
<a-select :placeholder="$t('pleaseSelect') + $t('project')"
v-decorator="['projectId']"
show-search
allowClear
:filter-option="filterOption">
<a-select-option v-for="item in projectSelectOptions" :key="item.id">{{ item.projectName }}</a-select-option>
</a-select>
</a-form-item>
</div>
<!--设计工程师-->
<div class="form-flex-item custom-flex-form-item">
<a-form-item :label="$t('workCenter.standardConsultationProcess.designEngineer')">
<user-selection v-decorator="['engineerId', validatorRules.engineerId]"
:name-str="businessInfo.engineerId_dictText"
:placeholder="$t('pleaseSelect') + $t('workCenter.standardConsultationProcess.designEngineer')"
@nameChange="handleDesignEngineerNameChange" />
</a-form-item>
</div>
<!--按条件查询-->
<a-button type="primary" class="form-search-btn" @click="selectStandard">
{{ $t('workCenter.noMatchTracking.queryByCondition') }}
</a-button>
</div>
</a-form>
<component ref="expandTable"
v-if="tableComponent"
:is="tableComponent"
:columns="columns"
:data-source="dataSource"
:pagination="false"
:scroll="{x: '100%'}"
:extra-form="extraForm"
:all-disabled="expandTableDisabled">
<!--跳转标准详情-->
<template v-slot:detail="{text, record}">
<a-tooltip overlay-class-name="tooltip-style">
<template slot="title">{{ text || text === 0 ? text : global.emptyLine }}</template>
<div class="table-text can-click-table-text" v-if="text || text === 0" @click="toDetailPage(record)">{{ text }}</div>
<div v-else class="table-text">{{ global.emptyLine }}</div>
</a-tooltip>
</template>
</component>
<!--流程审批信息-->
<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.NO_MATCH_TRACKING.value">
<template #personnelInfo>
<personnel-info ref="personnelInfo" :data="personnelInfoData" />
</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('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>
<!--按条件查询选择标准弹框-->
<no-match-item-select-drawer ref="selectStandardDrawer" @ok="handleStandardSelected" />
<!--转办选人-->
<user-select-modal type="radio" ref="userSelectModal" @change="continueTransfer" />
</internal-detail-page>
</template>
<script>
import PersonnelInfo from '../../../components/PersonnelInfo'
import InternalDetailPage from '../../../components/InternalDetailPage'
import ProcessDetailList from '../../../components/ProcessDetailList'
import { WorkCenterMixin } from '../../../mixins/WorkCenterMixin'
import { ProcessKey, NoMatchTrackingNodes, StandardSource } from '../../../enums/commonEnums'
import UserSelection from '../../../components/selection/UserSelection'
import NoMatchItemSelectDrawer from './modules/NoMatchItemSelectDrawer'
import { getCarTypeProjectList } from '../../../api/projectLibraryApi'
import {
saveNoMatchTrackingProcess,
queryNoMatchTrackingProcess,
initialNoMatchTrackingProcess,
submitNoMatchTrackingProcess, processTransfer, agreeNoMatchTrackingProcess, rejectNoMatchTrackingProcess
} from '../../../api/workCenter'
import { cloneDeep } from 'lodash'
import UserSelectModal from '../../../components/selection/UserSelectModal'
export default {
name: 'NoMatchTrackingProcess',
components: { UserSelectModal, ProcessDetailList, InternalDetailPage, PersonnelInfo, UserSelection, NoMatchItemSelectDrawer },
mixins: [WorkCenterMixin],
data () {
return {
ProcessKey,
loading: false,
btnList: [],
// 流程信息表单
processInfoForm: this.$form.createForm(this),
processInfo: {},
// 审批信息的表单
approvalInfoForm: this.$form.createForm(this),
approvalInfo: {},
// 业务基本信息表单(发起时候的查询条件)
businessInfoForm: this.$form.createForm(this),
businessInfo: {},
currentNode: null,
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: {
// 备注
handleText: {
rules: [{ required: false, message: this.$t('pleaseEnter') + this.$t('remarks') }],
validateTrigger: 'blur'
},
// 标准编号/标准名称
standardNumberOrName: {
rules: [{
required: true,
message: this.$t('pleaseEnter') + this.$t('projectLibrary.vehicleItemLibrary.standardNumberStandardName')
}],
validateTrigger: 'blur'
},
// 设计工程师
engineerId: {
rules: [{ required: true, message: this.$t('pleaseSelect') + this.$t('workCenter.standardConsultationProcess.designEngineer') }],
validateTrigger: 'change'
}
},
columns: [
// 标准编号
{
dataIndex: 'standardNumber',
title: this.$t('standardNumber'),
width: 150,
align: 'center',
scopedSlots: { customRender: 'detail' }
},
// 标准名称
{
dataIndex: 'standardName',
title: this.$t('standardName'),
width: 150,
align: 'center',
scopedSlots: { customRender: 'detail' }
},
// 条款号
{
dataIndex: 'termNum',
title: this.$t('workCenter.enStandardRevision.clauseNumber'),
width: 150,
align: 'center',
scopedSlots: { customRender: 'text' }
},
// 条款名称
{
title: this.$t('workCenter.enStandardRevision.clauseName'),
width: 150,
dataIndex: 'termName',
align: 'center',
scopedSlots: { customRender: 'text' }
},
// 问题类型
{
dataIndex: 'assessResults_dictText',
title: this.$t('workCenter.noMatchTracking.problemTypes'),
width: 150,
align: 'center',
scopedSlots: { customRender: 'text' }
},
// 相关项目
{
title: this.$t('projectLibrary.noncoincidenceItem.relevantProject'),
width: 150,
dataIndex: 'projectName',
align: 'center',
scopedSlots: { customRender: 'text' }
},
// 设计工程师
{
dataIndex: 'engineerId_dictText',
title: this.$t('workCenter.standardConsultationProcess.designEngineer'),
width: 120,
align: 'center',
scopedSlots: { customRender: 'text' }
},
// 预计整改完成日期
{
dataIndex: 'expectedTime',
title: this.$t('projectLibrary.vehicleItemLibrary.estimatedDateOfCompletionOfRectification'),
width: 180,
align: 'center',
scopedSlots: { customRender: 'text' }
}
],
dataSource: [],
// 展开表格的规则
extraForm: {
rules: {
// 依据描述
description: {
required: true,
message: this.$t('pleaseEnter') + this.$t('projectLibrary.specialProjectLibrary.basisDescription'),
trigger: 'blur'
},
// 佐证材料
fileId: {
required: false,
message: this.$t('pleaseUpload') + this.$t('projectLibrary.specialProjectLibrary.supportingMaterial'),
trigger: 'change'
}
},
formArr: [
{
fieldShowType: 1,
dbFieldTxt: this.$t('projectLibrary.specialProjectLibrary.basisDescription'),
dbFieldName: 'description'
},
{
fieldShowType: 2,
dbFieldTxt: this.$t('projectLibrary.specialProjectLibrary.supportingMaterial'),
dbFieldName: 'fileId'
}
]
},
projectSelectOptions: [] // 项目下拉数据
}
},
computed: {
pageTitle () {
const subTitle = this.$route.query.taskName || NoMatchTrackingNodes.initial.text
return `${this.$t('flowCenter')}${this.$route.meta.title}(${subTitle})`
},
// 是否展示选择标准的表单
showSelectStandardForm () {
return this.currentNode === NoMatchTrackingNodes.initial.value
},
// 表格用哪个组件
tableComponent () {
if (this.showSelectStandardForm) {
return resolve => require(['../../../components/jero/JTable.vue'], resolve)
}
return resolve => require(['../../../components/JExpandTable.vue'], resolve)
},
// 展开表格是否禁用,设计工程师上传整改材料节点不禁用
expandTableDisabled () {
return this.currentNode !== NoMatchTrackingNodes.designEngineer.value
},
// 禁用流程信息部分表单
disabledProcessInfo () {
return this.currentNode !== NoMatchTrackingNodes.initial.value
}
},
created () {
this.getPersonInfoStructure(ProcessKey.NO_MATCH_TRACKING.value, () => {
this.initDict()
if (this.$route.query.processInstanceId || this.$route.query.draftId) {
this.currentNode = this.$route.query.nodeId || NoMatchTrackingNodes.initial.value
this.initPersonInfoData(this.currentNode === NoMatchTrackingNodes.initial.value)
this.initProcessInfo()
} else {
this.currentNode = NoMatchTrackingNodes.initial.value
this.initPersonInfoData(this.currentNode === NoMatchTrackingNodes.initial.value)
}
// 如果节点不是固定节点,就默认显示审批节点的信息
this.btnList = NoMatchTrackingNodes.propertyOfValue('btn', this.currentNode) || NoMatchTrackingNodes.regulatoryEngineer.btn
})
},
methods: {
/**
* 获取下拉数据
*/
initDict () {
getCarTypeProjectList().then(res => {
if (res.success) {
this.projectSelectOptions = res.result
} else {
this.$message.warning(res.message)
}
})
},
/**
* 获取流程信息
*/
initProcessInfo () {
this.loading = true
const params = {
taskId: this.$route.query.taskId
}
if (this.$route.query.draftId) {
params.draftId = this.$route.query.draftId
} else {
params.processInstanceId = this.$route.query.processInstanceId
}
queryNoMatchTrackingProcess(params).then(res => {
if (res.success) {
const { result = {} } = res
// 草稿从json里取得
if (result.infoJsonStr) {
const draftResult = JSON.parse(result.infoJsonStr)
this.processInfo = draftResult.processInfo
this.businessInfo = draftResult.businessInfo
this.dataSource = draftResult.dataSource || []
this.approvalInfo = draftResult.approvalInfo
this.draftInitPersonInfo(draftResult.userInfo || {})
} else {
this.processInfo = result.basicProcessInfoDTO || {}
this.dataSource = result.businessInfoDTO.processProjectNotMetLinks || []
this.approvalInfo = result.basicTaskInfoDTO || {}
}
this.$nextTick(() => {
this.processInfoForm.setFieldsValue(this.processInfo)
this.businessInfoForm.setFieldsValue(this.businessInfo)
this.approvalInfoForm.setFieldsValue(this.approvalInfo)
})
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
/**
* 选择标准
*/
selectStandard () {
this.businessInfoForm.validateFields((errors, values) => {
if (!errors) {
const selectedNoMatchItemKeys = this.dataSource.map(item => item.id)
this.$refs.selectStandardDrawer.open(values, selectedNoMatchItemKeys)
}
})
},
handleStandardSelected (list) {
this.dataSource = list
},
/**
* 跳转标准详情
* @param record
*/
toDetailPage ({ standardId, source }) {
let path
// 根据来源跳转不同的详情页
switch (source) {
// 国内
case StandardSource.DOMESTIC.value:
path = '/standardRegulationLibrary/DomesticStandardDetail'
break
// 海外
case StandardSource.OVERSEAS.value:
path = '/standardRegulationLibrary/OverseasStandardDetail'
break
// 企标
case StandardSource.ENTERPRISE.value:
path = '/enterpriseStandardLibrary/enterpriseStandardDetail'
break
default:
break
}
if (!path) {
return
}
const query = {
id: standardId
}
this.$openPageNewSheet({
path, query
})
},
filterOption (input, option) {
return (
option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
)
},
/**
* 转办
*/
handleTurnTo () {
this.$refs.userSelectModal.open()
},
continueTransfer (userId) {
const params = {
taskId: this.$route.query.taskId,
userId
}
this.loading = true
processTransfer(params).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
/**
* 保存
*/
handleSave () {
const processInfo = Object.assign(this.processInfo, this.processInfoForm.getFieldsValue())
const businessInfo = Object.assign(this.businessInfo, this.businessInfoForm.getFieldsValue())
const approvalInfo = Object.assign(this.approvalInfo, this.approvalInfoForm.getFieldsValue())
approvalInfo.taskId = this.$route.query.taskId
const userInfo = this.$refs.personnelInfo.getDataObj()
const checkValueArr = Object.values({ ...processInfo, ...businessInfo, ...approvalInfo, ...userInfo })
if (!checkValueArr.some(tt => !tt) && this.dataSource.length === 0) {
// 提示至少填写一项
this.$message.warning(this.$t('pleaseFillInAtLeastOneItem'))
return
}
const formData = {
processInfo, businessInfo, approvalInfo, userInfo,
dataSource: this.dataSource,
basicTaskInfoDTO: approvalInfo
}
this.loading = true
saveNoMatchTrackingProcess({ infoJsonStr: JSON.stringify(formData) }).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
/**
* 处理表单数据
*/
dealFormData () {
let flag = true, basicProcessInfoDTO = {}, basicTaskInfoDTO = {}, userInfoMap = {}
this.processInfoForm.validateFields((errors, values) => {
if (!errors) {
basicProcessInfoDTO = Object.assign(this.processInfo, values)
} else {
flag = false
}
})
this.approvalInfoForm.validateFields((errors, values) => {
if (!errors) {
basicTaskInfoDTO = Object.assign(this.approvalInfo, values)
basicTaskInfoDTO.taskId = this.$route.query.taskId
} else {
flag = false
}
})
// 发起节点表格无数据需要提示
if (this.currentNode === NoMatchTrackingNodes.initial.value && this.dataSource.length === 0) {
this.$message.warning(this.$t('addAtLeastOneRowOfData'))
flag = false
}
// 展示展开表格,且不被禁用,需要校验表格的表单
if (!this.showSelectStandardForm && !this.expandTableDisabled && !this.$refs.expandTable.submit()) {
this.$message.warning(this.$t('workCenter.checkTableRequired'))
flag = false
}
const basicFlag = flag
// 用户信息
const userInfo = this.$refs.personnelInfo.getDataObjVerify()
if (!userInfo) {
flag = false
} else {
userInfoMap = userInfo
}
if (!flag && !basicFlag) {
this.switchValue = 'base'
} else if (!flag && !userInfo) {
this.switchValue = 'user'
}
const formData = {
basicProcessInfoDTO,
basicTaskInfoDTO,
businessInfoDTO: {
processProjectNotMetLinks: cloneDeep(this.dataSource)
},
userInfoMap
}
return !flag ? false : formData
},
/**
* 提交
*/
handleSubmit () {
const formData = this.dealFormData()
if (!formData) {
return
}
this.loading = true
const submitFunc = this.currentNode === NoMatchTrackingNodes.initial.value ? initialNoMatchTrackingProcess : submitNoMatchTrackingProcess
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
agreeNoMatchTrackingProcess(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
rejectNoMatchTrackingProcess(formData).then(res => {
if (res.success) {
this.$message.success(res.message)
this.goBack()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
handleDesignEngineerNameChange (name) {
this.businessInfo.engineerId_dictText = name
}
}
}
</script>
<style scoped lang="less">
@import '~@assets/less/common.less';
.box-title-text .title-text {
width: 9rem;
}
.form-flex-item {
width: calc((100% - 105px) / 3);
}
.form-flex-item:first-child {
padding-left: 0;
}
/deep/ .custom-flex-form-item .ant-form-item .ant-form-item-label {
width: 8.5rem;
}
</style>