钉钉审批功能完善、混炼示方新增是否附加料
This commit is contained in:
@@ -9,10 +9,18 @@ enum Api {
|
||||
edit = '/xslmes/mesXslBizDocRegistry/edit',
|
||||
deleteOne = '/xslmes/mesXslBizDocRegistry/delete',
|
||||
deleteBatch = '/xslmes/mesXslBizDocRegistry/deleteBatch',
|
||||
dbTables = '/xslmes/mesXslBizDocRegistry/dbTables',
|
||||
}
|
||||
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/** 当前库物理表(审批注册中心下拉) */
|
||||
export const listDbTables = (keyword?: string) =>
|
||||
defHttp.get<{ value: string; label: string; comment?: string }[]>({
|
||||
url: Api.dbTables,
|
||||
params: keyword ? { keyword } : {},
|
||||
});
|
||||
|
||||
export const saveOrUpdate = (params, isUpdate) =>
|
||||
isUpdate ? defHttp.put({ url: Api.edit, params }) : defHttp.post({ url: Api.save, params });
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { listDbTables } from './MesXslBizDocRegistry.api';
|
||||
|
||||
const STAGE_DICT = 'mes_xsl_approval_stage';
|
||||
|
||||
@@ -36,9 +37,16 @@ export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '物理表名',
|
||||
field: 'tableName',
|
||||
component: 'Input',
|
||||
componentProps: { placeholder: '数据库表名,如 mes_xsl_mixer_ps_compile' },
|
||||
dynamicRules: () => [{ required: true, message: '请输入物理表名!' }],
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
api: listDbTables,
|
||||
showSearch: true,
|
||||
placeholder: '请选择数据库物理表,可输入关键字筛选',
|
||||
labelField: 'label',
|
||||
valueField: 'value',
|
||||
immediate: true,
|
||||
},
|
||||
dynamicRules: () => [{ required: true, message: '请选择物理表名!' }],
|
||||
},
|
||||
{
|
||||
label: '中文名称',
|
||||
|
||||
@@ -19,6 +19,8 @@ enum Api {
|
||||
registryByTable = '/xslmes/mesXslIntegrationPlan/registryByTable',
|
||||
previewDefaultFromFlow = '/xslmes/mesXslIntegrationPlan/previewDefaultFromFlow',
|
||||
generateDefaultFromFlow = '/xslmes/mesXslIntegrationPlan/generateDefaultFromFlow',
|
||||
generateForNode = '/xslmes/mesXslIntegrationPlan/generateForNode',
|
||||
queryById = '/xslmes/mesXslIntegrationPlan/queryById',
|
||||
}
|
||||
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
@@ -49,6 +51,18 @@ export const generateDefaultFromFlow = (params: {
|
||||
nodeBindings?: Array<{ nodeId: string; stage?: string | null }>;
|
||||
}) => defHttp.post<any>({ url: Api.generateDefaultFromFlow, params });
|
||||
|
||||
/** 流程设计器:为单个节点生成集成方案 */
|
||||
export const generateForNode = (params: {
|
||||
sourceTable: string;
|
||||
flowId: string;
|
||||
nodeId: string;
|
||||
stageKey: string;
|
||||
flowConfig?: string;
|
||||
overwriteDraft?: boolean;
|
||||
}) => defHttp.post<any>({ url: Api.generateForNode, params });
|
||||
|
||||
export const queryPlanById = (id: string) => defHttp.get<any>({ url: Api.queryById, params: { id } });
|
||||
|
||||
// 动作管理
|
||||
export const listActions = (planId) => defHttp.get({ url: Api.actionList, params: { planId } });
|
||||
export const saveAction = (params) => defHttp.post({ url: Api.actionAdd, params });
|
||||
|
||||
@@ -105,6 +105,15 @@
|
||||
return record.actionConfig || '-';
|
||||
}
|
||||
}
|
||||
if (record.actionType === 'SQL_UPDATE') {
|
||||
try {
|
||||
const cfg = JSON.parse(record.actionConfig || '{}');
|
||||
const base = record.sqlTemplate || '-';
|
||||
return cfg.syncTrace ? `${base};痕迹同步:是` : base;
|
||||
} catch {
|
||||
return record.sqlTemplate || '-';
|
||||
}
|
||||
}
|
||||
return record.sqlTemplate || '-';
|
||||
}
|
||||
|
||||
@@ -192,5 +201,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ open });
|
||||
defineExpose({ open, openAndEditFirstAction });
|
||||
|
||||
async function openAndEditFirstAction(plan: Recordable) {
|
||||
await open(plan);
|
||||
if (actions.value.length > 0) {
|
||||
openVisualEditor(actions.value[0]);
|
||||
} else {
|
||||
openVisualEditor();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -177,6 +177,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- update-begin---author:GHT ---date:2026-06-10 for:【关联表痕迹同步】关联表动作可选同步主表审批痕迹 -->
|
||||
<div
|
||||
v-if="vc.visualType === 'STATUS_MODIFY' || vc.visualType === 'DATA_SYNC'"
|
||||
style="background: #f6ffed; border: 1px solid #b7eb8f; border-radius: 6px; padding: 12px 14px; margin-bottom: 16px"
|
||||
>
|
||||
<a-checkbox v-model:checked="vc.syncTrace">同步主表审批痕迹到目标表</a-checkbox>
|
||||
<div style="font-size: 12px; color: #666; margin-top: 8px; line-height: 1.6">
|
||||
开启后:环节通过时将主表当前审批人/时间写入目标表 <code>mes_xsl_approval_trace</code>;
|
||||
驳回时将按「新状态」清空对应环节痕迹。
|
||||
<span v-if="vc.visualType === 'DATA_SYNC'" style="color: #fa8c16">(驳回清空仅对「状态修改」动作生效)</span>
|
||||
目标表须已在审批注册中心启用对应环节。
|
||||
</div>
|
||||
</div>
|
||||
<!-- update-end---author:GHT ---date:2026-06-10 for:【关联表痕迹同步】关联表动作可选同步主表审批痕迹 -->
|
||||
|
||||
<!-- ============ 状态修改(全新设计) ============ -->
|
||||
<template v-if="vc.visualType === 'STATUS_MODIFY'">
|
||||
|
||||
@@ -341,6 +356,8 @@
|
||||
statusConfig: StatusConfig;
|
||||
fieldMappings: FieldMapping[];
|
||||
registryStage?: RegistryStageConfig;
|
||||
/** 是否将主表审批痕迹同步到目标表 */
|
||||
syncTrace?: boolean;
|
||||
}
|
||||
|
||||
const emit = defineEmits<{ success: [action: any] }>();
|
||||
@@ -431,6 +448,7 @@
|
||||
statusConfig: defaultStatusConfig(),
|
||||
fieldMappings: [],
|
||||
registryStage: defaultRegistryStage(),
|
||||
syncTrace: false,
|
||||
});
|
||||
|
||||
/** 兼容 Flyway 扁平格式(stage/expectedFrom 在顶层)与向导嵌套格式(registryStage 对象) */
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import { queryByBiz } from './MesXslApprovalTrace.api';
|
||||
|
||||
/** 配合示方业务表(与审批注册中心 table_name 一致) */
|
||||
export const FORMULA_SPEC_BIZ_TABLE = 'mes_xsl_formula_spec';
|
||||
|
||||
/** 混炼示方业务表 */
|
||||
export const MIXING_SPEC_BIZ_TABLE = 'mes_xsl_mixing_spec';
|
||||
|
||||
const TRACE_FIELD_KEYS = [
|
||||
'traceProofreadBy',
|
||||
'traceProofreadTime',
|
||||
'traceAuditBy',
|
||||
'traceAuditTime',
|
||||
'traceApproveBy',
|
||||
'traceApproveTime',
|
||||
] as const;
|
||||
|
||||
/** 从列表/详情记录中提取已注入的痕迹字段 */
|
||||
export function pickTraceFields(record?: Recordable | null): Recordable {
|
||||
const out: Recordable = {};
|
||||
if (!record) return out;
|
||||
for (const key of TRACE_FIELD_KEYS) {
|
||||
if (record[key] != null && record[key] !== '') {
|
||||
out[key] = record[key];
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** 将痕迹表实体字段映射为列表注入格式 traceProofreadBy 等 */
|
||||
export function applyTraceEntityToRecord(record: Recordable, trace?: Recordable | null): Recordable {
|
||||
if (!record) return record;
|
||||
const merged = { ...record, ...pickTraceFields(record) };
|
||||
if (!trace) return merged;
|
||||
return {
|
||||
...merged,
|
||||
traceProofreadBy: trace.proofreadBy ?? merged.traceProofreadBy,
|
||||
traceProofreadTime: trace.proofreadTime ?? merged.traceProofreadTime,
|
||||
traceAuditBy: trace.auditBy ?? merged.traceAuditBy,
|
||||
traceAuditTime: trace.auditTime ?? merged.traceAuditTime,
|
||||
traceApproveBy: trace.approveBy ?? merged.traceApproveBy,
|
||||
traceApproveTime: trace.approveTime ?? merged.traceApproveTime,
|
||||
};
|
||||
}
|
||||
|
||||
export function hasTraceWorkflowInfo(record?: Recordable | null): boolean {
|
||||
return !!(
|
||||
record?.traceProofreadBy ||
|
||||
record?.traceProofreadTime ||
|
||||
record?.traceAuditBy ||
|
||||
record?.traceAuditTime ||
|
||||
record?.traceApproveBy ||
|
||||
record?.traceApproveTime
|
||||
);
|
||||
}
|
||||
|
||||
export function normalizeApiRecord(mainRaw: unknown): Recordable {
|
||||
const raw = mainRaw as Recordable;
|
||||
if (raw?.id != null) return raw;
|
||||
return (raw as any)?.result ?? raw ?? {};
|
||||
}
|
||||
|
||||
/** 加载业务主表并合并痕迹(列表注入 / queryById 增强 / queryByBiz 兜底) */
|
||||
export async function loadRecordWithTrace(
|
||||
id: string,
|
||||
bizTable: string,
|
||||
fetchById: (params: { id: string }) => Promise<unknown>,
|
||||
listRecord?: Recordable,
|
||||
): Promise<Recordable> {
|
||||
const mainRaw = await fetchById({ id });
|
||||
let record = normalizeApiRecord(mainRaw);
|
||||
record = applyTraceEntityToRecord(record, pickTraceFields(listRecord));
|
||||
if (!hasTraceWorkflowInfo(record)) {
|
||||
try {
|
||||
const trace = await queryByBiz({ bizTable, bizDataId: id });
|
||||
record = applyTraceEntityToRecord(record, trace);
|
||||
} catch {
|
||||
// 无痕迹或无权查询时忽略
|
||||
}
|
||||
}
|
||||
return record;
|
||||
}
|
||||
Reference in New Issue
Block a user