B2 议题二前端:版本历史补全 + 升版本改动说明 + 列表分组 + 在途可见
- Defs.vue 版本历史弹窗 640→820,补 创建人/创建时间/改动说明 三列(存量说明显示「(未填写)」) - def-editor 升版本保存弹「本次改动说明(可跳过)」:doSave 入口设闸(!editId&&baseGuid 或 editId&&sourceStatus!==0),主体抽成 submitSave(changeLog) 防递归;常用类型 chips 分号追加, 500 字上限;跳过与填写两条路径都放行并按说明有无区分 toast;草稿直改不弹不传 - Defs.vue 列表默认分组态(同 flowGuid 折叠一行,代表行=已发布最高版,无已发布标「无生效版」), 展开行复用 rowActions;可切「显示全部版本」回现状平铺 - 在途(议题二④):defList 落位后批量取 distinct flowGuid → 新接口 defInflight, 分组行/平铺 GUID 旁展示「在途 N 件」(0 也展示,接口失败降级「—」);停用确认 N>0 追加在途文案 - flow.ts:defSave 加 changeLog 入参、新增 defInflight(未跑 api:gen,按方案手工改) 验证:npm run build 通过;vue-tsc 1.8.27 与 TS 5.9.3 不兼容无法作门禁(另记)
This commit is contained in:
@@ -144,7 +144,7 @@ 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 }) {
|
||||
defSave(body: { id?: number; code: string; name: string; contentJson: string; baseGuid?: string; appKey?: string; changeLog?: string }) {
|
||||
return post(`${ROOT}/admin/def/save`, body);
|
||||
}
|
||||
/** 元数据原地编辑(2026-10-10 议题2):只改 name/appKey 不升版本;已发布亦可 */
|
||||
@@ -164,6 +164,10 @@ class FlowApi {
|
||||
defVersions(flowGuid: string) {
|
||||
return get(`${ROOT}/admin/def/versions`, { flowGuid });
|
||||
}
|
||||
/** 在途办件数(议题二④):flowGuid → 审批中办件数,无在途的流程线也返回 0 键 */
|
||||
defInflight(flowGuids: string[]) {
|
||||
return get(`${ROOT}/admin/def/inflight`, { flowGuids: flowGuids.join(",") });
|
||||
}
|
||||
/** 流程定义示意图(管理面:defId 任意版本,草稿可预览) */
|
||||
adminDefDiagram(params: { id: number | string; mode?: string }) {
|
||||
return get(`${ROOT}/admin/def/diagram`, params);
|
||||
|
||||
+180
-38
@@ -4,7 +4,7 @@
|
||||
// 本页不再直接编辑 JSON 文本(编辑器内置"源码"高级模式兜底);行内「源码」为只读查看+复制。
|
||||
import { ref, computed, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { Message, Tag } from "view-ui-plus";
|
||||
import { Message, Table, Tag } from "view-ui-plus";
|
||||
import MyConfirm from "@/components/MyConfirm";
|
||||
import SourceDrawer from "@/views/flow/components/SourceDrawer.vue";
|
||||
import { flowApi } from "@/api/module/flow";
|
||||
@@ -29,54 +29,173 @@ const defsH = useElementHeight(defsRegionRef);
|
||||
const apps = ref<{ appKey: string; appName: string }[]>([]);
|
||||
const appMap = ref<Record<string, string>>({});
|
||||
const filterApp = ref("");
|
||||
// 议题二②:列表视图(group=同 flowGuid 折叠一行,默认;flat=现状全版本平铺)——纯前端切换,defList 已全量返回
|
||||
const viewMode = ref<"group" | "flat">("group");
|
||||
// 分组展开态(key=flowGuid):Table 数据由 computed 派生,展开态必须存外面才不会丢
|
||||
const openMap = ref<Record<string, boolean>>({});
|
||||
// 议题二④:flowGuid → 在途办件数;拉取失败降级空 map(行内显示「—」,列表不崩)
|
||||
const inflightMap = ref<Record<string, number>>({});
|
||||
|
||||
/** 在途展示:数字=件数(0 也展示);undefined=接口无该线数据 → 「—」 */
|
||||
function inflightText(guid: string): string {
|
||||
const n = inflightMap.value[guid];
|
||||
return n == null ? "在途 —" : `在途 ${n} 件`;
|
||||
}
|
||||
|
||||
/** 创建时间格式化 YYYY-MM-DD HH:mm(后端 LocalDateTime 带 T,空值显示 -) */
|
||||
function fmtTime(raw: any): string {
|
||||
return raw ? String(raw).replace("T", " ").slice(0, 16) : "-";
|
||||
}
|
||||
|
||||
/** 应用列(未归属标记 2026-10-12 appKey 必填化):平铺/分组/展开行共用,口径不漂移 */
|
||||
const renderApp = (h: any, p: any) => {
|
||||
if (!p.row.appKey) {
|
||||
return h(Tag, { color: "warning" }, () => "未归属");
|
||||
}
|
||||
return h("span", appMap.value[p.row.appKey] || p.row.appKey);
|
||||
};
|
||||
|
||||
/** 状态列(草稿橙/已发布绿/停用灰):三态共用 */
|
||||
const renderStatus = (h: any, p: any) => {
|
||||
const c = p.row.status === 1 ? "green" : p.row.status === 0 ? "orange" : "gray";
|
||||
return h(Tag, { color: c }, () => DEF_STATUS[p.row.status] || p.row.status);
|
||||
};
|
||||
|
||||
/** 行操作集(平铺态、分组展开行同一套;禁用规则按 status) */
|
||||
const rowActions = [
|
||||
{ key: "edit", label: "编辑", icon: "icon-edit", on: (r: any) => onEdit(r), disabledWhen: (r: any) => r.status !== 0 },
|
||||
{ key: "publish", label: "发布", icon: "icon-fasong", on: (r: any) => onPublish(r), disabledWhen: (r: any) => r.status !== 0 },
|
||||
{ key: "newVersion", label: "升版本", icon: "icon-tianjia", on: (r: any) => onNewVersion(r), disabledWhen: (r: any) => r.status !== 1 },
|
||||
// 停用:破坏性动作(已发布→停用),danger 沉底并进「更多」
|
||||
{ key: "offline", label: "停用", icon: "icon-stop", on: (r: any) => onOffline(r), disabledWhen: (r: any) => r.status !== 1, danger: true },
|
||||
// 与「停用」对称的专用启用通道(后端 /def/enable:仅停用版→已发布,重跑发布校验;
|
||||
// 草稿不走这里,草稿用「发布」)
|
||||
{ key: "enable", label: "启用", icon: "icon-play", on: (r: any) => onEnable(r), disabledWhen: (r: any) => r.status !== 2 },
|
||||
// 元数据原地编辑(2026-10-10 议题2):改名称/归属应用不升版本(含已发布/停用)
|
||||
{ key: "editMeta", label: "编辑信息", icon: "icon-bianji", on: (r: any) => onEditMeta(r) },
|
||||
{ key: "diagram", label: "图示", icon: "icon-tupian", on: (r: any) => onDiagram(r) },
|
||||
{ key: "source", label: "源码", icon: "icon-liebiao", on: (r: any) => onSource(r) },
|
||||
{ key: "versions", label: "版本历史", icon: "icon-shijian", on: (r: any) => onVersions(r) },
|
||||
];
|
||||
|
||||
const columns = [
|
||||
{ title: "序号", type: "index", width: 70, align: "center" },
|
||||
{ title: "流程", key: "name", minWidth: 180 },
|
||||
{ title: "编码", key: "code", width: 160 },
|
||||
{ title: "应用", key: "appKey", width: 130, align: "center", render: (h: any, p: any) => {
|
||||
// 未归属标记(2026-10-12 appKey 必填化):存量 NULL 线在此醒目,随编辑/升版本收敛
|
||||
if (!p.row.appKey) {
|
||||
return h(Tag, { color: "warning" }, () => "未归属");
|
||||
}
|
||||
return h("span", appMap.value[p.row.appKey] || p.row.appKey);
|
||||
} },
|
||||
{ title: "应用", key: "appKey", width: 130, align: "center", render: renderApp },
|
||||
{ title: "版本", key: "version", width: 70, align: "center" },
|
||||
{ title: "状态", width: 90, align: "center", render: (h: any, p: any) => {
|
||||
const c = p.row.status === 1 ? "green" : p.row.status === 0 ? "orange" : "gray";
|
||||
return h(Tag, { color: c }, () => DEF_STATUS[p.row.status] || p.row.status);
|
||||
{ title: "状态", width: 90, align: "center", render: renderStatus },
|
||||
{ title: "GUID", key: "flowGuid", width: 240, render: (h: any, p: any) => {
|
||||
// 平铺态也带在途(议题二④):计数按流程线口径,故挂在 GUID 旁
|
||||
const n = inflightMap.value[p.row.flowGuid];
|
||||
return h("span", {}, [
|
||||
p.row.flowGuid,
|
||||
h(Tag, { color: n ? "blue" : "default", style: "margin-left:6px" }, () => inflightText(p.row.flowGuid)),
|
||||
]);
|
||||
} },
|
||||
{ title: "GUID", key: "flowGuid", width: 200 },
|
||||
{ title: "发布时间", width: 160, render: (h: any, p: any) => h("span", (p.row.publishTime || "").replace("T", " ") || "-") },
|
||||
actionColumn(
|
||||
[
|
||||
{ key: "edit", label: "编辑", icon: "icon-edit", on: (r: any) => onEdit(r), disabledWhen: (r: any) => r.status !== 0 },
|
||||
{ key: "publish", label: "发布", icon: "icon-fasong", on: (r: any) => onPublish(r), disabledWhen: (r: any) => r.status !== 0 },
|
||||
{ key: "newVersion", label: "升版本", icon: "icon-tianjia", on: (r: any) => onNewVersion(r), disabledWhen: (r: any) => r.status !== 1 },
|
||||
// 停用:破坏性动作(已发布→停用),danger 沉底并进「更多」
|
||||
{ key: "offline", label: "停用", icon: "icon-stop", on: (r: any) => onOffline(r), disabledWhen: (r: any) => r.status !== 1, danger: true },
|
||||
// 与「停用」对称的专用启用通道(后端 /def/enable:仅停用版→已发布,重跑发布校验;
|
||||
// 草稿不走这里,草稿用「发布」)
|
||||
{ key: "enable", label: "启用", icon: "icon-play", on: (r: any) => onEnable(r), disabledWhen: (r: any) => r.status !== 2 },
|
||||
// 元数据原地编辑(2026-10-10 议题2):改名称/归属应用不升版本(含已发布/停用)
|
||||
{ key: "editMeta", label: "编辑信息", icon: "icon-bianji", on: (r: any) => onEditMeta(r) },
|
||||
{ key: "diagram", label: "图示", icon: "icon-tupian", on: (r: any) => onDiagram(r) },
|
||||
{ key: "source", label: "源码", icon: "icon-liebiao", on: (r: any) => onSource(r) },
|
||||
{ key: "versions", label: "版本历史", icon: "icon-shijian", on: (r: any) => onVersions(r) },
|
||||
],
|
||||
{ mode: "text", width: 180, fixed: "right" },
|
||||
),
|
||||
{ title: "发布时间", width: 160, render: (h: any, p: any) => h("span", fmtTime(p.row.publishTime)) },
|
||||
actionColumn(rowActions, { mode: "text", width: 180, fixed: "right" }),
|
||||
];
|
||||
|
||||
async function load() {
|
||||
loading.value = true;
|
||||
try {
|
||||
rows.value = (await flowApi.defList({ appKey: filterApp.value || undefined }).send()) || [];
|
||||
loadInflight();
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** 在途统计(议题二④):列表到位后取 distinct flowGuids 批量查,失败静默降级(行内显示「—」) */
|
||||
async function loadInflight() {
|
||||
const guids = Array.from(new Set(rows.value.map((r: any) => r.flowGuid).filter(Boolean))).slice(0, 100);
|
||||
if (!guids.length) {
|
||||
inflightMap.value = {};
|
||||
return;
|
||||
}
|
||||
try {
|
||||
inflightMap.value = (await flowApi.defInflight(guids).send()) || {};
|
||||
} catch {
|
||||
inflightMap.value = {};
|
||||
}
|
||||
}
|
||||
|
||||
/** 分组行(议题二②):同 flowGuid 折叠一行,代表行=已发布中最高版;无已发布取最高版并标「无生效版」 */
|
||||
const groups = computed(() => {
|
||||
const bucket: Record<string, any[]> = {};
|
||||
const order: string[] = [];
|
||||
rows.value.forEach((r: any) => {
|
||||
const g = r.flowGuid || "";
|
||||
if (!g) return;
|
||||
if (!bucket[g]) {
|
||||
bucket[g] = [];
|
||||
order.push(g);
|
||||
}
|
||||
bucket[g].push(r);
|
||||
});
|
||||
return order.map((g) => {
|
||||
const vs = bucket[g].slice().sort((a: any, b: any) => b.version - a.version);
|
||||
const published = vs.filter((v: any) => v.status === 1);
|
||||
const cur = published[0] || vs[0];
|
||||
return {
|
||||
flowGuid: g, id: cur.id, name: cur.name, code: cur.code, appKey: cur.appKey,
|
||||
version: cur.version, status: cur.status, publishTime: cur.publishTime,
|
||||
total: vs.length, hasPublished: published.length > 0,
|
||||
versions: vs, _expanded: !!openMap.value[g],
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
/** 展开行:该流程线全部版本明细(行对象即 FlwDef,操作复用 rowActions)。
|
||||
* 在途计数接口按 flowGuid 聚合,没有按版本的可靠数据,故明细列不铺在途、只在分组行展示。 */
|
||||
const versionColumns = [
|
||||
{ title: "版本", width: 70, render: (h: any, p: any) => h("b", `v${p.row.version}`) },
|
||||
{ title: "状态", width: 90, align: "center", render: renderStatus },
|
||||
{ title: "创建人", width: 100, render: (h: any, p: any) => h("span", p.row.createBy || "-") },
|
||||
{ title: "创建时间", width: 140, render: (h: any, p: any) => h("span", fmtTime(p.row.createTime)) },
|
||||
{ title: "改动说明", minWidth: 230, render: (h: any, p: any) => (p.row.changeLog
|
||||
? h("span", p.row.changeLog)
|
||||
: h("span", { style: "color:#999" }, "(未填写)")) },
|
||||
actionColumn(rowActions, { mode: "text", width: 210 }),
|
||||
];
|
||||
|
||||
const groupColumns = [
|
||||
{ type: "expand", width: 40, render: (h: any, p: any) => h(Table, {
|
||||
columns: versionColumns, data: p.row.versions, size: "small", noDataText: "暂无数据",
|
||||
}) },
|
||||
{ title: "序号", type: "index", width: 60, align: "center" },
|
||||
{ title: "流程", minWidth: 260, render: (h: any, p: any) => {
|
||||
const n = inflightMap.value[p.row.flowGuid];
|
||||
return h("span", {}, [
|
||||
h("b", p.row.name),
|
||||
h(Tag, { color: p.row.hasPublished ? "green" : "default", style: "margin-left:6px" },
|
||||
() => (p.row.hasPublished ? `当前生效 v${p.row.version}` : "无生效版")),
|
||||
h(Tag, { color: n ? "blue" : "default", style: "margin-left:6px" }, () => inflightText(p.row.flowGuid)),
|
||||
]);
|
||||
} },
|
||||
{ title: "编码", key: "code", width: 160 },
|
||||
{ title: "应用", key: "appKey", width: 130, align: "center", render: renderApp },
|
||||
{ title: "版本", width: 120, render: (h: any, p: any) => h("span", `v${p.row.version} · 共 ${p.row.total} 版`) },
|
||||
{ title: "状态", width: 90, align: "center", render: renderStatus },
|
||||
{ title: "GUID", width: 130, render: (h: any, p: any) => h("span", { title: p.row.flowGuid }, `${String(p.row.flowGuid).slice(0, 8)}…`) },
|
||||
{ title: "发布时间", width: 160, render: (h: any, p: any) => h("span", fmtTime(p.row.publishTime)) },
|
||||
actionColumn(
|
||||
[
|
||||
{ key: "versions", label: "版本历史", icon: "icon-shijian", on: (r: any) => onVersions(r) },
|
||||
{ key: "editMeta", label: "编辑信息", icon: "icon-bianji", on: (r: any) => onEditMeta(r) },
|
||||
],
|
||||
{ mode: "text", width: 140, fixed: "right" },
|
||||
),
|
||||
];
|
||||
|
||||
/** 分组态点行展开/收起(展开箭头同一路径:箭头内部态会被下一帧的 _expanded 重新校准) */
|
||||
function onGroupRowClick(row: any) {
|
||||
if (row && row.flowGuid) {
|
||||
openMap.value[row.flowGuid] = !openMap.value[row.flowGuid];
|
||||
}
|
||||
}
|
||||
|
||||
/** 应用清单(筛选下拉):应用设置白名单(flw_app enabled=1),失败降级为空下拉 */
|
||||
async function loadAppKeys() {
|
||||
try {
|
||||
@@ -119,10 +238,13 @@ async function onPublish(row: any) {
|
||||
}
|
||||
|
||||
function onOffline(row: any) {
|
||||
// 议题二④:在途数 >0 才追加提示(0 或接口降级态沿用原文案)
|
||||
const n = inflightMap.value[row.flowGuid] || 0;
|
||||
MyConfirm({
|
||||
title: "停用",
|
||||
msg: `确定停用流程「${row.name}」吗?`,
|
||||
info: "停用后无法发起新办件,进行中的办件不受影响",
|
||||
info: "停用后无法发起新办件,进行中的办件不受影响"
|
||||
+ (n ? `;当前在途 ${n} 件仍跑本版直至完成` : ""),
|
||||
async onOk() {
|
||||
await flowApi.defOffline(row.id).send();
|
||||
Message.success("已停用");
|
||||
@@ -241,19 +363,39 @@ onMounted(() => {
|
||||
style="width: 200px; margin-left: 8px" @on-change="load">
|
||||
<Option v-for="a in apps" :key="a.appKey" :value="a.appKey">{{ a.appName }}</Option>
|
||||
</Select>
|
||||
<!-- 议题二②:分组(同 flowGuid 折叠一行,默认)/ 平铺(现状全版本行)纯前端切换 -->
|
||||
<RadioGroup v-model="viewMode" type="button" button-style="solid" class="fl" style="margin-left: 8px">
|
||||
<Radio label="group">仅最新版(分组)</Radio>
|
||||
<Radio label="flat">显示全部版本</Radio>
|
||||
</RadioGroup>
|
||||
<span class="fl" style="margin-left: 12px; color: #808695; font-size: 12px; line-height: 32px">
|
||||
{{ viewMode === "group"
|
||||
? "同 flowGuid 多版折叠为一行,点行展开可见各版创建人 / 创建时间 / 改动说明"
|
||||
: "平铺所有版本行(现状口径)" }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="table-region" ref="defsRegionRef">
|
||||
<Table :columns="columns" :data="rows" :loading="loading" class="link-table table-bottom-box"
|
||||
<Table v-if="viewMode === 'group'" :columns="groupColumns" :data="groups" :loading="loading"
|
||||
class="link-table table-bottom-box" :height="defsH || undefined" no-data-text="暂无数据"
|
||||
@on-row-click="onGroupRowClick" />
|
||||
<Table v-else :columns="columns" :data="rows" :loading="loading" class="link-table table-bottom-box"
|
||||
:height="defsH || undefined" no-data-text="暂无数据" />
|
||||
</div>
|
||||
|
||||
<Modal v-model="versionVisible" title="版本历史" width="640">
|
||||
<Modal v-model="versionVisible" title="版本历史" width="820">
|
||||
<p style="color: #808695; font-size: 12px; line-height: 1.6; margin-bottom: 8px">
|
||||
审计信息:创建人 / 创建时间 / 改动说明为本次新增列(存量版本未填说明时显示「(未填写)」)
|
||||
</p>
|
||||
<Table :columns="[
|
||||
{ title: '版本', key: 'version', width: 80 },
|
||||
{ title: '名称', key: 'name' },
|
||||
{ title: '状态', width: 90, render: (h, p) => h(Tag, () => DEF_STATUS[p.row.status]) },
|
||||
{ title: '发布时间', width: 160, render: (h, p) => (p.row.publishTime || '').replace('T', ' ') || '-' },
|
||||
{ title: '版本', key: 'version', width: 70, render: (h, p) => h('b', 'v' + p.row.version) },
|
||||
{ title: '名称', key: 'name', width: 150 },
|
||||
{ title: '状态', width: 80, render: (h, p) => h(Tag, () => DEF_STATUS[p.row.status]) },
|
||||
{ title: '发布时间', width: 132, render: (h, p) => (p.row.publishTime || '').replace('T', ' ').slice(0, 16) || '-' },
|
||||
{ title: '创建人', width: 90, render: (h, p) => p.row.createBy || '-' },
|
||||
{ title: '创建时间', width: 132, render: (h, p) => (p.row.createTime || '').replace('T', ' ').slice(0, 16) || '-' },
|
||||
{ title: '改动说明', minWidth: 230, render: (h, p) => p.row.changeLog
|
||||
? h('span', p.row.changeLog) : h('span', { style: 'color:#999' }, '(未填写)') },
|
||||
]" :data="versions" size="small" no-data-text="暂无数据" />
|
||||
</Modal>
|
||||
|
||||
|
||||
@@ -100,6 +100,10 @@ const conditionDrawer = ref(false);
|
||||
const settingsDrawer = ref(false);
|
||||
const jsonDrawer = ref(false);
|
||||
const editingUid = ref("");
|
||||
// 议题二③:升版本改动说明弹窗(仅「本次保存将创建新版本」时出现,可跳过)
|
||||
const logModal = ref(false);
|
||||
const logText = ref("");
|
||||
const LOG_CHIPS = ["修复审批人缺失", "调整审批链", "新增抄送对象", "修改条件表达式", "调整流程设置"];
|
||||
|
||||
const editingNode = computed<ApprovalNode | null>(() => {
|
||||
const item = editingUid.value ? findItem(model, editingUid.value) : null;
|
||||
@@ -399,6 +403,28 @@ async function onSave(): Promise<void> {
|
||||
}
|
||||
|
||||
async function doSave(): Promise<void> {
|
||||
// 议题二③:本次保存将复制出新版本行时先问改动说明(挂在 doSave 入口,onSave 与同编码软确认两条路径都经过)
|
||||
if (willCreateVersion()) {
|
||||
logText.value = "";
|
||||
logModal.value = true;
|
||||
return;
|
||||
}
|
||||
await submitSave();
|
||||
}
|
||||
|
||||
/** 升版本判据:baseGuid 入口(列表「升版本」)必带 baseGuid;编辑已发布/停用版会走后端复制升版分支 */
|
||||
function willCreateVersion(): boolean {
|
||||
return (!editId.value && !!baseGuid.value) || (!!editId.value && sourceStatus.value !== 0);
|
||||
}
|
||||
|
||||
/** 常用改动类型点选:追加到说明文本(分号连接),可再手工补充 */
|
||||
function appendLogChip(text: string): void {
|
||||
const cur = logText.value.trim();
|
||||
logText.value = cur ? `${cur};${text}` : text;
|
||||
}
|
||||
|
||||
async function submitSave(changeLog?: string): Promise<void> {
|
||||
logModal.value = false;
|
||||
const content = JSON.stringify(toContentJson(model));
|
||||
saving.value = true;
|
||||
try {
|
||||
@@ -410,9 +436,12 @@ async function doSave(): Promise<void> {
|
||||
contentJson: content,
|
||||
baseGuid: baseGuid.value || undefined,
|
||||
appKey: (appKey.value || "").trim() || undefined,
|
||||
changeLog: changeLog || undefined,
|
||||
}).send();
|
||||
savedSnapshot.value = currentSnapshot.value;
|
||||
Message.success("已保存草稿");
|
||||
Message.success(willCreateVersion()
|
||||
? (changeLog ? "已保存草稿 · 改动说明已留存" : "已保存草稿(未填写改动说明)")
|
||||
: "已保存草稿");
|
||||
router.push("/admin/defs");
|
||||
} finally {
|
||||
saving.value = false;
|
||||
@@ -534,6 +563,25 @@ onUnmounted(() => window.removeEventListener("beforeunload", onBeforeUnload));
|
||||
<ConditionDrawer v-model="conditionDrawer" :node="editingCondition" @removed="conditionDrawer = false" />
|
||||
<SettingsDrawer v-model="settingsDrawer" :settings="model.settings" @save="onUrgeSave" />
|
||||
<JsonDrawer v-model="jsonDrawer" :def="defJson" @applied="onJsonApplied" />
|
||||
|
||||
<!-- 议题二③:升版本改动说明(仅「本次保存将创建新版本」时出现,跳过也放行) -->
|
||||
<Modal v-model="logModal" title="保存为新版本草稿" :mask-closable="false" width="520">
|
||||
<p class="cl-note">
|
||||
当前为「升版本 · 基于 v{{ sourceVersion }}({{ DEF_STATUS[sourceStatus] }})」,
|
||||
保存将创建新版本草稿(flowGuid 不变,版本号自动 +1)。
|
||||
</p>
|
||||
<div class="cl-label">本次改动说明<span class="cl-skip">可跳过</span></div>
|
||||
<div class="cl-chips">
|
||||
<span v-for="c in LOG_CHIPS" :key="c" class="cl-chip" @click="appendLogChip(c)">{{ c }}</span>
|
||||
</div>
|
||||
<Input v-model="logText" type="textarea" :rows="3" :maxlength="500" show-word-limit
|
||||
placeholder="一句话说清本版改了什么,如:教务处节点补充审批人配置;版本历史与列表可见" />
|
||||
<template #footer>
|
||||
<span class="cl-hint">跳过也允许保存——但「多一条记录」的区分度就没了</span>
|
||||
<Button :disabled="saving" @click="submitSave()">跳过</Button>
|
||||
<Button type="primary" :loading="saving" @click="submitSave(logText.trim())">保存草稿</Button>
|
||||
</template>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -660,4 +708,52 @@ onUnmounted(() => window.removeEventListener("beforeunload", onBeforeUnload));
|
||||
color: #b0b6c1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* 升版本改动说明弹窗(议题二③,规格对齐原型 V2) */
|
||||
.cl-note {
|
||||
background: #fff7e6;
|
||||
border: 1px solid #ffd77a;
|
||||
border-radius: 6px;
|
||||
padding: 9px 12px;
|
||||
font-size: 12px;
|
||||
color: #8a5a17;
|
||||
line-height: 1.7;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.cl-label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #17233d;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.cl-skip {
|
||||
font-weight: 400;
|
||||
color: #808695;
|
||||
font-size: 12px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
.cl-chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.cl-chip {
|
||||
border: 1px solid #e3e6eb;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 3px 11px;
|
||||
font-size: 12px;
|
||||
color: #515a6e;
|
||||
cursor: pointer;
|
||||
}
|
||||
.cl-chip:hover {
|
||||
border-color: var(--brand);
|
||||
color: var(--brand);
|
||||
}
|
||||
.cl-hint {
|
||||
float: left;
|
||||
font-size: 12px;
|
||||
color: #b0b6c1;
|
||||
line-height: 32px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user