From cdea9c559be8e586274bb1aabe528623e489bc87 Mon Sep 17 00:00:00 2001 From: chenxing Date: Thu, 22 Oct 2026 09:56:06 +0800 Subject: [PATCH] =?UTF-8?q?t1:=20=E5=AE=9A=E4=B9=89=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E6=8E=A5=E8=A1=A8=E5=8D=95=E4=B8=AD=E5=BF=83=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=EF=BC=88=E8=A1=A8=E5=8D=95=E9=80=89=E6=8B=A9=E4=B8=8E?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=9D=90=E6=A0=87=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/module/flow.ts | 24 +++++++++- src/views/flow/admin/def-editor/index.vue | 55 +++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/api/module/flow.ts b/src/api/module/flow.ts index 49c45ad..ca8e38c 100644 --- a/src/api/module/flow.ts +++ b/src/api/module/flow.ts @@ -144,7 +144,29 @@ class FlowApi { defGet(id: number | string) { return get(`${ROOT}/admin/def/get`, { id }); } - defSave(body: { id?: number; code: string; name: string; contentJson: string; baseGuid?: string; appKey?: string; changeLog?: string }) { + /** + * 表单中心目录(v3/TASK_1):编辑器"关联表单"选择器的数据源。 + * 走本应用同源代理,浏览器不持 appKey/secret、也不出现 form-center 地址; + * **没有 schId 入参**——管理域由后端从 CAS 会话派生,这是有意的,别"顺手加一个"。 + */ + formCenterForms(params: { keyword?: string; page?: number; pageSize?: number } = {}) { + return get<{ items: any[]; total: number }>(`${ROOT}/admin/form-center/forms`, params); + } + /** + * 保存定义。`formUuid`/`formVersion`(v3)是**行字段**、不进 contentJson: + * 成对提交(后端单传一个即拒);`formUuid=""`=取消关联并同时清空版本;不传=保持原关联。 + */ + defSave(body: { + id?: number; + code: string; + name: string; + contentJson: string; + baseGuid?: string; + appKey?: string; + changeLog?: string; + formUuid?: string; + formVersion?: number; + }) { return post(`${ROOT}/admin/def/save`, body); } /** 元数据原地编辑(2026-10-10 议题2):只改 name/appKey 不升版本;已发布亦可 */ diff --git a/src/views/flow/admin/def-editor/index.vue b/src/views/flow/admin/def-editor/index.vue index e639585..d246ffa 100644 --- a/src/views/flow/admin/def-editor/index.vue +++ b/src/views/flow/admin/def-editor/index.vue @@ -61,6 +61,15 @@ const sourceFlowGuid = ref(""); const appKey = ref(""); /** 应用清单下拉(应用设置白名单 flw_app enabled=1,显示应用名),拉取失败降级为仅当前值 */ const appOptions = ref<{ appKey: string; appName: string }[]>([]); +/** + * 关联表单坐标(flw_def.form_uuid / form_version,v3/TASK_1):行字段、不进 contentJson。 + * 版本由选中时那一条目录行带出(中心当前发布版),不给手填——存的就是服务端核验过的坐标。 + */ +const formUuid = ref(""); +const formVersion = ref(undefined); +/** 表单中心目录(同源代理);拉不到时选择器禁用并说明原因,不假装"这所学校没有表单" */ +const formOptions = ref([]); +const formCenterError = ref(""); const model = reactive(createEmptyModel()); /** 科室列表(deptList 聚合行):仅用于下拉选项与"无启用人员"提示 */ @@ -249,6 +258,15 @@ async function load(): Promise { } catch { appOptions.value = []; } + // 表单中心目录:授权没配/中心不可达时选择器禁用并说明原因(空列表 ≠ "没有可用表单") + try { + const page: any = await flowApi.formCenterForms({ page: 1, pageSize: 100 }).send(); + formOptions.value = page?.items || []; + formCenterError.value = ""; + } catch (e: any) { + formOptions.value = []; + formCenterError.value = String(e?.message || e || "表单中心目录不可达"); + } const queryId = route.query.id ? Number(route.query.id) : null; const queryGuid = (route.query.baseGuid as string) || ""; @@ -273,6 +291,8 @@ async function load(): Promise { model.code = d?.code || ""; model.name = d?.name || ""; appKey.value = d?.appKey || ""; + formUuid.value = d?.formUuid || ""; + formVersion.value = d?.formVersion == null ? undefined : Number(d.formVersion); try { applyParsed(fromContentJson(JSON.parse(d?.contentJson || "{}"))); } catch (e: any) { @@ -430,6 +450,16 @@ function onJsonApplied(p: ParsedDef): void { applyParsed(p); } +/** + * 选表=成对记下 uuid 与中心当时发布版;清空则两列一起清(后端要求成对,半个坐标存不下)。 + * 版本号一律取自目录行,页面不提供手填——填一个中心没有的版本,只会在发布期撞"坐标不符"。 + */ +function onFormChange(uuid: string): void { + const hit = uuid ? formOptions.value.find((f) => f.formUuid === uuid) : null; + formUuid.value = hit ? hit.formUuid : ""; + formVersion.value = hit ? Number(hit.version) : undefined; +} + async function onSave(): Promise { if (!model.name.trim()) { Message.warning("请填写流程名称"); @@ -445,6 +475,11 @@ async function onSave(): Promise { Message.warning("请选择归属应用(应用需先在 流程管理 > 应用设置 中开启)"); return; } + // 关联表单必须成对:改造前只有关联、没有版本号的存量行,重新选一次才能保存(后端同样会拒) + if (formUuid.value && !formVersion.value) { + Message.warning("该流程关联的表单还没有确切版本号,请在「关联表单」里重新选择一次(版本由表单中心给出,不可手填)"); + return; + } const errors = countErrors(issues.value); if (errors.length) { Message.error(`校验未通过:${errors[0].text}`); @@ -503,6 +538,9 @@ async function submitSave(changeLog?: string): Promise { baseGuid: baseGuid.value || undefined, appKey: (appKey.value || "").trim() || undefined, changeLog: changeLog || undefined, + // 关联表单成对提交:空串=显式取消关联(后端同时清空版本),有值=uuid + 中心当时发布版 + formUuid: formUuid.value, + formVersion: formUuid.value ? formVersion.value : undefined, }).send(); savedSnapshot.value = currentSnapshot.value; Message.success(willCreateVersion() @@ -617,6 +655,23 @@ onUnmounted(() => window.removeEventListener("beforeunload", onBeforeUnload)); +
+ + +
+ {{ formCenterError }} +
+
+ 历史关联缺版本号,请重新选择表单后再保存 +
+
已绑定 v{{ formVersion }}(发布时按这组坐标核验快照)
+
目录只列中心已发布、且已授权给本应用的表单
+