update 征求意见流程

This commit is contained in:
赵霄
2023-11-14 09:27:51 +08:00
parent 09aab41ccc
commit 08a58aed1d
4 changed files with 490 additions and 12 deletions
@@ -39,6 +39,7 @@
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
v-decorator="['processDueDate']"
:disabled="processInfoDisabled"
style="width: 100%" />
</a-form-item>
</a-col>
@@ -49,6 +50,7 @@
@change="event => event.target.value = event.target.value.trim()"
:maxLength="500"
type="textarea"
:disabled="processInfoDisabled"
v-decorator="['processDescription']" />
</a-form-item>
</a-form>
@@ -61,6 +63,7 @@
<!--标准编号-->
<a-form-item :label="$t('standardNumber')">
<standard-selection v-decorator="['standardNumber', validatorRules.standardNumber]"
:disabled="basicServiceInfoDisabled"
:placeholder="$t('pleaseSelect') + $t('standardNumber')" />
</a-form-item>
</div>
@@ -71,6 +74,7 @@
@change="event => event.target.value = event.target.value.trim()"
:maxLength="50"
disabled
:disabled="basicServiceInfoDisabled"
v-decorator="['standardName', validatorRules.standardName]" />
</a-form-item>
</div>
@@ -81,6 +85,7 @@
<a-input class="box-input"
v-decorator="['standardText', validatorRules.standardText]"
readonly
:disabled="basicServiceInfoDisabled"
:placeholder="$t('pleaseSelect') + $t('workCenter.standardConsultationProcess.standardText')" />
<a-button type="primary" class="button-box" @click="chooseStandardText">
{{ this.$t('workCenter.standardConsultationProcess.selectText') }}
@@ -91,13 +96,15 @@
<div class="form-flex-item custom-flex-form-item">
<!--相关文件-->
<a-form-item :label="$t('workCenter.standardConsultationProcess.relevantDocument')">
<j-upload return-id v-decorator="['relatedFile', validatorRules.relatedFile]" />
<j-upload return-id v-decorator="['relatedFile', validatorRules.relatedFile]" :disabled="basicServiceInfoDisabled" />
</a-form-item>
</div>
<div class="form-flex-item custom-flex-form-item">
<!--征求意见结束日期-->
<a-form-item :label="$t('workCenter.standardConsultationProcess.endDate')">
<j-date show-type="day" v-decorator="['consultationDueDate', validatorRules.consultationDueDate]" />
<j-date show-type="day"
v-decorator="['consultationDueDate', validatorRules.consultationDueDate]"
:disabled="basicServiceInfoDisabled" />
</a-form-item>
</div>
</div>
@@ -106,7 +113,74 @@
<!--业务分派信息-->
<template v-if="showDispatchInformation">
<div class="process-part-title">{{ $t('workCenter.dispatchInformation') }}</div>
<a-form :form="dispatchInfoForm"></a-form>
<a-form :form="dispatchInfoForm">
<div class="form-flex-box">
<div class="form-flex-item custom-flex-form-item" v-if="currentNode === ConsultationProcess.distribute.value">
<!--下发人员类型-->
<a-form-item :label="$t('workCenter.standardConsultationProcess.senderType')">
<j-dict-select-tag v-decorator="['userType', validatorRules.userType]"
:placeholder="$t('pleaseSelect') + $t('workCenter.standardConsultationProcess.senderType')"
type="select"
dict-code="sender_type"
:triggerChange="false"
@change="handleSenderTypeChange" />
</a-form-item>
</div>
<div class="form-flex-item custom-flex-form-item" v-if="senderType === SenderType.moduleOwner.value">
<!--模块负责人-->
<a-form-item :label="$t('workCenter.standardConsultationProcess.moduleOwner')">
<user-selection v-decorator="['moduleOwnerId', validatorRules.moduleOwnerId]"
:name-str="dispatchInfo.moduleOwnerId"
type="checkbox"
:placeholder="$t('pleaseSelect') + $t('workCenter.standardConsultationProcess.moduleOwner')" />
</a-form-item>
</div>
<!--下发人员类型选了模块负责人或者模块负责人分发节点都显示这个选项-->
<div class="form-flex-item custom-flex-form-item"
v-if="senderType === SenderType.designEngineer.value || currentNode === ConsultationProcess.moduleOwnerDistribution.value">
<!--设计工程师-->
<a-form-item :label="$t('workCenter.standardConsultationProcess.designEngineer')">
<user-selection v-decorator="['designEngineerId', validatorRules.designEngineerId]"
:name-str="dispatchInfo.designEngineerId"
type="checkbox"
:placeholder="$t('pleaseSelect') + $t('workCenter.standardConsultationProcess.designEngineer')" />
</a-form-item>
</div>
</div>
</a-form>
</template>
<!--征求意见列表-->
<template v-if="showConsultationList">
<div class="process-part-title">{{ $t('workCenter.standardConsultationProcess.solicitationList') }}</div>
<!--设计工程师填写征求意见表格-->
<template v-if="currentNode === ConsultationProcess.designEngineerFillIn.value">
<div class="table-operator">
<!-- 新增-->
<a-button icon="plus" type="primary" @click="handleAdd">{{ $t('newlyAdded') }}</a-button>
<!-- 批量删除-->
<a-button type="primary" icon="delete" ghost @click="batchDel">{{ $t('delete') }}</a-button>
</div>
<div>
<j-table
:can-drag="true"
:scroll="{x: '100%'}"
ref="table"
:rowKey="(record, index) => {return index}"
:columns="columns"
:dataSource="dataSource"
:pagination="false"
:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
:loading="loading">
<!-- 操作栏 -->
<div slot="action" slot-scope="{record, index}" class="action-span-cell">
<a @click="handleEdit(record, index)" class="table-ope-btn">{{ $t('edit') }}</a>
</div>
</j-table>
</div>
</template>
</template>
<!--流程审批信息-->
@@ -149,19 +223,28 @@
{{ $t('reject') }}
</a-button>
</div>
<!--新增编辑征求意见列表弹框-->
<consultation-modal ref="consultationModal" @ok="handleAddData" />
</internal-detail-page>
</template>
<script>
import InternalDetailPage from '../../../components/InternalDetailPage.vue'
import StandardSelection from '../../../components/selection/StandardSelection.vue'
import { ConsultationProcess } from '../../../enums/commonEnums'
import { ConsultationProcess, SenderType } from '../../../enums/commonEnums'
import UserSelection from '../../../components/selection/UserSelection'
import JTable from '../../../components/jero/JTable'
import ConsultationModal from './modules/ConsultationModal'
import line from 'ant-design-vue/lib/progress/line'
export default {
name: 'StandardConsultationProcess',
components: { InternalDetailPage, StandardSelection },
components: { JTable, UserSelection, InternalDetailPage, StandardSelection, ConsultationModal },
data () {
return {
SenderType,
ConsultationProcess,
switchValue: 'base',
twoLabelCol: {
xs: { span: 24 },
@@ -180,12 +263,17 @@ export default {
sm: { span: 22 }
},
// 流程信息
processInfo: {},
processInfoForm: this.$form.createForm(this),
// 业务基本信息
basicServiceInfo: {},
basicServiceInfoForm: this.$form.createForm(this),
// 流程审批信息
approvalInfo: {},
approvalInfoForm: this.$form.createForm(this),
// 业务分派信息
dispatchInfo: {},
dispatchInfoDisabled: false,
dispatchInfoForm: this.$form.createForm(this),
validatorRules: {
// 标准编号
@@ -221,21 +309,114 @@ export default {
message: this.$t('pleaseSelect') + this.$t('workCenter.standardConsultationProcess.endDate')
}],
validateTrigger: 'change'
},
// 下发人员类型
userType: {
rules: [{
required: true,
message: this.$t('pleaseSelect') + this.$t('workCenter.standardConsultationProcess.senderType')
}],
validateTrigger: 'change'
},
// 模块负责人
moduleOwnerId: {
rules: [{
required: true,
message: this.$t('pleaseSelect') + this.$t('workCenter.standardConsultationProcess.senderType')
}],
validateTrigger: 'change'
},
// 设计工程师
designEngineerId: {
rules: [{
required: true,
message: this.$t('pleaseSelect') + this.$t('workCenter.standardConsultationProcess.designEngineer')
}],
validateTrigger: 'change'
}
},
btnList: [], // 显示的按钮
loading: false,
currentNode: '2',
nodeEnumsKey: null // 当前节点对应枚举的key
nodeEnumsKey: null, // 当前节点对应枚举的key
senderType: null,
columns: [
{
title: this.$t('serialNumber'),
dataIndex: '',
key: 'rowIndex',
align: 'center',
width: 80,
customRender: function (t, r, index) {
return parseInt(index) + 1
}
},
{ // 章节编号
title: this.$t('workCenter.esInspectionProcess.sectionNumber'),
width: 180,
dataIndex: 'chapterNumber'
},
{ // 章节名称
title: this.$t('workCenter.standardConsultationProcess.chapterName'),
width: 180,
dataIndex: 'chapterName'
},
{ // 修改意见内容
title: this.$t('workCenter.enStandardChange.revisedOpinionContent'),
children: [
{ // 修改前
title: this.$t('workCenter.enStandardChange.beforeUpdate'),
align: 'center',
width: 180,
dataIndex: 'modificationBefore',
scopedSlots: { customRender: 'text' }
},
{ // 修改后
title: this.$t('workCenter.enStandardChange.afterUpdate'),
align: 'center',
width: 180,
dataIndex: 'modificationAfter',
scopedSlots: { customRender: 'text' }
},
{ // 修改理由
title: this.$t('workCenter.enStandardChange.updateReason'),
align: 'center',
width: 180,
dataIndex: 'modificationReason',
scopedSlots: { customRender: 'text' }
}
]
},
{
title: this.$t('operation'),
scopedSlots: { customRender: 'action' },
align: 'center',
width: 200
}
],
dataSource: [],
selectedRowKeys: []
}
},
computed: {
pageTitle () {
return `${this.$t('flowCenter')}${this.$route.meta.title}`
},
// 是否展示业务分派信息
// 是否展示业务分派信息,各部所主管级领导分发、模块负责人分发显示
showDispatchInformation () {
return this.currentNode === ConsultationProcess.distribute.value
return this.currentNode === ConsultationProcess.distribute.value || this.currentNode === ConsultationProcess.moduleOwnerDistribution.value
},
// 流程信息禁用,非发起节点都禁用
processInfoDisabled () {
return !!this.currentNode
},
// 业务基本信息禁用,非发起节点都禁用
basicServiceInfoDisabled () {
return this.currentNode && this.currentNode !== ConsultationProcess.initiate.value
},
// 展示征求意见列表(设计工程师填写征求意见)
showConsultationList () {
return this.currentNode === ConsultationProcess.designEngineerFillIn.value
}
},
created () {
@@ -251,14 +432,56 @@ export default {
switchChange (value) {
this.switchValue = value
},
/**
* 选择标准文本
*/
chooseStandardText () {
},
/**
* 下发人员类型修改
* @param value
*/
handleSenderTypeChange (value) {
this.senderType = value
},
/**
* 征求意见列表-新增
*/
handleAdd () {
const pdfId = '1723899113057075201'
this.$refs.consultationModal.add(pdfId)
},
/**
* 表单填写完成,新增数据
*/
handleAddData (lineData) {
if (lineData.index || lineData.index === 0) {
this.dataSource.splice(lineData.index, 1, lineData)
} else {
this.dataSource.push(lineData)
}
},
/**
* 征求意见列表-删除
*/
batchDel () {
},
onSelectChange (selectedRowKeys) {
this.selectedRowKeys = selectedRowKeys
},
handleEdit (record, index) {
record.index = index
this.$refs.consultationModal.edit(null, record)
}
}
}
</script>
<style scoped lang="less">
@import '~@assets/less/common.less';
.box-title-text {
height: 40px;
line-height: 40px;
@@ -0,0 +1,237 @@
<template>
<j-modal
:title="title"
:maskClosable="true"
:width="500"
:closable="true"
@cancel="handleCancel"
fullscreen
:visible="visible">
<a-spin :spinning="loading">
<div class="modal-box">
<div class="modal-left">
<iframe v-if="previewUrl" :src="previewUrl" width="100%" frameborder="0"></iframe>
<a-empty class="empty-file" v-else description="当前文件类型暂不支持预览"></a-empty>
</div>
<div class="modal-right">
<a-form :form="form">
<!--章节编号-->
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('workCenter.esInspectionProcess.sectionNumber')">
<a-input :placeholder="$t('pleaseEnter') + $t('workCenter.esInspectionProcess.sectionNumber')"
:maxLength="50"
@change="event => event.target.value = event.target.value.trim()"
v-decorator="['chapterNumber', validatorRules.chapterNumber]" />
</a-form-item>
<!--章节名称-->
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('workCenter.standardConsultationProcess.chapterName')">
<a-input :placeholder="$t('pleaseEnter') + $t('workCenter.standardConsultationProcess.chapterName')"
:maxLength="50"
@change="event => event.target.value = event.target.value.trim()"
v-decorator="['chapterName', validatorRules.chapterName]" />
</a-form-item>
<!--修改前-->
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('workCenter.enStandardChange.beforeUpdate')">
<a-input :placeholder="$t('pleaseEnter') + $t('workCenter.enStandardChange.beforeUpdate')"
:maxLength="50"
@change="event => event.target.value = event.target.value.trim()"
v-decorator="['modificationBefore', validatorRules.modificationBefore]" />
</a-form-item>
<!-- 修改后 -->
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('workCenter.enStandardChange.afterUpdate')">
<a-input :placeholder="$t('pleaseEnter') + $t('workCenter.enStandardChange.afterUpdate')"
:maxLength="50"
@change="event => event.target.value = event.target.value.trim()"
v-decorator="['modificationAfter', validatorRules.modificationAfter]" />
</a-form-item>
<!-- 修改理由 -->
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('workCenter.enStandardChange.updateReason')">
<a-input :placeholder="$t('pleaseEnter') + $t('workCenter.enStandardChange.updateReason')"
:maxLength="50"
@change="event => event.target.value = event.target.value.trim()"
v-decorator="['modificationReason', validatorRules.modificationReason]" />
</a-form-item>
</a-form>
</div>
</div>
</a-spin>
<template v-slot:footer>
<a-button @click="handleCancel" :loading="loading">{{ $t('cancel') }}</a-button>
<a-button type="primary" @click="handleOk(false)">{{ $t('submitAddAdd') }}</a-button>
<a-button @click="handleOk(true)" type="primary" :loading="loading">{{ $t('submit') }}</a-button>
</template>
</j-modal>
</template>
<script>
import { getFileInfo } from '../../../../api/api'
import Vue from 'vue'
import { ACCESS_TOKEN } from '../../../../store/mutation-types'
import { previewPdf } from '../../../../utils/previewPdf'
import { Base64 } from 'js-base64'
export default {
name: 'ConsultationModal',
data () {
return {
title: this.$t('newlyAdded'),
visible: false,
loading: false,
previewUrl: null,
form: this.$form.createForm(this),
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 6 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 }
},
validatorRules: {
// 章节编号
chapterNumber: {
rules: [{ required: true, message: this.$t('pleaseEnter') + this.$t('workCenter.esInspectionProcess.sectionNumber') }],
validateTrigger: 'blur'
},
// 章节名称
chapterName: {
rules: [{ required: false, message: this.$t('pleaseEnter') + this.$t('workCenter.standardConsultationProcess.chapterName') }],
validateTrigger: 'blur'
},
// 修改前
modificationBefore: {
rules: [{ required: false, message: this.$t('pleaseEnter') + this.$t('workCenter.enStandardChange.beforeUpdate') }],
validateTrigger: 'blur'
},
// 修改后
modificationAfter: {
rules: [{ required: true, message: this.$t('pleaseEnter') + this.$t('workCenter.enStandardChange.afterUpdate') }],
validateTrigger: 'blur'
},
// 修改理由
modificationReason: {
rules: [{ required: true, message: this.$t('pleaseEnter') + this.$t('workCenter.enStandardChange.updateReason') }],
validateTrigger: 'blur'
}
}
}
},
methods: {
async add (fileId) {
this.title = this.$t('newlyAdded')
this.visible = true
if (!fileId) {
return
}
this.loading = true
await this.handlePreview(fileId)
this.loading = false
},
async edit (fileId, record) {
this.title = this.$t('edit')
this.visible = true
this.model = Object.assign({}, record)
this.$nextTick(() => {
this.form.setFieldsValue(this.model)
})
if (!fileId) {
return
}
this.loading = true
await this.handlePreview(fileId)
this.loading = false
},
handlePreview (fileId) {
return new Promise(resolve => {
getFileInfo({ id: fileId }).then(res => {
if (res.success) {
const fileInfo = res.result || {}
const fileFullUrl = `${window._CONFIG.domianWebSocketURL}/sys/common/download/${fileInfo.id}?token=${Vue.ls.get(ACCESS_TOKEN)}&fullfilename=${fileInfo.fileName}`
// 截取文件后缀名
const fileSuffix = (fileInfo.fileName ? fileInfo.fileName.split('.')[fileInfo.fileName.split('.').length - 1] : '').toLowerCase()
switch (fileSuffix) {
case 'pdf':
this.previewUrl = previewPdf(fileInfo.id)
break
case 'doc':
case 'docx':
this.previewUrl = `${window._CONFIG.onlinePreviewDomainURL}?url=${encodeURIComponent(Base64.encode(fileFullUrl))}`
break
default:
break
}
} else {
this.$message.warning(res.message)
}
}).finally(() => {
resolve()
})
})
},
handleOk (needClose) {
this.form.validateFields((errors, values) => {
if (!errors) {
const formData = Object.assign(this.model, values)
this.$emit('ok', formData)
if (needClose) {
this.close()
} else {
this.form.resetFields()
this.model = {}
}
}
})
},
handleCancel () {
this.close()
},
close () {
this.visible = false
this.previewUrl = null
this.model = {}
this.form.resetFields()
}
}
}
</script>
<style scoped lang="less">
/deep/ .ant-modal-body {
padding: 0;
}
/deep/ .ant-spin-nested-loading, /deep/ .ant-spin-container {
height: 100%;
width: 100%;
}
.modal-box {
height: 100%;
width: 100%;
display: flex;
}
.modal-left {
width: 60%;
height: 100%;
iframe {
height: calc(100% - 5px);
}
}
.modal-right {
width: 40%;
height: 100%;
overflow-y: auto;
padding: 24px;
}
.ant-empty {
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
}
</style>