diff --git a/src/utils/mk-approval.js b/src/utils/mk-approval.js
index 3562545..60ee800 100644
--- a/src/utils/mk-approval.js
+++ b/src/utils/mk-approval.js
@@ -89,13 +89,22 @@ export async function resolveMkTemplateCode(dictName, list) {
return String(templateCode);
}
+/**
+ * 是否属于「审核通过后再提交」需要新建表单实例的状态
+ */
+export function isMkApprovedStatus(bizType, approvalStatus) {
+ const conf = MK_BIZ[bizType];
+ if (!conf) return false;
+ return (conf.approved || []).includes(approvalStatus);
+}
+
/**
* 提交 MK 审核流
* @param {Object} options
* @param {string} options.bizType 业务类型
* @param {string|number} options.bizId 业务主键(后端据此生成/复用 formInstanceId)
* @param {string} [options.subjectName] 标题后缀
- * @param {string} [options.approvalStatus] 当前审批状态(驳回态会先 delete;通过态强制新建实例)
+ * @param {string} [options.approvalStatus] 提交前的审批状态(须在业务 submit 改状态前取值;通过态强制新建实例)
*/
export async function submitMkApprovalFlow({
bizType,
@@ -115,7 +124,7 @@ export async function submitMkApprovalFlow({
return;
}
const bizIdText = String(bizId);
- const forceNewFormInstance = (conf.approved || []).includes(approvalStatus);
+ const forceNewFormInstance = isMkApprovedStatus(bizType, approvalStatus);
// 审核通过后再提交必须新建流程;其余场景已有有效实例则跳过
if (!forceNewFormInstance) {
const existsRes = await hasMkProcessInstance({ bizId: bizIdText });
diff --git a/src/views/business/contract-manage.vue b/src/views/business/contract-manage.vue
index 3c2fd7b..c57b980 100644
--- a/src/views/business/contract-manage.vue
+++ b/src/views/business/contract-manage.vue
@@ -1872,6 +1872,7 @@ export default {
submitCreate(action) {
if (this.submitAction || !this.validateBase(action)) return;
this.submitAction = action;
+ const previousApprovalStatus = this.form.approvalStatus || '';
const submit = {
...this.normalizeSubmit(),
contractStage: action === 'formal' ? 'temporary' : 'draft',
@@ -1892,7 +1893,7 @@ export default {
bizType: 'contract-manage',
bizId: id,
subjectName: saved.contractName || submit.contractName || '',
- approvalStatus: saved.approvalStatus || submit.approvalStatus || '',
+ approvalStatus: previousApprovalStatus || saved.approvalStatus || submit.approvalStatus || '',
})
);
}
diff --git a/src/views/business/project-apply.vue b/src/views/business/project-apply.vue
index ee1b8bd..6062b93 100644
--- a/src/views/business/project-apply.vue
+++ b/src/views/business/project-apply.vue
@@ -1907,7 +1907,8 @@ export default {
const data = res.data?.data || {};
const id = data.id || this.form.id;
const name = data.projectName || this.form.projectName || '';
- const status = data.approvalStatus || this.form.approvalStatus || '';
+ // 必须用提交前状态:业务 submit 后可能已变成 reviewing,导致无法识别「通过后再提交」
+ const status = this.form.approvalStatus || data.approvalStatus || '';
if (!id) {
this.$message.success('操作成功!');
this.closeProjectForm();
diff --git a/src/views/payment/bill-payment-form.vue b/src/views/payment/bill-payment-form.vue
index 745fc2e..d16b681 100644
--- a/src/views/payment/bill-payment-form.vue
+++ b/src/views/payment/bill-payment-form.vue
@@ -341,12 +341,13 @@ export default {
try {
const id = this.unwrapData(await api.save(this.payload()));
this.form.id = id;
+ const previousApprovalStatus = this.form.approvalStatus || '';
await api.submit({ id: this.form.id });
await submitMkApprovalFlow({
bizType: 'bill-payment',
bizId: this.form.id,
subjectName: this.form.paymentNo || this.form.billNo || '',
- approvalStatus: this.form.approvalStatus || '',
+ approvalStatus: previousApprovalStatus,
});
this.$message.success('提交成功');
this.goBack();
diff --git a/src/views/payment/bill-payment.vue b/src/views/payment/bill-payment.vue
index e1d1e40..1f63ccb 100644
--- a/src/views/payment/bill-payment.vue
+++ b/src/views/payment/bill-payment.vue
@@ -121,12 +121,13 @@ export default {
this.loadTable();
},
async handleSubmit(row) {
+ const previousApprovalStatus = row.approvalStatus || '';
await api.submit({ id: row.id });
await submitMkApprovalFlow({
bizType: 'bill-payment',
bizId: row.id,
subjectName: row.paymentNo || row.billNo || '',
- approvalStatus: row.approvalStatus || '',
+ approvalStatus: previousApprovalStatus,
});
this.$message.success('提交成功');
this.loadTable();
diff --git a/src/views/payment/invoice-application-form.vue b/src/views/payment/invoice-application-form.vue
index a968b04..ee2bf75 100644
--- a/src/views/payment/invoice-application-form.vue
+++ b/src/views/payment/invoice-application-form.vue
@@ -1194,12 +1194,13 @@ export default {
}
const saved = await this.saveDraft();
if (!saved) return;
+ const previousApprovalStatus = this.form.approvalStatus || '';
await api.submit({ id: this.form.id });
await submitMkApprovalFlow({
bizType: 'invoice-application',
bizId: this.form.id,
subjectName: this.form.applicationNo || '',
- approvalStatus: this.form.approvalStatus || '',
+ approvalStatus: previousApprovalStatus,
});
this.$message.success('提交成功');
this.goBack();
diff --git a/src/views/payment/invoice-application.vue b/src/views/payment/invoice-application.vue
index a52a064..6d69539 100644
--- a/src/views/payment/invoice-application.vue
+++ b/src/views/payment/invoice-application.vue
@@ -344,12 +344,13 @@ export default {
this.loadTable();
},
async handleSubmit(row) {
+ const previousApprovalStatus = row.approvalStatus || '';
await api.submit({ id: row.id });
await submitMkApprovalFlow({
bizType: 'invoice-application',
bizId: row.id,
subjectName: row.applicationNo || '',
- approvalStatus: row.approvalStatus || '',
+ approvalStatus: previousApprovalStatus,
});
this.$message.success('提交成功');
this.loadTable();
diff --git a/src/views/payment/invoice-receipt-form.vue b/src/views/payment/invoice-receipt-form.vue
index 57cbbe7..97556b4 100644
--- a/src/views/payment/invoice-receipt-form.vue
+++ b/src/views/payment/invoice-receipt-form.vue
@@ -766,12 +766,13 @@ export default {
async submitForm() {
const saved = await this.saveDraft();
if (!saved) return;
+ const previousApprovalStatus = this.form.approvalStatus || '';
await api.submit({ id: this.form.id });
await submitMkApprovalFlow({
bizType: 'invoice-receipt',
bizId: this.form.id,
subjectName: this.form.invoiceNo || '',
- approvalStatus: this.form.approvalStatus || '',
+ approvalStatus: previousApprovalStatus,
});
this.$message.success('提交成功');
this.goBack();
diff --git a/src/views/payment/invoice-receipt.vue b/src/views/payment/invoice-receipt.vue
index da8b05a..462d04f 100644
--- a/src/views/payment/invoice-receipt.vue
+++ b/src/views/payment/invoice-receipt.vue
@@ -309,12 +309,13 @@ export default {
this.loadTable();
},
async handleSubmit(row) {
+ const previousApprovalStatus = row.approvalStatus || '';
await api.submit({ id: row.id });
await submitMkApprovalFlow({
bizType: 'invoice-receipt',
bizId: row.id,
subjectName: row.invoiceNo || '',
- approvalStatus: row.approvalStatus || '',
+ approvalStatus: previousApprovalStatus,
});
this.$message.success('提交成功');
this.loadTable();
diff --git a/src/views/payment/payment-application-form.vue b/src/views/payment/payment-application-form.vue
index 9e7e278..851b550 100644
--- a/src/views/payment/payment-application-form.vue
+++ b/src/views/payment/payment-application-form.vue
@@ -2632,12 +2632,13 @@ export default {
// 提交前静默保存,避免同时弹出「保存成功」与材料缺失 toast
const saved = await this.saveDraft({ showSuccess: false });
if (!saved) return;
+ const previousApprovalStatus = this.form.approvalStatus || '';
await api.submit({ id: this.form.id });
await submitMkApprovalFlow({
bizType: 'payment-application',
bizId: this.form.id,
subjectName: this.form.paymentNo || '',
- approvalStatus: this.form.approvalStatus || '',
+ approvalStatus: previousApprovalStatus,
});
this.$message.success('提交成功');
this.goBack();
diff --git a/src/views/payment/payment-application.vue b/src/views/payment/payment-application.vue
index 1d4042e..597ad6f 100644
--- a/src/views/payment/payment-application.vue
+++ b/src/views/payment/payment-application.vue
@@ -364,12 +364,13 @@ export default {
this.loadTable();
},
async handleSubmit(row) {
+ const previousApprovalStatus = row.approvalStatus || '';
await api.submit({ id: row.id });
await submitMkApprovalFlow({
bizType: 'payment-application',
bizId: row.id,
subjectName: row.paymentNo || '',
- approvalStatus: row.approvalStatus || '',
+ approvalStatus: previousApprovalStatus,
});
this.$message.success('提交成功');
this.loadTable();
diff --git a/src/views/settlement/components/pre-settlement-editor.vue b/src/views/settlement/components/pre-settlement-editor.vue
index 1c5f134..dfba02c 100644
--- a/src/views/settlement/components/pre-settlement-editor.vue
+++ b/src/views/settlement/components/pre-settlement-editor.vue
@@ -1601,12 +1601,13 @@ export default {
await this.loadDetail();
await this.persistPendingAdjustments();
if (shouldSubmit) {
+ const previousApprovalStatus = this.form.approvalStatus || '';
await submit({ id: this.form.id });
await submitMkApprovalFlow({
bizType: 'pre-settlement',
bizId: this.form.id,
subjectName: this.form.preSettlementNo || this.form.contractName || '',
- approvalStatus: this.form.approvalStatus || '',
+ approvalStatus: previousApprovalStatus,
});
this.$message.success('审批流程已发起');
this.visible = false;
diff --git a/src/views/settlement/formal-settlement.vue b/src/views/settlement/formal-settlement.vue
index a5aca35..86a8ac7 100644
--- a/src/views/settlement/formal-settlement.vue
+++ b/src/views/settlement/formal-settlement.vue
@@ -349,12 +349,13 @@ export default {
},
async handleSubmit(row) {
await this.$confirm('提交后来源预结算将保持锁定,确认提交?', '提示', { type: 'warning' });
+ const previousApprovalStatus = row.approvalStatus || '';
await api.submit({ id: row.id });
await submitMkApprovalFlow({
bizType: 'formal-settlement',
bizId: row.id,
subjectName: row.formalSettlementNo || '',
- approvalStatus: row.approvalStatus || '',
+ approvalStatus: previousApprovalStatus,
});
this.$message.success('提交成功');
this.loadTable();
diff --git a/src/views/settlement/pre-settlement.vue b/src/views/settlement/pre-settlement.vue
index 2a7e1b6..5a0d123 100644
--- a/src/views/settlement/pre-settlement.vue
+++ b/src/views/settlement/pre-settlement.vue
@@ -641,12 +641,13 @@ export default {
downloadFile(data, `预结算单${this.$dayjs().format('YYYY-MM-DD HH-mm-ss')}.xlsx`);
},
async handleSubmit(row) {
+ const previousApprovalStatus = row.approvalStatus || '';
await submit({ id: row.id });
await submitMkApprovalFlow({
bizType: 'pre-settlement',
bizId: row.id,
subjectName: row.preSettlementNo || '',
- approvalStatus: row.approvalStatus || '',
+ approvalStatus: previousApprovalStatus,
});
this.$message.success('提交成功');
this.loadTable();
diff --git a/src/views/system/dept.vue b/src/views/system/dept.vue
index 565ad53..f6a4f72 100644
--- a/src/views/system/dept.vue
+++ b/src/views/system/dept.vue
@@ -48,7 +48,7 @@
- {{ getDeptCategoryLabel(row.deptCategory) }}
+ {{ row.deptCategoryName || getDeptCategoryLabel(row.deptCategory) }}
@@ -181,18 +181,21 @@ import {
clearNonTopDept,
} from '@/api/system/dept';
import { getLeaderList } from '@/api/system/user';
+import { getDictionary } from '@/api/system/dictbiz';
import { getList as getCustomerArchiveList } from '@/api/vehicle/customer-archive';
import { mapGetters } from 'vuex';
import website from '@/config/website';
import func from '@/utils/func';
const escapeRegExp = value => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+const ORGANIZATION_TYPE_DICT_CODE = 'organization_type';
export default {
data() {
return {
form: {},
leaderOptions: [],
+ organizationTypeOptions: [],
parentDeptCode: '',
parentDept: null,
carrierDialogVisible: false,
@@ -315,6 +318,31 @@ export default {
},
],
},
+ {
+ label: '金蝶部门代码',
+ prop: 'kingdeeDeptCode',
+ minWidth: 140,
+ order: 65,
+ maxlength: 64,
+ showWordLimit: true,
+ rules: [
+ {
+ validator: (rule, value, callback) => {
+ const code = String(value || '').trim();
+ if (!code) {
+ callback();
+ return;
+ }
+ if (code.length > 64) {
+ callback(new Error('金蝶部门代码不能超过64个字符'));
+ return;
+ }
+ callback();
+ },
+ trigger: 'blur',
+ },
+ ],
+ },
{
label: '组织简称',
prop: 'shortName',
@@ -336,14 +364,7 @@ export default {
{
label: '组织类型',
type: 'select',
- dicData: [
- { label: '一级集团', value: 1 },
- { label: '二级事业部', value: 2 },
- { label: '部门', value: 3 },
- { label: '三级分公司', value: 4 },
- { label: '物流园区', value: 5 },
- { label: '承运商', value: 6 },
- ],
+ dicData: [],
dataType: 'number',
minWidth: 120,
order: 90,
@@ -486,6 +507,7 @@ export default {
// ignore storage errors
}
this.loadLeaderOptions();
+ this.loadOrganizationTypeOptions();
},
computed: {
...mapGetters(['userInfo', 'permission']),
@@ -725,30 +747,52 @@ export default {
});
});
},
+ loadOrganizationTypeOptions() {
+ return getDictionary({ code: ORGANIZATION_TYPE_DICT_CODE }).then(res => {
+ const list = res.data.data || [];
+ this.organizationTypeOptions = list
+ .map(item => ({
+ label: item.dictValue,
+ value: Number(item.dictKey),
+ }))
+ .filter(item => item.label && !Number.isNaN(item.value));
+ this.resetDeptCategoryOptions();
+ // 字典异步返回后触发表格组织类型标签重绘
+ if (Array.isArray(this.data) && this.data.length) {
+ this.data = [...this.data];
+ }
+ });
+ },
+ resetDeptCategoryOptions() {
+ const categoryColumn = this.findColumn(this.option.column, 'deptCategory');
+ if (!categoryColumn) {
+ return;
+ }
+ categoryColumn.dicData = [...this.organizationTypeOptions];
+ },
+ filterOrganizationTypeOptions(values) {
+ const valueSet = new Set(values.map(Number));
+ return this.organizationTypeOptions.filter(item => valueSet.has(Number(item.value)));
+ },
updateDeptCategoryOptions() {
const categoryColumn = this.findColumn(this.option.column, 'deptCategory');
const parent = this.parentDept;
- if (!parent) return;
+ if (!parent || !categoryColumn) {
+ return;
+ }
let dicData = [];
if (this.isRootDept(parent)) {
dicData =
parent.deptName === '外部组织'
- ? [{ label: '承运商', value: 6 }]
- : [{ label: '集团', value: 1 }];
+ ? this.filterOrganizationTypeOptions([6])
+ : this.filterOrganizationTypeOptions([1]);
} else if (Number(parent.deptCategory) === 1) {
- dicData = [
- { label: '事业部', value: 2 },
- { label: '部门', value: 3 },
- ];
+ dicData = this.filterOrganizationTypeOptions([2, 3]);
} else if ([2, 3].includes(Number(parent.deptCategory))) {
- dicData = [
- { label: '分公司', value: 4 },
- { label: '物流园区', value: 5 },
- { label: '承运商', value: 6 },
- ];
+ dicData = this.filterOrganizationTypeOptions([4, 5, 6]);
}
categoryColumn.dicData = dicData;
- if (!dicData.some(item => item.value === Number(this.form.deptCategory))) {
+ if (!dicData.some(item => Number(item.value) === Number(this.form.deptCategory))) {
this.form.deptCategory = dicData[0]?.value;
}
if (Number(this.form.deptCategory) === 6) {
@@ -816,15 +860,13 @@ export default {
});
},
getDeptCategoryLabel(deptCategory) {
- const categoryMap = {
- 1: '集团',
- 2: '事业部',
- 3: '部门',
- 4: '分公司',
- 5: '物流园区',
- 6: '承运商',
- };
- return categoryMap[Number(deptCategory)] || '-';
+ if (deptCategory === null || deptCategory === undefined || deptCategory === '') {
+ return '-';
+ }
+ const matched = this.organizationTypeOptions.find(
+ item => Number(item.value) === Number(deptCategory)
+ );
+ return matched?.label || '-';
},
getLeaderValue(leaderId, field) {
// func.split 空值时返回 '',需兼容为数组,避免表格 formatter 渲染崩溃导致列错位
@@ -861,6 +903,7 @@ export default {
rowSave(row, done, loading) {
row.tenantId = row.tenantId || this.userInfo.tenantId || website.tenantId;
row.deptCode = String(row.deptCode || '').trim();
+ row.kingdeeDeptCode = String(row.kingdeeDeptCode || '').trim();
row.leaderId = func.join(row.leaderId);
this.normalizeTopParent(row);
if (Number(row.deptCategory) === 6 && !row.carrierCustomerId) {
@@ -891,6 +934,7 @@ export default {
rowUpdate(row, index, done, loading) {
row.tenantId = row.tenantId || this.userInfo.tenantId || website.tenantId;
row.deptCode = String(row.deptCode || '').trim();
+ row.kingdeeDeptCode = String(row.kingdeeDeptCode || '').trim();
row.leaderId = func.join(row.leaderId);
this.normalizeTopParent(row);
if (Number(row.deptCategory) === 6 && !row.carrierCustomerId) {
@@ -1026,6 +1070,7 @@ export default {
const column = this.findColumn(this.option.column, 'parentId');
column.value = '';
column.addDisabled = false;
+ this.resetDeptCategoryOptions();
done();
},
currentChange(currentPage) {
diff --git a/src/views/system/user.vue b/src/views/system/user.vue
index 6d400fb..1e9c069 100644
--- a/src/views/system/user.vue
+++ b/src/views/system/user.vue
@@ -178,7 +178,14 @@
{{ row.roleName }}
- {{ row.deptName }}
+
+ {{ name }}
+
+ -
@@ -214,11 +221,25 @@
-
+
+
+
+
+
仅所属组织全部组织自定义
- 包含下级仅本级
+ 包含下级仅本级
@@ -505,7 +526,24 @@ export default {
password: [{ required: true, validator: validateLoginPassword, trigger: 'blur' }],
realName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
phone: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
- deptId: [{ required: true, message: '请选择所属组织', trigger: 'change' }],
+ deptId: [
+ {
+ required: true,
+ validator: (rule, value, callback) => {
+ const ids = Array.isArray(value)
+ ? value.filter(item => item !== undefined && item !== null && item !== '')
+ : value
+ ? String(value).split(',').filter(Boolean)
+ : [];
+ if (!ids.length) {
+ callback(new Error('请选择所属组织'));
+ return;
+ }
+ callback();
+ },
+ trigger: 'change',
+ },
+ ],
},
excelForm: {},
excelOption: excelOption,
@@ -561,31 +599,36 @@ export default {
}
return undefined;
},
- // 所属组织级联配置:checkStrictly 为 true 时任意一级都可选择
+ // 所属组织级联配置:多选,checkStrictly 为 true 时任意一级都可选择
deptCascaderProps() {
return {
label: 'title',
value: 'id',
children: 'children',
emitPath: false,
+ multiple: true,
checkStrictly: true,
expandTrigger: 'click',
- leaf: data => !data.children || data.children.length === 0,
};
},
- // 所属组织为单选级联:form.deptId 为数组(提交时 join),级联返回单个 id 值
+ // 所属组织多选级联:form.deptId 为 id 数组(提交时 join)
deptCascaderValue: {
get() {
const ids = Array.isArray(this.form.deptId)
? this.form.deptId
: this.form.deptId
- ? [this.form.deptId]
+ ? String(this.form.deptId).split(',').filter(Boolean)
: [];
- const id = ids.find(item => item !== undefined && item !== null && item !== '');
- return id === undefined ? '' : id;
+ return ids
+ .filter(item => item !== undefined && item !== null && item !== '')
+ .map(item => (typeof item === 'number' ? item : String(item)));
},
set(value) {
- this.form.deptId = value ? [value] : [];
+ this.form.deptId = Array.isArray(value)
+ ? value.filter(item => item !== undefined && item !== null && item !== '')
+ : value
+ ? [value]
+ : [];
this.$refs.userFormRef?.validateField('deptId');
},
},
@@ -844,6 +887,15 @@ export default {
handleCustomerSelection(rows) {
this.form.customerIds = rows.map(row => row.id);
},
+ formatDeptNames(deptName) {
+ if (!deptName) {
+ return [];
+ }
+ return String(deptName)
+ .split(',')
+ .map(item => item.trim())
+ .filter(Boolean);
+ },
openUserDialog(mode, row = {}) {
this.userDialogMode = mode;
if (mode === 'add') {
@@ -872,9 +924,10 @@ export default {
}
getUser(row.id).then(res => {
const user = res.data.data;
+ const deptIds = func.split(user.deptId || '');
this.form = {
...user,
- deptId: func.split(user.deptId || ''),
+ deptId: Array.isArray(deptIds) ? deptIds : [],
postId: func.split(user.postId || '')[0] || '',
roleId: func.join(user.roleId || ''),
dataScopeDeptIds: user.dataScopeDeptIds || [],
@@ -1416,6 +1469,10 @@ export default {
justify-content: flex-start;
}
+.user-dept-tag + .user-dept-tag {
+ margin-left: 6px;
+}
+
.avue-dialog .el-form-item__label {
white-space: nowrap;
}