fix:bug
This commit is contained in:
parent
bc33619a91
commit
0d2457af5b
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -48,6 +48,10 @@ export default {
|
||||
url: '/custom/template/export',
|
||||
method: 'get'
|
||||
},
|
||||
DOWNLODE_ALL_MODEL: {
|
||||
url: '/custom/template/exportMultiple',
|
||||
method: 'get'
|
||||
},
|
||||
//获取部门
|
||||
GET_DEPARTMENT: {
|
||||
url: '/custom/template/getDept',
|
||||
|
||||
@ -276,17 +276,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 流程主题 -->
|
||||
<div class="approval-process-title">
|
||||
<div class="description-label">
|
||||
流程主题 <span class="required-mark">*</span>
|
||||
</div>
|
||||
<el-input
|
||||
v-model="approvalFormData.processTitle"
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
placeholder="请输入流程主题"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 说明 -->
|
||||
<div class="approval-description">
|
||||
@ -305,6 +295,17 @@
|
||||
<div class="approval-workflow">
|
||||
<div class="workflow-title">
|
||||
审批环节
|
||||
</div>
|
||||
<div class="approval-process-title">
|
||||
<div class="description-label">
|
||||
流程主题 <span class="required-mark">*</span>
|
||||
</div>
|
||||
<el-input
|
||||
v-model="approvalFormData.processTitle"
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
placeholder="请输入流程主题"
|
||||
/>
|
||||
</div>
|
||||
<div class="workflow-table">
|
||||
<table class="workflow-table-content">
|
||||
@ -603,7 +604,7 @@ export default {
|
||||
// }
|
||||
// initialize version data for v2/v3 as example variations
|
||||
// 加载权限数据
|
||||
this.loadUserSelfRole()
|
||||
// this.loadUserSelfRole()
|
||||
// 加载责任人列表和填写人列表
|
||||
this.loadResponsiblePersons()
|
||||
this.loadFillerPersons()
|
||||
|
||||
@ -544,7 +544,7 @@ export default {
|
||||
},
|
||||
handleDownloadImportTemplate() {
|
||||
const request = {
|
||||
...api.DOWNLODE_MODEL,
|
||||
...api.DOWNLODE_ALL_MODEL,
|
||||
disableSuccessMsg: true
|
||||
}
|
||||
this.$request(request)
|
||||
|
||||
@ -198,6 +198,16 @@
|
||||
:rows="2"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 审批环节 -->
|
||||
<div class="approval-workflow">
|
||||
<div class="workflow-title">
|
||||
审批环节
|
||||
</div>
|
||||
<div>
|
||||
<div class="approval-process-title">
|
||||
<div class="description-label">
|
||||
流程主题 <span class="required-mark">*</span>
|
||||
</div>
|
||||
@ -208,11 +218,6 @@
|
||||
placeholder="请输入流程主题"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 审批环节 -->
|
||||
<div class="approval-workflow">
|
||||
<div class="workflow-title">
|
||||
审批环节
|
||||
</div>
|
||||
<div class="workflow-table">
|
||||
<table class="workflow-table-content">
|
||||
@ -612,7 +617,7 @@ export default {
|
||||
// 根据 GET_MODEL_DETAIL 接口返回的 status 控制维护参数和导入按钮
|
||||
// 检查状态是否为 DRAFT 或 COMPLETE,且当前版本是最新版本
|
||||
const status = this.currentStatus || ''
|
||||
return (status === 'DRAFT' || status === 'COMPLETE') && this.isLatestVersion
|
||||
return (status === 'DRAFT' || status === 'COMPLETE')
|
||||
},
|
||||
// 检查是否应该显示维护参数按钮(在 DRAFT 或 COMPLETE 状态下都显示,且当前版本是最新版本)
|
||||
shouldShowMaintainButton() {
|
||||
@ -974,7 +979,7 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadUserSelfRole()
|
||||
// this.loadUserSelfRole()
|
||||
// 优先使用 props,如果没有则使用路由参数
|
||||
if (this.templateId) {
|
||||
this.internalTemplateId = this.templateId
|
||||
@ -2919,7 +2924,7 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.required-mark{color:#f56c6c;margin-left:4px}
|
||||
// 审批内容样式
|
||||
.approval-content {
|
||||
display: flex;
|
||||
|
||||
@ -34,6 +34,12 @@
|
||||
align="center"
|
||||
min-width="150"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="roleCode"
|
||||
label="角色代码"
|
||||
align="center"
|
||||
min-width="150"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="roleDescription"
|
||||
label="角色描述"
|
||||
@ -312,8 +318,7 @@
|
||||
ref="addRoleForm"
|
||||
:model="addRoleFormData"
|
||||
:rules="addRoleFormRules"
|
||||
label-width="100px"
|
||||
>
|
||||
label-width="100px">
|
||||
<el-form-item label="角色名称" prop="roleName">
|
||||
<el-input
|
||||
v-model="addRoleFormData.roleName"
|
||||
@ -322,6 +327,14 @@
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色代码" prop="roleCode">
|
||||
<el-input
|
||||
v-model="addRoleFormData.roleCode"
|
||||
placeholder="请输入角色代码"
|
||||
maxlength="50"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色描述" prop="roleDescription">
|
||||
<el-input
|
||||
v-model="addRoleFormData.roleDescription"
|
||||
@ -332,7 +345,7 @@
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-form-item>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="handleAddRoleDialogClose">
|
||||
取消
|
||||
@ -864,10 +877,12 @@ export default {
|
||||
? {
|
||||
id: this.addRoleFormData.roleId,
|
||||
roleName: this.addRoleFormData.roleName,
|
||||
roleCode: this.addRoleFormData.roleCode,
|
||||
roleDescription: this.addRoleFormData.roleDescription
|
||||
}
|
||||
: {
|
||||
roleName: this.addRoleFormData.roleName,
|
||||
roleCode: this.addRoleFormData.roleCode,
|
||||
roleDescription: this.addRoleFormData.roleDescription
|
||||
},
|
||||
disableSuccessMsg: true
|
||||
@ -1105,7 +1120,7 @@ export default {
|
||||
// 加载部门列表
|
||||
loadDepartmentList() {
|
||||
const request = {
|
||||
...api.GET_SUB_DEPT,
|
||||
...api.QUERY_ORG_TREE,
|
||||
disableSuccessMsg: true
|
||||
}
|
||||
this.$request(request)
|
||||
|
||||
@ -84,7 +84,9 @@
|
||||
</div>
|
||||
|
||||
<div class="toolbar">
|
||||
<el-button type="primary" @click="handleCreate">新增</el-button>
|
||||
<el-button type="primary" @click="handleCreate">
|
||||
新增
|
||||
</el-button>
|
||||
<!-- <el-button @click="handleDownloadTemplate">下载模板</el-button> -->
|
||||
</div>
|
||||
<div class="page-data-list">
|
||||
@ -111,7 +113,9 @@
|
||||
v-for="(colConfig, index) in tableConfig.colConfigs"
|
||||
v-slot:[colConfig.customHeadSlot]="{ column }"
|
||||
>
|
||||
<div v-if="colConfig.customHeadSlot" :key="index"> {{ column }} {{ colConfig }} </div>
|
||||
<div v-if="colConfig.customHeadSlot" :key="index">
|
||||
{{ column }} {{ colConfig }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template
|
||||
@ -122,52 +126,60 @@
|
||||
<span
|
||||
v-if="row[colConfig.prop] === 'APPROVING'"
|
||||
style="background: #E6A23C; padding: 4px 8px; color: white; border-radius: 20px;"
|
||||
>审核中</span
|
||||
>
|
||||
审核中
|
||||
</span>
|
||||
<span
|
||||
v-else-if="row[colConfig.prop] === 'COMPLETE'"
|
||||
style="background: #67C23A; padding: 4px 8px; color: white; border-radius: 20px;"
|
||||
>已完成</span
|
||||
>
|
||||
已完成
|
||||
</span>
|
||||
<span
|
||||
v-else-if="row[colConfig.prop] === 'DRAFT'"
|
||||
style="background: #909399; padding: 4px 8px; color: white; border-radius: 20px;"
|
||||
>草稿</span
|
||||
>
|
||||
草稿
|
||||
</span>
|
||||
<span
|
||||
v-else-if="row[colConfig.prop] === 'REJECTED'"
|
||||
style="background: #F56C6C; padding: 4px 8px; color: white; border-radius: 20px;"
|
||||
>已拒绝</span
|
||||
>
|
||||
已拒绝
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
style="background: #909399; padding: 4px 8px; color: white; border-radius: 20px;"
|
||||
>-</span
|
||||
>
|
||||
-
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="colConfig.customSlot === 'options'" :key="'op' + index + '' + rowIndex">
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
class="el-link el-link--primary"
|
||||
@click.stop="handleRowView(row)"
|
||||
>查看</a
|
||||
>
|
||||
查看
|
||||
</a>
|
||||
<span style="width: 6px; display: inline-block"></span>
|
||||
<a
|
||||
v-if="row.status !== 'APPROVING' && row.status !== 'COMPLETE'"
|
||||
v-if="false"
|
||||
href="javascript:void(0)"
|
||||
class="el-link el-link--primary"
|
||||
@click.stop="handleEdit(row)"
|
||||
>修改</a
|
||||
>
|
||||
修改
|
||||
</a>
|
||||
<span style="width: 6px; display: inline-block"></span>
|
||||
<a
|
||||
v-if="row.status === 'APPROVING'"
|
||||
href="javascript:void(0)"
|
||||
class="el-link el-link--primary"
|
||||
@click.stop="handleApprove(row)"
|
||||
>审批</a
|
||||
>
|
||||
审批
|
||||
</a>
|
||||
<span
|
||||
v-if="row.status === 'APPROVING'"
|
||||
style="width: 6px; display: inline-block"
|
||||
@ -177,8 +189,9 @@
|
||||
href="javascript:void(0)"
|
||||
class="el-link el-link--primary"
|
||||
@click.stop="handleLaunch(row)"
|
||||
>发起</a
|
||||
>
|
||||
发起
|
||||
</a>
|
||||
<span
|
||||
v-if="!row.status || row.status === '' || row.status === 'DRAFT'"
|
||||
style="width: 6px; display: inline-block"
|
||||
@ -188,8 +201,9 @@
|
||||
href="javascript:void(0)"
|
||||
class="el-link el-link--primary"
|
||||
@click.stop="handleRestart(row)"
|
||||
>重新发起</a
|
||||
>
|
||||
重新发起
|
||||
</a>
|
||||
<span
|
||||
v-if="row.status === 'REJECTED'"
|
||||
style="width: 6px; display: inline-block"
|
||||
@ -199,8 +213,9 @@
|
||||
href="javascript:void(0)"
|
||||
class="el-link el-link--primary"
|
||||
@click.stop="handleDownload(row)"
|
||||
>下载</a
|
||||
>
|
||||
下载
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -344,8 +359,12 @@
|
||||
</el-form>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="handleDialogClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
<el-button @click="handleDialogClose">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
@ -359,6 +378,18 @@
|
||||
@close="handleLaunchDialogClose"
|
||||
>
|
||||
<div class="dialog-body-wrapper">
|
||||
<div class="approval-process-title">
|
||||
<div class="description-label">
|
||||
流程主题 <span class="required-mark">*</span>
|
||||
</div>
|
||||
<el-input
|
||||
v-model="launchProcessTitle"
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
placeholder="请输入流程主题"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="approval-workflow">
|
||||
<div class="workflow-title">
|
||||
审批环节
|
||||
@ -414,8 +445,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="handleLaunchDialogClose">取消</el-button>
|
||||
<el-button type="primary" :loading="launching" @click="handleLaunchSubmit">确定</el-button>
|
||||
<el-button @click="handleLaunchDialogClose">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button type="primary" :loading="launching" @click="handleLaunchSubmit">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
@ -503,6 +538,7 @@ export default {
|
||||
currentEditRow: null, // 当前要修改的行数据
|
||||
launchDialogVisible: false, // 发起弹窗显示状态
|
||||
currentLaunchRow: null, // 当前要发起的行数据
|
||||
launchProcessTitle: '',
|
||||
launchWorkflowSteps: [
|
||||
{
|
||||
name: '校对',
|
||||
@ -717,6 +753,7 @@ export default {
|
||||
},
|
||||
handleLaunch(row) {
|
||||
this.currentLaunchRow = row
|
||||
this.launchProcessTitle = row.title || ''
|
||||
// 重置审批环节
|
||||
this.launchWorkflowSteps = [
|
||||
{
|
||||
@ -746,6 +783,7 @@ export default {
|
||||
handleLaunchDialogClose() {
|
||||
this.launchDialogVisible = false
|
||||
this.currentLaunchRow = null
|
||||
this.launchProcessTitle = ''
|
||||
// 重置审批环节
|
||||
this.launchWorkflowSteps = [
|
||||
{
|
||||
@ -787,6 +825,13 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
// 流程主题必填
|
||||
const processTitle = (this.launchProcessTitle || '').trim()
|
||||
if (!processTitle) {
|
||||
this.$message.warning('请填写流程主题')
|
||||
return
|
||||
}
|
||||
|
||||
const reportId = this.currentLaunchRow.reportId || this.currentLaunchRow.id
|
||||
if (!reportId) {
|
||||
this.$message.error('缺少报告ID')
|
||||
@ -797,6 +842,7 @@ export default {
|
||||
const submitData = {
|
||||
reportId: reportId,
|
||||
userId: getUserId(),
|
||||
processTitle: processTitle,
|
||||
proofreadUsers: this.launchWorkflowSteps[0].handlers,
|
||||
reviewUsers: this.launchWorkflowSteps[1].handlers,
|
||||
countersignUsers: [],
|
||||
|
||||
@ -18,8 +18,27 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<!-- 草稿状态:显示发起和修改按钮 -->
|
||||
<template v-if="reportDetail.status === 'DRAFT' && !isEditMode">
|
||||
<el-button @click="handleLaunch">
|
||||
发起
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleEdit">
|
||||
修改
|
||||
</el-button>
|
||||
</template>
|
||||
<!-- 编辑模式:显示保存和返回按钮 -->
|
||||
<template v-if="isEditMode">
|
||||
<el-button @click="handleCancelEdit">
|
||||
返回
|
||||
</el-button>
|
||||
<el-button type="primary" :loading="saving" @click="handleSave">
|
||||
保存
|
||||
</el-button>
|
||||
</template>
|
||||
<!-- 审批中状态:显示审批按钮 -->
|
||||
<el-button
|
||||
v-if="reportDetail.status === 'APPROVING'"
|
||||
v-if="reportDetail.status === 'APPROVING' && !isEditMode"
|
||||
type="primary"
|
||||
@click="handleApprove"
|
||||
>
|
||||
@ -33,6 +52,8 @@
|
||||
<div class="section-title">
|
||||
报告信息
|
||||
</div>
|
||||
<!-- 只读模式 -->
|
||||
<template v-if="!isEditMode">
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<span class="label">标题名称</span>
|
||||
@ -97,7 +118,7 @@
|
||||
<div class="info-item">
|
||||
<span class="label">文件</span>
|
||||
<span class="value">
|
||||
<a v-if="reportDetail.filePath" href="javascript:void(0)" class="el-link el-link--primary" @click.stop="handleDownload(reportDetail)">下载</a>
|
||||
<a v-if="reportDetail.filePath" href="javascript:void(0)" class="el-link el-link--primary" @click.stop="handleDownload(reportDetail)">{{ reportDetail.fileName }}</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -105,10 +126,121 @@
|
||||
<span class="label">说明:</span>
|
||||
<span class="value">{{ reportDetail.explanation }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 编辑模式 -->
|
||||
<template v-else>
|
||||
<el-form ref="editForm" :model="editFormData" label-width="150px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="标题名称" prop="title">
|
||||
<el-input v-model="editFormData.title" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="厂家名称(全称)" prop="manufacturerName">
|
||||
<el-input v-model="editFormData.manufacturerName" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="产品型号(全称)" prop="modelName">
|
||||
<el-input v-model="editFormData.modelName" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="厂家简称" prop="manufacturerAbbreviation">
|
||||
<el-input v-model="editFormData.manufacturerAbbreviation" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="产品型号简称" prop="modelAbbreviation">
|
||||
<el-input v-model="editFormData.modelAbbreviation" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="产品编号" prop="productNumber">
|
||||
<el-input v-model="editFormData.productNumber" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领域/模块" prop="module">
|
||||
<el-input v-model="editFormData.module" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="板块" prop="plate">
|
||||
<el-input v-model="editFormData.plate" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="平台" prop="platform">
|
||||
<el-input v-model="editFormData.platform" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="系列" prop="series">
|
||||
<el-input v-model="editFormData.series" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="细分市场" prop="marketSegment">
|
||||
<el-input v-model="editFormData.marketSegment" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目名称" prop="projectName">
|
||||
<el-input v-model="editFormData.projectName" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目编号" prop="projectNumber">
|
||||
<el-input v-model="editFormData.projectNumber" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="附件上传" prop="attachments">
|
||||
<el-upload
|
||||
ref="upload"
|
||||
:auto-upload="false"
|
||||
:on-change="handleFileChange"
|
||||
:on-remove="handleFileRemove"
|
||||
:file-list="fileList"
|
||||
:limit="1"
|
||||
accept=".doc,.pdf,.xls,.xlsx,.ppt,.pptx"
|
||||
>
|
||||
<el-button type="primary" icon="el-icon-upload">
|
||||
选择文件
|
||||
</el-button>
|
||||
<div slot="tip" class="el-upload__tip">
|
||||
支持扩展名: .doc .pdf .xls .xlsx .ppt .pptx,仅支持上传一个文件
|
||||
</div>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="说明" prop="explanation">
|
||||
<el-input
|
||||
v-model="editFormData.explanation"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</section>
|
||||
|
||||
<!-- 审批流程 -->
|
||||
<section v-if="reportDetail.status && reportDetail.status !== 'DRAFT'" class="block-section">
|
||||
<section v-if="reportDetail.status && reportDetail.status !== 'DRAFT' && reportDetail.flowId" class="block-section">
|
||||
<div class="section-title">
|
||||
审批流程
|
||||
</div>
|
||||
@ -150,6 +282,92 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 发起弹窗 -->
|
||||
<el-dialog
|
||||
title="发起"
|
||||
:visible.sync="launchDialogVisible"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
@close="handleLaunchDialogClose"
|
||||
>
|
||||
<div class="dialog-body-wrapper">
|
||||
<div class="approval-process-title">
|
||||
<div class="description-label">
|
||||
流程主题 <span class="required-mark">*</span>
|
||||
</div>
|
||||
<el-input
|
||||
v-model="launchProcessTitle"
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
placeholder="请输入流程主题"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="approval-workflow">
|
||||
<div class="workflow-title">
|
||||
审批环节
|
||||
</div>
|
||||
<div class="workflow-table">
|
||||
<table class="workflow-table-content">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="step-name-col">
|
||||
环节名称
|
||||
</th>
|
||||
<th class="handler-col">
|
||||
处理人
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(step, index) in launchWorkflowSteps" :key="index" class="workflow-row">
|
||||
<td class="step-name-cell">
|
||||
<span class="step-name">
|
||||
{{ step.name }}
|
||||
<span v-if="step.required" class="required-mark">*</span>
|
||||
</span>
|
||||
</td>
|
||||
<td class="handler-cell">
|
||||
<el-select
|
||||
v-model="step.handlers"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
placeholder="请选择"
|
||||
:remote-method="(query) => handleLaunchRemoteSearch(query, index)"
|
||||
:loading="step.loading"
|
||||
class="handler-select"
|
||||
@change="(value) => handleLaunchHandlerChange(index, value)"
|
||||
>
|
||||
<el-option
|
||||
v-for="person in step.options"
|
||||
:key="person.userNumber"
|
||||
:value="person.userId"
|
||||
:label="person.username"
|
||||
>
|
||||
<span class="username-text">{{ person.username }}</span>
|
||||
<span class="user-id-text">{{ person.userNumber }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="handleLaunchDialogClose">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button type="primary" :loading="launching" @click="handleLaunchSubmit">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 审批弹窗 -->
|
||||
<el-dialog
|
||||
title="审核"
|
||||
@ -216,7 +434,57 @@ export default {
|
||||
result: '',
|
||||
opinion: ''
|
||||
},
|
||||
approvalSubmitting: false
|
||||
approvalSubmitting: false,
|
||||
isEditMode: false, // 编辑模式
|
||||
editFormData: {
|
||||
title: '',
|
||||
manufacturerName: '',
|
||||
modelName: '',
|
||||
manufacturerAbbreviation: '',
|
||||
modelAbbreviation: '',
|
||||
productNumber: '',
|
||||
module: '',
|
||||
plate: '',
|
||||
platform: '',
|
||||
series: '',
|
||||
marketSegment: '',
|
||||
projectName: '',
|
||||
projectNumber: '',
|
||||
explanation: '',
|
||||
fileUrl: '',
|
||||
fileName: ''
|
||||
},
|
||||
originalReportDetail: {}, // 保存原始数据,用于取消编辑时恢复
|
||||
selectedFile: null, // 选中的文件
|
||||
fileList: [], // 文件列表
|
||||
uploading: false, // 上传中状态
|
||||
saving: false, // 保存中状态
|
||||
launchDialogVisible: false, // 发起弹窗显示状态
|
||||
launchProcessTitle: '', // 流程主题
|
||||
launchWorkflowSteps: [
|
||||
{
|
||||
name: '校对',
|
||||
required: true,
|
||||
handlers: [],
|
||||
options: [],
|
||||
loading: false
|
||||
},
|
||||
{
|
||||
name: '审核',
|
||||
required: true,
|
||||
handlers: [],
|
||||
options: [],
|
||||
loading: false
|
||||
},
|
||||
{
|
||||
name: '批准',
|
||||
required: true,
|
||||
handlers: [],
|
||||
options: [],
|
||||
loading: false
|
||||
}
|
||||
],
|
||||
launching: false // 发起中状态
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -374,6 +642,8 @@ export default {
|
||||
this.$request(request)
|
||||
.asyncThen((resp) => {
|
||||
this.reportDetail = resp.data || resp
|
||||
// 保存原始数据(用于编辑模式取消时恢复)
|
||||
this.originalReportDetail = JSON.parse(JSON.stringify(this.reportDetail))
|
||||
// 如果flowId存在且状态不是草稿,加载审批流程
|
||||
if (flowId && this.reportDetail.status && this.reportDetail.status !== 'DRAFT') {
|
||||
this.getApprovalSpet(flowId)
|
||||
@ -610,6 +880,414 @@ export default {
|
||||
}
|
||||
return formattedStep
|
||||
})
|
||||
},
|
||||
// 发起功能
|
||||
handleLaunch() {
|
||||
this.launchProcessTitle = this.reportDetail.title || ''
|
||||
// 重置审批环节
|
||||
this.launchWorkflowSteps = [
|
||||
{
|
||||
name: '校对',
|
||||
required: true,
|
||||
handlers: [],
|
||||
options: [],
|
||||
loading: false
|
||||
},
|
||||
{
|
||||
name: '审核',
|
||||
required: true,
|
||||
handlers: [],
|
||||
options: [],
|
||||
loading: false
|
||||
},
|
||||
{
|
||||
name: '批准',
|
||||
required: true,
|
||||
handlers: [],
|
||||
options: [],
|
||||
loading: false
|
||||
}
|
||||
]
|
||||
this.launchDialogVisible = true
|
||||
},
|
||||
// 关闭发起弹窗
|
||||
handleLaunchDialogClose() {
|
||||
this.launchDialogVisible = false
|
||||
this.launchProcessTitle = ''
|
||||
// 重置审批环节
|
||||
this.launchWorkflowSteps = [
|
||||
{
|
||||
name: '校对',
|
||||
required: true,
|
||||
handlers: [],
|
||||
options: [],
|
||||
loading: false
|
||||
},
|
||||
{
|
||||
name: '审核',
|
||||
required: true,
|
||||
handlers: [],
|
||||
options: [],
|
||||
loading: false
|
||||
},
|
||||
{
|
||||
name: '批准',
|
||||
required: true,
|
||||
handlers: [],
|
||||
options: [],
|
||||
loading: false
|
||||
}
|
||||
]
|
||||
},
|
||||
// 发起提交
|
||||
handleLaunchSubmit() {
|
||||
// 验证必填环节是否已选择处理人
|
||||
const requiredStepsWithoutHandlers = this.launchWorkflowSteps.filter(
|
||||
(step) => step.required && (!step.handlers || step.handlers.length === 0)
|
||||
)
|
||||
if (requiredStepsWithoutHandlers.length > 0) {
|
||||
const stepNames = requiredStepsWithoutHandlers.map((step) => step.name).join('、')
|
||||
this.$message.warning(`请为必填环节"${stepNames}"选择处理人`)
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.reportDetail.reportId && !this.reportDetail.id) {
|
||||
this.$message.error('缺少报告信息')
|
||||
return
|
||||
}
|
||||
|
||||
// 流程主题必填
|
||||
const processTitle = (this.launchProcessTitle || '').trim()
|
||||
if (!processTitle) {
|
||||
this.$message.warning('请填写流程主题')
|
||||
return
|
||||
}
|
||||
|
||||
const reportId = this.reportDetail.reportId || this.reportDetail.id
|
||||
if (!reportId) {
|
||||
this.$message.error('缺少报告ID')
|
||||
return
|
||||
}
|
||||
|
||||
// 构建提交数据
|
||||
const submitData = {
|
||||
reportId: reportId,
|
||||
userId: getUserId(),
|
||||
processTitle: processTitle,
|
||||
proofreadUsers: this.launchWorkflowSteps[0].handlers,
|
||||
reviewUsers: this.launchWorkflowSteps[1].handlers,
|
||||
countersignUsers: [],
|
||||
approveUsers: this.launchWorkflowSteps[2].handlers
|
||||
}
|
||||
|
||||
this.launching = true
|
||||
const request = {
|
||||
...api.ADD_REPORT,
|
||||
params: submitData,
|
||||
disableSuccessMsg: true
|
||||
}
|
||||
|
||||
this.$request(request)
|
||||
.asyncThen((resp) => {
|
||||
this.launching = false
|
||||
this.handleLaunchDialogClose()
|
||||
// 重新加载详情
|
||||
this.loadReportDetailFromApi(reportId, this.detail.flowId)
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '发起成功'
|
||||
})
|
||||
// 触发刷新事件
|
||||
this.$emit('refresh')
|
||||
})
|
||||
.asyncErrorCatch((err) => {
|
||||
console.error('发起失败:', err)
|
||||
this.launching = false
|
||||
this.$message.error('发起失败,请重试')
|
||||
})
|
||||
},
|
||||
// 发起远程搜索人员
|
||||
handleLaunchRemoteSearch(query, stepIndex) {
|
||||
const step = this.launchWorkflowSteps[stepIndex]
|
||||
if (!query || query.trim() === '') {
|
||||
if (step.handlers && step.handlers.length > 0) {
|
||||
const selectedOptions = step.options.filter((opt) => step.handlers.includes(opt.userId))
|
||||
step.options = selectedOptions
|
||||
} else {
|
||||
step.options = []
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
step.loading = true
|
||||
const trimmedQuery = query.trim()
|
||||
const request = {
|
||||
...api.GET_ALLUSERS,
|
||||
params: {
|
||||
name: trimmedQuery
|
||||
},
|
||||
disableSuccessMsg: true
|
||||
}
|
||||
|
||||
this.$request(request)
|
||||
.asyncThen((resp) => {
|
||||
const respData = resp && resp.data
|
||||
let result = []
|
||||
if (Array.isArray(respData)) {
|
||||
result = respData
|
||||
} else if (respData && Array.isArray(respData.result)) {
|
||||
result = respData.result
|
||||
} else if (respData && respData.data && Array.isArray(respData.data)) {
|
||||
result = respData.data
|
||||
}
|
||||
const users = result
|
||||
.map((user) => ({
|
||||
userId: user.userId || user.id,
|
||||
username: user.username || user.name,
|
||||
userNumber: user.userNumber || user.userId || user.id
|
||||
}))
|
||||
.filter((user) => user.userId && user.userNumber)
|
||||
const existingIds = new Set(step.handlers || [])
|
||||
const filteredUsers = users.filter((user) => !existingIds.has(user.userId))
|
||||
const selectedOptions = (step.options || []).filter(
|
||||
(opt) => opt.userId && step.handlers && step.handlers.includes(opt.userId)
|
||||
)
|
||||
const optionsMap = new Map()
|
||||
selectedOptions.forEach((opt) => {
|
||||
if (opt.userNumber) {
|
||||
optionsMap.set(opt.userNumber, opt)
|
||||
}
|
||||
})
|
||||
filteredUsers.forEach((user) => {
|
||||
if (user.userNumber && !optionsMap.has(user.userNumber)) {
|
||||
optionsMap.set(user.userNumber, user)
|
||||
}
|
||||
})
|
||||
step.options = Array.from(optionsMap.values())
|
||||
step.loading = false
|
||||
})
|
||||
.asyncErrorCatch((err) => {
|
||||
console.error('搜索人员失败:', err)
|
||||
if (step.handlers && step.handlers.length > 0) {
|
||||
const selectedOptions = step.options.filter((opt) => step.handlers.includes(opt.userId))
|
||||
step.options = selectedOptions
|
||||
} else {
|
||||
step.options = []
|
||||
}
|
||||
step.loading = false
|
||||
})
|
||||
},
|
||||
handleLaunchHandlerChange(stepIndex, selectedIds) {
|
||||
// 处理人员选择变化
|
||||
},
|
||||
// 修改功能:进入编辑模式
|
||||
handleEdit() {
|
||||
// 保存原始数据
|
||||
this.originalReportDetail = JSON.parse(JSON.stringify(this.reportDetail))
|
||||
// 填充表单数据
|
||||
this.editFormData = {
|
||||
title: this.reportDetail.title || '',
|
||||
manufacturerName: this.reportDetail.manufacturerName || '',
|
||||
modelName: this.reportDetail.modelName || '',
|
||||
manufacturerAbbreviation: this.reportDetail.manufacturerAbbreviation || '',
|
||||
modelAbbreviation: this.reportDetail.modelAbbreviation || '',
|
||||
productNumber: this.reportDetail.productNumber || '',
|
||||
module: this.reportDetail.module || '',
|
||||
plate: this.reportDetail.plate || '',
|
||||
platform: this.reportDetail.platform || '',
|
||||
series: this.reportDetail.series || '',
|
||||
marketSegment: this.reportDetail.marketSegment || '',
|
||||
projectName: this.reportDetail.projectName || '',
|
||||
projectNumber: this.reportDetail.projectNumber || '',
|
||||
explanation: this.reportDetail.explanation || '',
|
||||
fileUrl: this.reportDetail.fileUrl || this.reportDetail.filePath || '',
|
||||
fileName: this.reportDetail.fileName || ''
|
||||
}
|
||||
// 如果有文件路径,显示在文件列表中
|
||||
if (this.reportDetail.fileUrl || this.reportDetail.filePath) {
|
||||
this.fileList = [
|
||||
{
|
||||
name: this.reportDetail.fileName || '文件',
|
||||
url: this.reportDetail.fileUrl || this.reportDetail.filePath
|
||||
}
|
||||
]
|
||||
} else {
|
||||
this.fileList = []
|
||||
}
|
||||
this.selectedFile = null
|
||||
this.isEditMode = true
|
||||
},
|
||||
// 取消编辑:恢复只读状态
|
||||
handleCancelEdit() {
|
||||
// 恢复原始数据
|
||||
this.reportDetail = JSON.parse(JSON.stringify(this.originalReportDetail))
|
||||
// 清空表单数据
|
||||
this.editFormData = {
|
||||
title: '',
|
||||
manufacturerName: '',
|
||||
modelName: '',
|
||||
manufacturerAbbreviation: '',
|
||||
modelAbbreviation: '',
|
||||
productNumber: '',
|
||||
module: '',
|
||||
plate: '',
|
||||
platform: '',
|
||||
series: '',
|
||||
marketSegment: '',
|
||||
projectName: '',
|
||||
projectNumber: '',
|
||||
explanation: '',
|
||||
fileUrl: '',
|
||||
fileName: ''
|
||||
}
|
||||
this.fileList = []
|
||||
this.selectedFile = null
|
||||
this.isEditMode = false
|
||||
// 清除表单验证
|
||||
if (this.$refs.editForm) {
|
||||
this.$refs.editForm.clearValidate()
|
||||
}
|
||||
},
|
||||
// 文件变化
|
||||
handleFileChange(file, fileList) {
|
||||
const allowedTypes = ['.doc', '.pdf', '.xls', '.xlsx', '.ppt', '.pptx']
|
||||
const fileName = file.name.toLowerCase()
|
||||
const isValidType = allowedTypes.some((type) => fileName.endsWith(type))
|
||||
|
||||
if (!isValidType) {
|
||||
this.$message.error('不支持的文件类型,仅支持 .doc .pdf .xls .xlsx .ppt .pptx')
|
||||
this.$refs.upload.handleRemove(file)
|
||||
return false
|
||||
}
|
||||
|
||||
this.selectedFile = file && file.raw ? file.raw : null
|
||||
this.fileList = fileList.slice(-1)
|
||||
},
|
||||
// 文件移除
|
||||
handleFileRemove(file, fileList) {
|
||||
this.selectedFile = null
|
||||
this.fileList = []
|
||||
},
|
||||
// 文件上传
|
||||
handleFileUpload() {
|
||||
if (this.uploading || !this.selectedFile) {
|
||||
if (!this.selectedFile) {
|
||||
return Promise.resolve(null)
|
||||
}
|
||||
return Promise.resolve(null)
|
||||
}
|
||||
|
||||
const file = this.selectedFile
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
formData.append('createBy', getUserId())
|
||||
|
||||
const request = {
|
||||
...api.TEST_FILE_UPLOAD,
|
||||
params: formData,
|
||||
disableSuccessMsg: true
|
||||
}
|
||||
|
||||
this.uploading = true
|
||||
const loadingInstance = this.$loading({
|
||||
lock: true,
|
||||
text: '正在上传文件,请稍候...',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
})
|
||||
return this.$upload(request, null, false)
|
||||
.then((resp) => {
|
||||
console.log('文件上传成功:', resp)
|
||||
loadingInstance.close()
|
||||
let fileUrl = ''
|
||||
if (resp.data && resp) {
|
||||
const url = resp.data
|
||||
fileUrl = url
|
||||
this.editFormData.fileUrl = fileUrl
|
||||
}
|
||||
return fileUrl
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('文件上传失败:', err)
|
||||
loadingInstance.close()
|
||||
this.$message.error('文件上传失败,请重试')
|
||||
throw err
|
||||
})
|
||||
.finally(() => {
|
||||
if (loadingInstance) {
|
||||
loadingInstance.close()
|
||||
}
|
||||
this.uploading = false
|
||||
})
|
||||
},
|
||||
// 保存功能
|
||||
handleSave() {
|
||||
// 表单验证
|
||||
if (this.$refs.editForm) {
|
||||
this.$refs.editForm.validate((valid) => {
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
this.submitEdit()
|
||||
})
|
||||
} else {
|
||||
this.submitEdit()
|
||||
}
|
||||
},
|
||||
// 提交编辑
|
||||
submitEdit() {
|
||||
const submitData = async () => {
|
||||
// 如果有新文件,先上传文件获取文件路径
|
||||
if (this.selectedFile) {
|
||||
try {
|
||||
const fileUrl = await this.handleFileUpload()
|
||||
this.editFormData.fileUrl = fileUrl || ''
|
||||
this.editFormData.fileName = this.selectedFile.name
|
||||
} catch (err) {
|
||||
console.error('文件上传失败:', err)
|
||||
this.$message.error('文件上传失败,请重试')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const reportId = this.reportDetail.reportId || this.reportDetail.id
|
||||
if (!reportId) {
|
||||
this.$message.error('缺少报告ID')
|
||||
return
|
||||
}
|
||||
|
||||
const request = {
|
||||
...api.EDIT_REPORT,
|
||||
params: {
|
||||
reportId: reportId,
|
||||
...this.editFormData,
|
||||
createBy: getUserId(),
|
||||
userId: getUserId()
|
||||
}
|
||||
}
|
||||
|
||||
this.saving = true
|
||||
this.$request(request)
|
||||
.asyncThen((resp) => {
|
||||
this.saving = false
|
||||
this.isEditMode = false
|
||||
// 重新加载详情
|
||||
this.loadReportDetailFromApi(reportId, this.detail.flowId)
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '保存成功'
|
||||
})
|
||||
// 触发刷新事件
|
||||
this.$emit('refresh')
|
||||
})
|
||||
.asyncErrorCatch((err) => {
|
||||
console.error('保存失败:', err)
|
||||
this.saving = false
|
||||
this.$message.error('保存失败,请重试')
|
||||
})
|
||||
}
|
||||
|
||||
submitData()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -906,4 +1584,141 @@ export default {
|
||||
left: 7px;
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
.dialog-body-wrapper {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.approval-process-title {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.description-label {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.required-mark {
|
||||
color: #f56c6c;
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.approval-workflow {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
margin-top: 20px;
|
||||
|
||||
.workflow-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.workflow-table {
|
||||
width: 100%;
|
||||
|
||||
.workflow-table-content {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #ebeef5;
|
||||
|
||||
thead {
|
||||
background: #f5f7fa;
|
||||
|
||||
th {
|
||||
padding: 12px 16px;
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
|
||||
&.step-name-col {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
&.handler-col {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
.workflow-row {
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.step-name-cell {
|
||||
padding: 12px 16px;
|
||||
vertical-align: middle;
|
||||
|
||||
.step-name {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
|
||||
.required-mark {
|
||||
color: #f56c6c;
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.handler-cell {
|
||||
padding: 12px 16px;
|
||||
vertical-align: middle;
|
||||
|
||||
.handler-select {
|
||||
width: 100%;
|
||||
min-width: 200px;
|
||||
|
||||
::v-deep .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep .el-tag {
|
||||
margin: 2px 4px 2px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-select-dropdown__item {
|
||||
display: flex !important;
|
||||
justify-content: space-between !important;
|
||||
padding-right: 20px !important;
|
||||
}
|
||||
|
||||
.username-text {
|
||||
color: #303133 !important;
|
||||
display: inline-block;
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
.user-id-text {
|
||||
color: #909399 !important;
|
||||
display: inline-block;
|
||||
margin-left: 20px;
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
::v-deep .el-upload-dragger {
|
||||
width: 100%;
|
||||
height: 180px;
|
||||
}
|
||||
|
||||
::v-deep .el-form-item {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user