refactor(process-config): 重构过程配置弹窗为手写 el-dialog
- 将 process-config 弹窗由 Avue 内置弹窗改为手写 el-dialog 对齐 customer-archive 风格 - 移除 avue-crud 原有的弹窗相关生命周期和插槽方法 - 新增 openProcessConfig、submitProcessConfig、resetProcess 等方法管理弹窗状态和数据提交 - 更新模板结构,新增具备基本信息、过程节点、节点设置的表单布局和底部操作按钮 - 关闭原 avue-crud 弹窗的内置按钮,改由手写对话框控制操作 - 优化样式,增加弹窗内部滚动,保持 footer 固定 - 微调业务组件样式,调整边框和表单布局宽度以适配新弹窗设计
This commit is contained in:
@@ -177,6 +177,10 @@ export const option = {
|
||||
]),
|
||||
saveBtn: false,
|
||||
updateBtn: false,
|
||||
addBtn: false,
|
||||
viewBtn: false,
|
||||
editBtn: false,
|
||||
delBtn: false,
|
||||
dialogTop: '10px',
|
||||
dialogWidth: '96%',
|
||||
menuWidth: 220,
|
||||
|
||||
@@ -113,7 +113,7 @@ export const option = {
|
||||
value: 'projectName',
|
||||
},
|
||||
filterable: true,
|
||||
span: 12,
|
||||
span: 8,
|
||||
minWidth: 180,
|
||||
rules: textRule('项目名称', 100, true),
|
||||
},
|
||||
@@ -128,7 +128,7 @@ export const option = {
|
||||
prop: 'projectCode',
|
||||
hide: true,
|
||||
disabled: true,
|
||||
span: 12,
|
||||
span: 8,
|
||||
minWidth: 150,
|
||||
rules: textRule('项目编号', 50),
|
||||
},
|
||||
@@ -137,7 +137,7 @@ export const option = {
|
||||
prop: 'undertakeDeptName',
|
||||
hide: true,
|
||||
disabled: true,
|
||||
span: 12,
|
||||
span: 8,
|
||||
minWidth: 150,
|
||||
rules: textRule('承办部门', 50, true),
|
||||
},
|
||||
@@ -146,7 +146,7 @@ export const option = {
|
||||
prop: 'projectFundLimit',
|
||||
hide: true,
|
||||
disabled: true,
|
||||
span: 12,
|
||||
span: 8,
|
||||
minWidth: 200,
|
||||
rules: [nonNegativeRule('项目资金使用额度')],
|
||||
},
|
||||
@@ -155,7 +155,7 @@ export const option = {
|
||||
prop: 'usedFundLimit',
|
||||
hide: true,
|
||||
disabled: true,
|
||||
span: 12,
|
||||
span: 8,
|
||||
minWidth: 220,
|
||||
value: 0,
|
||||
rules: [nonNegativeRule('已使用项目资金额度')],
|
||||
@@ -165,7 +165,7 @@ export const option = {
|
||||
prop: 'remainingFundLimit',
|
||||
hide: true,
|
||||
disabled: true,
|
||||
span: 12,
|
||||
span: 8,
|
||||
minWidth: 230,
|
||||
value: 0,
|
||||
rules: [nonNegativeRule('剩余项目资金使用额度')],
|
||||
@@ -174,7 +174,7 @@ export const option = {
|
||||
label: '申请临时额度(万元)',
|
||||
prop: 'applyLimit',
|
||||
formslot: true,
|
||||
span: 12,
|
||||
span: 8,
|
||||
minWidth: 180,
|
||||
rules: [
|
||||
{ required: true, message: '请输入申请临时额度', trigger: 'blur' },
|
||||
@@ -187,7 +187,7 @@ export const option = {
|
||||
type: 'date',
|
||||
format: 'YYYY-MM-DD',
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
span: 12,
|
||||
span: 8,
|
||||
minWidth: 140,
|
||||
rules: [{ required: true, message: '请选择申请有效期至', trigger: 'change' }],
|
||||
},
|
||||
|
||||
@@ -13681,7 +13681,7 @@ export default {
|
||||
min-width: 56px;
|
||||
height: 22px;
|
||||
margin: 0 14px;
|
||||
border-bottom: 3px solid #303133;
|
||||
border-bottom: 4px solid #e4e7ed;
|
||||
}
|
||||
|
||||
&__transport-plan-waybill-card {
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
v-model="form"
|
||||
ref="crud"
|
||||
:permission="permissionList"
|
||||
:before-open="beforeOpen"
|
||||
@row-save="rowSave"
|
||||
@row-update="rowUpdate"
|
||||
@row-del="rowDel"
|
||||
@search-change="searchChange"
|
||||
@search-reset="searchReset"
|
||||
@selection-change="selectionChange"
|
||||
@@ -25,7 +21,7 @@
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
v-if="hasPermission('process_config_add')"
|
||||
@click="$refs.crud.rowAdd()"
|
||||
@click="openProcessConfig()"
|
||||
>新建过程配置
|
||||
</el-button>
|
||||
<el-button
|
||||
@@ -46,27 +42,6 @@
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template #menu-form-before="{ disabled }">
|
||||
<template v-if="!dialogReadonly">
|
||||
<el-button
|
||||
plain
|
||||
:loading="disabled"
|
||||
:disabled="disabled"
|
||||
@click="handleProcessConfigSave('draft')"
|
||||
>
|
||||
保存草稿
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="disabled"
|
||||
:disabled="disabled"
|
||||
@click="handleProcessConfigSave('enabled')"
|
||||
>
|
||||
保存并启用
|
||||
</el-button>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template #status="{ row }">
|
||||
<el-tag :type="statusTagType(row.status)">
|
||||
{{ row.statusName || displayStatus(row.status) }}
|
||||
@@ -79,101 +54,154 @@
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #basicInfo-form>
|
||||
<section-card title="基本信息">
|
||||
<el-form
|
||||
:model="form"
|
||||
label-position="right"
|
||||
label-width="calc(6em + 24px)"
|
||||
>
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="配置名称" required>
|
||||
<el-input
|
||||
v-model="form.configName"
|
||||
:disabled="dialogReadonly"
|
||||
maxlength="100"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="项目" required>
|
||||
<el-select
|
||||
v-model="selectedProjectId"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
:remote-method="loadProjectOptions"
|
||||
:loading="projectLoading"
|
||||
:disabled="dialogReadonly"
|
||||
placeholder="请选择"
|
||||
style="width: 100%"
|
||||
@change="handleProjectChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in projectOptions"
|
||||
:key="item.id"
|
||||
:label="formatProjectLabel(item)"
|
||||
:value="String(item.id)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="运输完成时限">
|
||||
<div class="process-config-page__finish-days">
|
||||
<span>默认</span>
|
||||
<el-input
|
||||
v-model="form.defaultFinishDays"
|
||||
:disabled="dialogReadonly"
|
||||
maxlength="3"
|
||||
placeholder="请输入"
|
||||
@input="handleFinishDaysInput"
|
||||
/>
|
||||
<span>天后完成运输</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="form.remark"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
:disabled="dialogReadonly"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</section-card>
|
||||
<template #menu="{ row, index }">
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="hasPermission('process_config_view')"
|
||||
@click="openProcessConfig(row, true)"
|
||||
>
|
||||
查看
|
||||
</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="canEdit(row)"
|
||||
@click="openProcessConfig(row, false)"
|
||||
>
|
||||
编辑
|
||||
</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="hasPermission('process_config_copy')"
|
||||
@click="handleCopy(row)"
|
||||
>
|
||||
复制
|
||||
</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="canEnable(row)"
|
||||
@click="handleAction('enable', row)"
|
||||
>
|
||||
启用
|
||||
</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="canDisable(row)"
|
||||
@click="handleAction('disable', row)"
|
||||
>
|
||||
停用
|
||||
</el-link>
|
||||
<el-link
|
||||
type="danger"
|
||||
v-if="canDelete(row)"
|
||||
@click="rowDel(row)"
|
||||
>
|
||||
删除
|
||||
</el-link>
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<template #nodeConfigJson-form>
|
||||
<div class="process-config-page__custom-form">
|
||||
<section-card title="现行过程节点">
|
||||
<div class="process-config-page__timeline" v-if="enabledNodes.length">
|
||||
<div class="process-config-page__timeline-line"></div>
|
||||
<div
|
||||
v-for="node in enabledNodes"
|
||||
:key="node.key"
|
||||
class="process-config-page__timeline-item"
|
||||
>
|
||||
<span class="process-config-page__timeline-dot"></span>
|
||||
<div class="process-config-page__timeline-name">{{ node.name }}</div>
|
||||
<div class="process-config-page__timeline-desc">
|
||||
<div v-for="text in timelineDescriptions(node)" :key="text">{{ text }}</div>
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
append-to-body
|
||||
v-model="processBox"
|
||||
width="92%"
|
||||
top="4vh"
|
||||
class="process-dialog"
|
||||
@closed="resetProcess"
|
||||
>
|
||||
<el-form
|
||||
ref="processForm"
|
||||
:model="form"
|
||||
label-position="right"
|
||||
label-width="calc(6em + 24px)"
|
||||
:disabled="dialogReadonly"
|
||||
class="process-form dialog-form-label-fixed"
|
||||
>
|
||||
<section-card title="基本信息">
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="配置名称" required>
|
||||
<el-input
|
||||
v-model="form.configName"
|
||||
:disabled="dialogReadonly"
|
||||
maxlength="100"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="项目" required>
|
||||
<el-select
|
||||
v-model="selectedProjectId"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
:remote-method="loadProjectOptions"
|
||||
:loading="projectLoading"
|
||||
:disabled="dialogReadonly"
|
||||
placeholder="请选择"
|
||||
style="width: 100%"
|
||||
@change="handleProjectChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in projectOptions"
|
||||
:key="item.id"
|
||||
:label="formatProjectLabel(item)"
|
||||
:value="String(item.id)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="运输完成时限">
|
||||
<div class="process-config-page__finish-days">
|
||||
<span>默认</span>
|
||||
<el-input
|
||||
v-model="form.defaultFinishDays"
|
||||
:disabled="dialogReadonly"
|
||||
maxlength="3"
|
||||
placeholder="请输入"
|
||||
@input="handleFinishDaysInput"
|
||||
/>
|
||||
<span>天后完成运输</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="form.remark"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
:disabled="dialogReadonly"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</section-card>
|
||||
|
||||
<section-card title="现行过程节点">
|
||||
<div class="process-config-page__timeline" v-if="enabledNodes.length">
|
||||
<div class="process-config-page__timeline-line"></div>
|
||||
<div
|
||||
v-for="node in enabledNodes"
|
||||
:key="node.key"
|
||||
class="process-config-page__timeline-item"
|
||||
>
|
||||
<span class="process-config-page__timeline-dot"></span>
|
||||
<div class="process-config-page__timeline-name">{{ node.name }}</div>
|
||||
<div class="process-config-page__timeline-desc">
|
||||
<div v-for="text in timelineDescriptions(node)" :key="text">{{ text }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-empty v-else description="请在节点设置中勾选过程节点" :image-size="72" />
|
||||
</section-card>
|
||||
</div>
|
||||
<el-empty v-else description="请在节点设置中勾选过程节点" :image-size="72" />
|
||||
</section-card>
|
||||
|
||||
<section-card title="节点设置">
|
||||
<section-card title="节点设置">
|
||||
<el-table
|
||||
class="process-config-page__node-table"
|
||||
border
|
||||
@@ -357,55 +385,21 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</section-card>
|
||||
</div>
|
||||
</template>
|
||||
</section-card>
|
||||
</el-form>
|
||||
|
||||
<template #menu="{ row, index }">
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="hasPermission('process_config_view')"
|
||||
@click="$refs.crud.rowView(row, index)"
|
||||
>
|
||||
查看
|
||||
</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="canEdit(row)"
|
||||
@click="$refs.crud.rowEdit(row, index)"
|
||||
>
|
||||
编辑
|
||||
</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="hasPermission('process_config_copy')"
|
||||
@click="handleCopy(row)"
|
||||
>
|
||||
复制
|
||||
</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="canEnable(row)"
|
||||
@click="handleAction('enable', row)"
|
||||
>
|
||||
启用
|
||||
</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="canDisable(row)"
|
||||
@click="handleAction('disable', row)"
|
||||
>
|
||||
停用
|
||||
</el-link>
|
||||
<el-link
|
||||
type="danger"
|
||||
v-if="canDelete(row)"
|
||||
@click="rowDel(row)"
|
||||
>
|
||||
删除
|
||||
</el-link>
|
||||
<template #footer>
|
||||
<template v-if="!dialogReadonly">
|
||||
<el-button plain :loading="submitting" :disabled="submitting" @click="submitProcessConfig('draft')">
|
||||
保存草稿
|
||||
</el-button>
|
||||
<el-button type="primary" :loading="submitting" :disabled="submitting" @click="submitProcessConfig('enabled')">
|
||||
保存并启用
|
||||
</el-button>
|
||||
</template>
|
||||
<el-button @click="processBox = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
|
||||
</template>
|
||||
</avue-crud>
|
||||
</el-dialog>
|
||||
|
||||
<empty-pagination
|
||||
:page="page"
|
||||
@@ -519,6 +513,8 @@ export default {
|
||||
},
|
||||
selectionList: [],
|
||||
submitStatus: 1,
|
||||
processBox: false,
|
||||
submitting: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -540,6 +536,10 @@ export default {
|
||||
enabledNodes() {
|
||||
return this.nodeRows.filter(item => item.enabled);
|
||||
},
|
||||
dialogTitle() {
|
||||
if (this.dialogReadonly) return '查看过程配置';
|
||||
return this.form.id ? '编辑过程配置' : '新增过程配置';
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.resetNodeRows();
|
||||
@@ -853,11 +853,6 @@ export default {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
stopSubmitLoading(loading) {
|
||||
if (typeof loading === 'function') {
|
||||
loading();
|
||||
}
|
||||
},
|
||||
needsDuplicateVoucherConfirm() {
|
||||
const signNode = this.nodeRows.find(item => item.key === 'sign');
|
||||
const returnNode = this.nodeRows.find(item => item.key === 'return');
|
||||
@@ -887,39 +882,74 @@ export default {
|
||||
}
|
||||
);
|
||||
},
|
||||
submitRow(row, done, loading, status = this.submitStatus) {
|
||||
openProcessConfig(row, readonly = false) {
|
||||
this.dialogReadonly = readonly;
|
||||
this.submitStatus = 1;
|
||||
this.syncNodeFields();
|
||||
const submitRow = this.normalizeRow({ ...row, status });
|
||||
if (!this.validateRow(submitRow)) {
|
||||
this.stopSubmitLoading(loading);
|
||||
if (row && row.id) {
|
||||
api.getDetail(row.id).then(res => {
|
||||
const data = res.data.data || {};
|
||||
this.form = data;
|
||||
this.selectedProjectId = data.projectIds ? String(data.projectIds) : '';
|
||||
this.ensureSelectedProjectOption();
|
||||
this.parseNodeConfig(data);
|
||||
this.processBox = true;
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.confirmDuplicateVoucher()
|
||||
.then(() => api.submit(submitRow))
|
||||
.then(() => {
|
||||
this.onLoad(this.page);
|
||||
this.$message({ type: 'success', message: '操作成功!' });
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
if (error !== 'cancel' && error !== 'close') {
|
||||
window.console.log(error);
|
||||
}
|
||||
this.stopSubmitLoading(loading);
|
||||
});
|
||||
this.form = {
|
||||
configName: '',
|
||||
projectIds: '',
|
||||
projectNames: '',
|
||||
defaultFinishDays: '',
|
||||
remark: '',
|
||||
status: 0,
|
||||
};
|
||||
this.selectedProjectId = '';
|
||||
this.resetNodeRows();
|
||||
this.processBox = true;
|
||||
},
|
||||
rowSave(row, done, loading) {
|
||||
this.submitRow(row, done, loading);
|
||||
submitProcessConfig(mode) {
|
||||
this.$refs.processForm.validate(valid => {
|
||||
if (!valid) return;
|
||||
this.submitting = true;
|
||||
this.submitStatus = mode === 'draft' ? 2 : 1;
|
||||
this.syncNodeFields();
|
||||
const submitRow = this.normalizeRow({ ...this.form, status: this.submitStatus });
|
||||
if (!this.validateRow(submitRow)) {
|
||||
this.submitting = false;
|
||||
return;
|
||||
}
|
||||
this.confirmDuplicateVoucher()
|
||||
.then(() => api.submit(submitRow))
|
||||
.then(() => {
|
||||
this.submitting = false;
|
||||
this.processBox = false;
|
||||
this.onLoad(this.page);
|
||||
this.$message({ type: 'success', message: '操作成功!' });
|
||||
})
|
||||
.catch(error => {
|
||||
this.submitting = false;
|
||||
if (error !== 'cancel' && error !== 'close') {
|
||||
window.console.log(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
rowUpdate(row, index, done, loading) {
|
||||
this.submitRow(row, done, loading);
|
||||
},
|
||||
handleProcessConfigSave(mode) {
|
||||
this.submitStatus = mode === 'draft' ? 2 : 1;
|
||||
if (this.$refs.crud && typeof this.$refs.crud.rowSave === 'function') {
|
||||
this.$refs.crud.rowSave();
|
||||
}
|
||||
resetProcess() {
|
||||
this.dialogReadonly = false;
|
||||
this.submitting = false;
|
||||
this.submitStatus = 1;
|
||||
this.form = {
|
||||
configName: '',
|
||||
projectIds: '',
|
||||
projectNames: '',
|
||||
defaultFinishDays: '',
|
||||
remark: '',
|
||||
status: 0,
|
||||
};
|
||||
this.selectedProjectId = '';
|
||||
this.resetNodeRows();
|
||||
this.$refs.processForm?.clearValidate();
|
||||
},
|
||||
rowDel(row) {
|
||||
this.$confirm('确定将选择数据删除?', {
|
||||
@@ -963,35 +993,6 @@ export default {
|
||||
}
|
||||
this.selectionClear();
|
||||
},
|
||||
beforeOpen(done, type) {
|
||||
this.dialogReadonly = type === 'view';
|
||||
this.submitStatus = 1;
|
||||
if (type === 'add') {
|
||||
this.form = {
|
||||
configName: '',
|
||||
projectIds: '',
|
||||
projectNames: '',
|
||||
defaultFinishDays: '',
|
||||
remark: '',
|
||||
status: 0,
|
||||
};
|
||||
this.selectedProjectId = '';
|
||||
this.resetNodeRows();
|
||||
done();
|
||||
return;
|
||||
}
|
||||
if (['edit', 'view'].includes(type)) {
|
||||
api.getDetail(this.form.id).then(res => {
|
||||
this.form = res.data.data || {};
|
||||
this.selectedProjectId = this.form.projectIds ? String(this.form.projectIds) : '';
|
||||
this.ensureSelectedProjectOption();
|
||||
this.parseNodeConfig(this.form);
|
||||
done();
|
||||
});
|
||||
return;
|
||||
}
|
||||
done();
|
||||
},
|
||||
searchReset() {
|
||||
this.query = {};
|
||||
this.applyDefaultDeptSearch();
|
||||
@@ -1239,5 +1240,10 @@ export default {
|
||||
:deep(.el-table__body tr:nth-child(even) > td.el-table__cell) {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
:deep(.process-dialog .el-dialog__body) {
|
||||
max-height: 72vh;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user