@epxing/utils 5.3.0-beta.2 → 5.3.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +1 -1
- package/README.md +23 -23
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/ai.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/ai_import.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/app.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/approval.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/canvas-editor/option.svg.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/create_market_system.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/create_system.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/custom.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/default-icon.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/ex_link.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/excel.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/folder.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/hall/form.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/hall/meta.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/hall/process.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/hall/rule.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/hall/service.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/hall/userRole.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/import.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/module.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/null.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/photo.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/single_file.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/snapshot-history.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/snapshot-manual.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/snapshot-realtime.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/staff.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/sync_append.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/sync_append_update.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/sync_loading.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/sync_replace.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/sync_update.png.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/src/assets/images/user_bg.png.js +4 -0
- package/dist/_virtual/jsencrypt.min.js +1 -1
- package/dist/{_vendor → frontend/frame/_vendor}/.pnpm/jsencrypt@3.5.4/_vendor/jsencrypt/bin/jsencrypt.min.js +1 -1
- package/dist/src/ai-call-method-form.js +55 -0
- package/dist/src/asset-images.js +105 -105
- package/dist/src/wiki-path.js +111 -0
- package/package.json +1 -1
- package/src/ai-call-method-form.js +54 -0
- package/src/chart-registry.js +41 -41
- package/src/fieldFactory.js +3 -3
- package/src/index.js +2 -2
- package/src/legacy.js +29 -29
- package/src/meta.js +2 -2
- package/src/pdf.viewer.js +2 -2
- package/src/public.js +11 -11
- package/src/util.js +2 -2
- package/src/wiki-path.js +164 -0
- package/dist/src/assets/images/ai.png.js +0 -4
- package/dist/src/assets/images/ai_import.png.js +0 -4
- package/dist/src/assets/images/app.png.js +0 -4
- package/dist/src/assets/images/approval.png.js +0 -4
- package/dist/src/assets/images/canvas-editor/option.svg.js +0 -4
- package/dist/src/assets/images/create_market_system.png.js +0 -4
- package/dist/src/assets/images/create_system.png.js +0 -4
- package/dist/src/assets/images/custom.png.js +0 -4
- package/dist/src/assets/images/default-icon.png.js +0 -4
- package/dist/src/assets/images/ex_link.png.js +0 -4
- package/dist/src/assets/images/excel.png.js +0 -4
- package/dist/src/assets/images/folder.png.js +0 -4
- package/dist/src/assets/images/hall/form.png.js +0 -4
- package/dist/src/assets/images/hall/meta.png.js +0 -4
- package/dist/src/assets/images/hall/process.png.js +0 -4
- package/dist/src/assets/images/hall/rule.png.js +0 -4
- package/dist/src/assets/images/hall/service.png.js +0 -4
- package/dist/src/assets/images/hall/userRole.png.js +0 -4
- package/dist/src/assets/images/import.png.js +0 -4
- package/dist/src/assets/images/module.png.js +0 -4
- package/dist/src/assets/images/null.png.js +0 -4
- package/dist/src/assets/images/photo.png.js +0 -4
- package/dist/src/assets/images/single_file.png.js +0 -4
- package/dist/src/assets/images/snapshot-history.png.js +0 -4
- package/dist/src/assets/images/snapshot-manual.png.js +0 -4
- package/dist/src/assets/images/snapshot-realtime.png.js +0 -4
- package/dist/src/assets/images/staff.png.js +0 -4
- package/dist/src/assets/images/sync_append.png.js +0 -4
- package/dist/src/assets/images/sync_append_update.png.js +0 -4
- package/dist/src/assets/images/sync_loading.png.js +0 -4
- package/dist/src/assets/images/sync_replace.png.js +0 -4
- package/dist/src/assets/images/sync_update.png.js +0 -4
- package/dist/src/assets/images/user_bg.png.js +0 -4
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/add.png.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/ai-button.png.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/book.png.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/alignment.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/arrow-left.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/arrow-right.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/block.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/bold.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/catalog.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/center.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/checkbox.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/close.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/codeblock.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/color.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/control.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/date.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/exit-fullscreen.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/format.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/highlight.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/hyperlink.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/image.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/italic.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/justify.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/latex.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/left.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/line-dash-dot-dot.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/line-dash-dot.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/line-dash-large-gap.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/line-dash-small-gap.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/line-dot.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/line-double.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/line-single.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/line-wavy.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/list.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/page-break.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/page-mode.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/page-scale-add.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/page-scale-minus.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/painter.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/paper-direction.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/paper-margin.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/paper-size.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/print.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/radio.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/redo.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/request-fullscreen.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/right.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/row-margin.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/search.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/separator.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/signature-undo.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/signature.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/size-add.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/size-minus.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/strikeout.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/subscript.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/superscript.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/table.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/title.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/trash.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/underline.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/undo.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/watermark.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/canvas-editor/word-tool.svg.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/clear.png.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/file.png.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/hr.png.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/jian.png.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/qq.png.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/robot.png.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/switch_app.png.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/assets/images/weixin.png.js +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
function splitAnchor(href) {
|
|
2
|
+
const s = String(href || "");
|
|
3
|
+
const i = s.indexOf("#");
|
|
4
|
+
return i < 0 ? { path: s, anchor: "" } : { path: s.slice(0, i), anchor: s.slice(i + 1) };
|
|
5
|
+
}
|
|
6
|
+
function isExternal(href) {
|
|
7
|
+
return /^(https?:)?\/\//i.test(String(href || "")) || /^(mailto|tel|data|javascript):/i.test(String(href || ""));
|
|
8
|
+
}
|
|
9
|
+
function pagePath(path) {
|
|
10
|
+
return decodePath(path).replace(/\\/g, "/").split("/").filter((seg) => seg && seg !== ".").join("/");
|
|
11
|
+
}
|
|
12
|
+
function resolvePath(fromPath, href) {
|
|
13
|
+
const split = splitAnchor(href);
|
|
14
|
+
const path = decodePath(split.path);
|
|
15
|
+
const anchor = decodeAnchor(split.anchor);
|
|
16
|
+
if (!path) return { path: pagePath(fromPath), anchor };
|
|
17
|
+
if (isExternal(path)) return { path: "", anchor: "" };
|
|
18
|
+
const abs = path.startsWith("/");
|
|
19
|
+
const baseDir = abs ? [] : String(fromPath || "").split("/").slice(0, -1);
|
|
20
|
+
const parts = abs ? [] : baseDir.slice();
|
|
21
|
+
for (const seg of path.replace(/^\//, "").split("/")) {
|
|
22
|
+
if (!seg || seg === ".") continue;
|
|
23
|
+
if (seg === "..") {
|
|
24
|
+
if (!parts.length) return { path: "", anchor: "" };
|
|
25
|
+
parts.pop();
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
parts.push(seg);
|
|
29
|
+
}
|
|
30
|
+
return { path: pagePath(parts.join("/")), anchor };
|
|
31
|
+
}
|
|
32
|
+
function siteUrl(route, path, anchor) {
|
|
33
|
+
const routePath = pagePath(path);
|
|
34
|
+
const out = {
|
|
35
|
+
name: route.name,
|
|
36
|
+
params: { ...route.params, path: routePath },
|
|
37
|
+
query: {}
|
|
38
|
+
};
|
|
39
|
+
if (route.name === "wikiView") {
|
|
40
|
+
out.query = { path: routePath };
|
|
41
|
+
if (route.query.w) out.query.w = route.query.w;
|
|
42
|
+
}
|
|
43
|
+
const contextKeys = ["mode", "from", "back"];
|
|
44
|
+
contextKeys.forEach((key) => {
|
|
45
|
+
if (route.query[key]) out.query[key] = route.query[key];
|
|
46
|
+
});
|
|
47
|
+
if (anchor) out.hash = "#" + anchor;
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
function chatPreviewRoute(route, wikiId, pageId, anchor) {
|
|
51
|
+
const query = {
|
|
52
|
+
w: wikiId,
|
|
53
|
+
mode: "preview",
|
|
54
|
+
from: "chat",
|
|
55
|
+
back: route.fullPath
|
|
56
|
+
};
|
|
57
|
+
if (pageId) query.p = pageId;
|
|
58
|
+
if (anchor) query.h = anchor;
|
|
59
|
+
const client = route.params.client;
|
|
60
|
+
if (client) {
|
|
61
|
+
delete query.w;
|
|
62
|
+
return { name: "wikiSite", params: { client, system: "epxing-frame", wiki: wikiId }, query };
|
|
63
|
+
}
|
|
64
|
+
return { name: "wikiView", query };
|
|
65
|
+
}
|
|
66
|
+
function restoreChatWikiRoute(route) {
|
|
67
|
+
if (route.name !== "wikiView" || route.query.from !== "chat" || !route.query.w) return null;
|
|
68
|
+
const back = route.query.back;
|
|
69
|
+
const match = typeof back === "string" && /^\/(?:app|hall)\/([\w-]+)(?:\/|\?|$)/.exec(back);
|
|
70
|
+
if (!match || match[1] === "role" || match[1] === "login") return null;
|
|
71
|
+
const { w, ...query } = route.query;
|
|
72
|
+
return {
|
|
73
|
+
name: "wikiSite",
|
|
74
|
+
params: { client: match[1], system: "epxing-frame", wiki: w },
|
|
75
|
+
query,
|
|
76
|
+
hash: route.hash,
|
|
77
|
+
replace: true
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function relativize(fromPath, toPath) {
|
|
81
|
+
const from = pagePath(fromPath).split("/").slice(0, -1);
|
|
82
|
+
const to = pagePath(toPath).split("/");
|
|
83
|
+
let common = 0;
|
|
84
|
+
while (common < from.length && common < to.length - 1 && from[common] === to[common]) common++;
|
|
85
|
+
const up = from.slice(common).map(() => "../").join("");
|
|
86
|
+
return up + to.slice(common).join("/");
|
|
87
|
+
}
|
|
88
|
+
function decodePath(value) {
|
|
89
|
+
try {
|
|
90
|
+
return decodeURI(String(value || ""));
|
|
91
|
+
} catch (e) {
|
|
92
|
+
return String(value || "");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function decodeAnchor(value) {
|
|
96
|
+
try {
|
|
97
|
+
return decodeURIComponent(String(value || ""));
|
|
98
|
+
} catch (e) {
|
|
99
|
+
return String(value || "");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export {
|
|
103
|
+
chatPreviewRoute,
|
|
104
|
+
isExternal,
|
|
105
|
+
pagePath,
|
|
106
|
+
relativize,
|
|
107
|
+
resolvePath,
|
|
108
|
+
restoreChatWikiRoute,
|
|
109
|
+
siteUrl,
|
|
110
|
+
splitAnchor
|
|
111
|
+
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// 通用填写页和开发者自定义页共用聊天提交契约,字段编码及关联标识来自方法配置。
|
|
2
|
+
export function createCallMethodInput (form, values) {
|
|
3
|
+
if (!form || !form.methodId || !form.draftId || !form.main) throw new Error('填写页面缺少方法或会话信息,请重新打开')
|
|
4
|
+
const scopeValues = (scope, data = {}) => {
|
|
5
|
+
const result = {}
|
|
6
|
+
scope.fields.forEach(field => {
|
|
7
|
+
const key = Object.prototype.hasOwnProperty.call(data, field.attriName) ? field.attriName : `bean.${field.attriName}`
|
|
8
|
+
if (!Object.prototype.hasOwnProperty.call(data, key)) return
|
|
9
|
+
let value = data[key]
|
|
10
|
+
if (value === '') value = null
|
|
11
|
+
if (value != null && ['int', 'order', 'num', 'currency'].includes(field.dataType)) {
|
|
12
|
+
value = Number(value)
|
|
13
|
+
if (!Number.isFinite(value)) throw new Error(`${field.attriLabel}必须是有效数字`)
|
|
14
|
+
}
|
|
15
|
+
if (value != null && field.dataType === 'switch') {
|
|
16
|
+
if ([true, '1', 1].includes(value)) value = true
|
|
17
|
+
else if ([false, '0', 0].includes(value)) value = false
|
|
18
|
+
else throw new Error(`${field.attriLabel}的开关值无效`)
|
|
19
|
+
}
|
|
20
|
+
result[field.attriName] = value
|
|
21
|
+
})
|
|
22
|
+
return result
|
|
23
|
+
}
|
|
24
|
+
const input = scopeValues(form.main, values)
|
|
25
|
+
const subEntitys = typeof values.subEntitys === 'string' ? JSON.parse(values.subEntitys) : (values.subEntitys || {})
|
|
26
|
+
for (const relation of form.relations || []) {
|
|
27
|
+
let data = values[relation.flag]
|
|
28
|
+
if (data === undefined) {
|
|
29
|
+
const key = Object.keys(subEntitys).find(key => key.toUpperCase() === relation.flag.toUpperCase())
|
|
30
|
+
if (key) data = subEntitys[key]
|
|
31
|
+
}
|
|
32
|
+
if (!relation.many && data === undefined) {
|
|
33
|
+
const prefix = `${relation.flag.toUpperCase()}|`
|
|
34
|
+
const fields = Object.entries(values).map(([key, value]) => [key.replace(/^bean\./, ''), value]).filter(([key]) => key.toUpperCase().startsWith(prefix))
|
|
35
|
+
if (fields.length) data = Object.fromEntries(fields.map(([key, value]) => [key.substring(prefix.length), value]))
|
|
36
|
+
}
|
|
37
|
+
if (data === undefined || data === null) continue
|
|
38
|
+
if (relation.many) {
|
|
39
|
+
if (!Array.isArray(data)) throw new Error(`${relation.title}应为对象列表`)
|
|
40
|
+
input[relation.flag] = data.filter(row => row.operateType !== 'delete').map(row => scopeValues(relation.scope, row))
|
|
41
|
+
} else {
|
|
42
|
+
if (typeof data !== 'object' || Array.isArray(data)) throw new Error(`${relation.title}应为对象`)
|
|
43
|
+
input[relation.flag] = scopeValues(relation.scope, data)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { __finalize__: true, __callMethodCreate__: { methodId: form.methodId, draftId: form.draftId, values: input } }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// sendMessage返回false表示聊天仍忙,调用方应保留表单内容并允许稍后再提交。
|
|
50
|
+
export function submitCallMethodForm (session, form, values) {
|
|
51
|
+
if (!session || typeof session.sendMessage !== 'function') throw new Error('当前页面未连接聊天会话')
|
|
52
|
+
const inputParam = createCallMethodInput(form, values)
|
|
53
|
+
return session.sendMessage(`确认提交${form.name || '新增信息'}`, null, { inputParam })
|
|
54
|
+
}
|
package/src/chart-registry.js
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
// Shared metadata; persisted type names and backend request types retain their existing meaning.
|
|
2
|
-
export const chartTypes = [
|
|
3
|
-
{ type: 'table', text: '统计表', icon: 'epx-icon-tongjibiao', component: 'chart-table', requestType: 'table', coordinate: 'none' },
|
|
4
|
-
{ type: 'pie', text: '饼状图', icon: 'epx-icon-bingzhuangtu', component: 'chart-common', requestType: 'pie', coordinate: 'none' },
|
|
5
|
-
{ type: 'circularPie', text: '环形饼图', icon: 'epx-icon-bingzhuangtu', component: 'chart-common', requestType: 'pie', coordinate: 'none' },
|
|
6
|
-
{ type: 'line', text: '折线图', icon: 'epx-icon-zhexiantu', component: 'chart-common', requestType: 'line', coordinate: 'cartesian2d' },
|
|
7
|
-
{ type: 'column', text: '柱状图', icon: 'epx-icon-zhuzhuangtu', component: 'chart-common', requestType: 'bar', coordinate: 'cartesian2d' },
|
|
8
|
-
{ type: 'horiColumn', text: '横向柱图', icon: 'epx-icon-zhuzhuangtu', component: 'chart-common', requestType: 'bar', cellScopeType: 'column', coordinate: 'cartesian2d' },
|
|
9
|
-
{ type: 'funnel', text: '漏斗图', icon: 'epx-icon-loudoutu', component: 'chart-common', requestType: 'funnel', coordinate: 'none' },
|
|
10
|
-
{ type: 'wordcloud', text: '词云', icon: 'epx-icon-ciyun', component: 'chart-wordcloud', requestType: 'wordCloud', coordinate: 'none' },
|
|
11
|
-
{ type: 'radar', text: '雷达图', icon: 'epx-icon-leidatu', component: 'chart-radar', requestType: 'radar', coordinate: 'radar' },
|
|
12
|
-
{ type: 'columnAndLine', text: '折柱混合', icon: 'epx-icon-zhezhutu', component: 'chart-common', requestType: 'bar', coordinate: 'cartesian2d' },
|
|
13
|
-
{ type: 'scatter', text: '散点图', icon: 'epx-icon-sandiantu', component: 'chart-scatter', requestType: 'scatter', coordinate: 'cartesian2d', binding: 'numericPairs', drill: false },
|
|
14
|
-
{ type: 'map', text: '地图', icon: 'epx-icon-ditu', component: 'chart-map', requestType: 'map', coordinate: 'geo' },
|
|
15
|
-
{ type: 'gauge', text: '仪表盘', icon: 'epx-icon-leidatu', component: 'chart-advanced', requestType: 'bar', cellScopeType: 'column', coordinate: 'none', dataHint: '单个统计值;设置一个指标且不拆分分类。' },
|
|
16
|
-
{ type: 'treemap', text: '矩形树图', icon: 'epx-icon-tongjibiao', component: 'chart-advanced', requestType: 'bar', cellScopeType: 'column', coordinate: 'none', dataHint: '按指标、分类组成两层矩形树,使用非负统计值;叶子支持钻取。' },
|
|
17
|
-
{ type: 'heatmap', text: '热力图', icon: 'epx-icon-zhuzhuangtu', component: 'chart-advanced', requestType: 'bar', cellScopeType: 'column', coordinate: 'cartesian2d', dataHint: '横轴为分类,纵轴为指标;各指标使用同一组分类。' },
|
|
18
|
-
{ type: 'boxplot', text: '箱线图', selectable: false, icon: 'epx-icon-zhexiantu', component: 'chart-advanced', requestType: 'scatter', coordinate: 'cartesian2d', binding: 'numericPairs', drill: false, dataHint: '选择两个数字统计字段,不设置分类;使用原始值计算四分位数与 1.5 倍四分位距的离群值,不支持钻取。' }
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
-
export const selectableChartTypes = chartTypes.filter(item => item.selectable !== false)
|
|
22
|
-
|
|
23
|
-
export function getChartType (type) {
|
|
24
|
-
return chartTypes.find(item => item.type === (type === 'bar' ? 'column' : type))
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const chartConfigCategories = [
|
|
28
|
-
{ key: 'all', label: '全部' },
|
|
29
|
-
{ key: 'appearance', label: '外观' }, { key: 'axis', label: '坐标与刻度' },
|
|
30
|
-
{ key: 'shape', label: '图形' }, { key: 'label', label: '标签与提示' },
|
|
31
|
-
{ key: 'interaction', label: '交互' }, { key: 'advanced', label: '高级' }
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
export function getChartConfigCategory (key) {
|
|
35
|
-
if (['title', 'grid', 'color', 'backgroundColor'].includes(key)) return 'appearance'
|
|
36
|
-
if (['xAxis', 'yAxis', 'dualAxes', 'dataZoom'].includes(key)) return 'axis'
|
|
37
|
-
if (key.startsWith('series-') || ['series.map', 'radar', 'scatter', 'table', 'visualMap'].includes(key)) return 'shape'
|
|
38
|
-
if (['legend', 'tooltip'].includes(key)) return 'label'
|
|
39
|
-
if (key === 'toolbox') return 'interaction'
|
|
40
|
-
return 'advanced'
|
|
41
|
-
}
|
|
1
|
+
// Shared metadata; persisted type names and backend request types retain their existing meaning.
|
|
2
|
+
export const chartTypes = [
|
|
3
|
+
{ type: 'table', text: '统计表', icon: 'epx-icon-tongjibiao', component: 'chart-table', requestType: 'table', coordinate: 'none' },
|
|
4
|
+
{ type: 'pie', text: '饼状图', icon: 'epx-icon-bingzhuangtu', component: 'chart-common', requestType: 'pie', coordinate: 'none' },
|
|
5
|
+
{ type: 'circularPie', text: '环形饼图', icon: 'epx-icon-bingzhuangtu', component: 'chart-common', requestType: 'pie', coordinate: 'none' },
|
|
6
|
+
{ type: 'line', text: '折线图', icon: 'epx-icon-zhexiantu', component: 'chart-common', requestType: 'line', coordinate: 'cartesian2d' },
|
|
7
|
+
{ type: 'column', text: '柱状图', icon: 'epx-icon-zhuzhuangtu', component: 'chart-common', requestType: 'bar', coordinate: 'cartesian2d' },
|
|
8
|
+
{ type: 'horiColumn', text: '横向柱图', icon: 'epx-icon-zhuzhuangtu', component: 'chart-common', requestType: 'bar', cellScopeType: 'column', coordinate: 'cartesian2d' },
|
|
9
|
+
{ type: 'funnel', text: '漏斗图', icon: 'epx-icon-loudoutu', component: 'chart-common', requestType: 'funnel', coordinate: 'none' },
|
|
10
|
+
{ type: 'wordcloud', text: '词云', icon: 'epx-icon-ciyun', component: 'chart-wordcloud', requestType: 'wordCloud', coordinate: 'none' },
|
|
11
|
+
{ type: 'radar', text: '雷达图', icon: 'epx-icon-leidatu', component: 'chart-radar', requestType: 'radar', coordinate: 'radar' },
|
|
12
|
+
{ type: 'columnAndLine', text: '折柱混合', icon: 'epx-icon-zhezhutu', component: 'chart-common', requestType: 'bar', coordinate: 'cartesian2d' },
|
|
13
|
+
{ type: 'scatter', text: '散点图', icon: 'epx-icon-sandiantu', component: 'chart-scatter', requestType: 'scatter', coordinate: 'cartesian2d', binding: 'numericPairs', drill: false },
|
|
14
|
+
{ type: 'map', text: '地图', icon: 'epx-icon-ditu', component: 'chart-map', requestType: 'map', coordinate: 'geo' },
|
|
15
|
+
{ type: 'gauge', text: '仪表盘', icon: 'epx-icon-leidatu', component: 'chart-advanced', requestType: 'bar', cellScopeType: 'column', coordinate: 'none', dataHint: '单个统计值;设置一个指标且不拆分分类。' },
|
|
16
|
+
{ type: 'treemap', text: '矩形树图', icon: 'epx-icon-tongjibiao', component: 'chart-advanced', requestType: 'bar', cellScopeType: 'column', coordinate: 'none', dataHint: '按指标、分类组成两层矩形树,使用非负统计值;叶子支持钻取。' },
|
|
17
|
+
{ type: 'heatmap', text: '热力图', icon: 'epx-icon-zhuzhuangtu', component: 'chart-advanced', requestType: 'bar', cellScopeType: 'column', coordinate: 'cartesian2d', dataHint: '横轴为分类,纵轴为指标;各指标使用同一组分类。' },
|
|
18
|
+
{ type: 'boxplot', text: '箱线图', selectable: false, icon: 'epx-icon-zhexiantu', component: 'chart-advanced', requestType: 'scatter', coordinate: 'cartesian2d', binding: 'numericPairs', drill: false, dataHint: '选择两个数字统计字段,不设置分类;使用原始值计算四分位数与 1.5 倍四分位距的离群值,不支持钻取。' }
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
export const selectableChartTypes = chartTypes.filter(item => item.selectable !== false)
|
|
22
|
+
|
|
23
|
+
export function getChartType (type) {
|
|
24
|
+
return chartTypes.find(item => item.type === (type === 'bar' ? 'column' : type))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const chartConfigCategories = [
|
|
28
|
+
{ key: 'all', label: '全部' },
|
|
29
|
+
{ key: 'appearance', label: '外观' }, { key: 'axis', label: '坐标与刻度' },
|
|
30
|
+
{ key: 'shape', label: '图形' }, { key: 'label', label: '标签与提示' },
|
|
31
|
+
{ key: 'interaction', label: '交互' }, { key: 'advanced', label: '高级' }
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
export function getChartConfigCategory (key) {
|
|
35
|
+
if (['title', 'grid', 'color', 'backgroundColor'].includes(key)) return 'appearance'
|
|
36
|
+
if (['xAxis', 'yAxis', 'dualAxes', 'dataZoom'].includes(key)) return 'axis'
|
|
37
|
+
if (key.startsWith('series-') || ['series.map', 'radar', 'scatter', 'table', 'visualMap'].includes(key)) return 'shape'
|
|
38
|
+
if (['legend', 'tooltip'].includes(key)) return 'label'
|
|
39
|
+
if (key === 'toolbox') return 'interaction'
|
|
40
|
+
return 'advanced'
|
|
41
|
+
}
|
package/src/fieldFactory.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
// 兼容旧路径;新代码从 @epxing/core 导入。
|
|
2
|
-
export { default } from '@epxing/core/src/runtime-utils/fieldFactory'
|
|
3
|
-
export * from '@epxing/core/src/runtime-utils/fieldFactory'
|
|
1
|
+
// 兼容旧路径;新代码从 @epxing/core 导入。
|
|
2
|
+
export { default } from '@epxing/core/src/runtime-utils/fieldFactory'
|
|
3
|
+
export * from '@epxing/core/src/runtime-utils/fieldFactory'
|
package/src/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// 保留历史 /src barrel;新产品从 @epxing/utils 导入纯工具。
|
|
2
|
-
export * from './legacy'
|
|
1
|
+
// 保留历史 /src barrel;新产品从 @epxing/utils 导入纯工具。
|
|
2
|
+
export * from './legacy'
|
package/src/legacy.js
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import util from '@epxing/core/src/runtime-utils/util'
|
|
2
|
-
// axios / mixins 已随 T17 迁 @epxing/core;barrel 暂经相对路径引用真身保持导出面不变(T23 收敛 barrel)
|
|
3
|
-
// ADR-009:跨包引用必须用裸说明符(单包构建外置为 @epxing/core 依赖;相对路径会把 core 打进 utils 产物)
|
|
4
|
-
import axios from '@epxing/core/src/axios'
|
|
5
|
-
import Config from './Config'
|
|
6
|
-
import FieldFactory from '@epxing/core/src/runtime-utils/fieldFactory'
|
|
7
|
-
import Meta from '@epxing/core/src/runtime-utils/meta'
|
|
8
|
-
import Page from './page'
|
|
9
|
-
import http from '@epxing/core/src/api'
|
|
10
|
-
import mixin from '@epxing/core/src/mixins/global'
|
|
11
|
-
// import router from '@epxing/core/src/router'
|
|
12
|
-
import PdfViewer from '@epxing/core/src/runtime-utils/pdf.viewer'
|
|
13
|
-
// 统一的 #{path} 占位符解析(见 placeholder.js 头注释:存量有 8 种不同语义的复制品)
|
|
14
|
-
import placeholder from './placeholder'
|
|
15
|
-
const pdfViewer = new PdfViewer()
|
|
16
|
-
export {
|
|
17
|
-
axios,
|
|
18
|
-
Config,
|
|
19
|
-
FieldFactory,
|
|
20
|
-
Meta,
|
|
21
|
-
Page,
|
|
22
|
-
util,
|
|
23
|
-
http,
|
|
24
|
-
mixin,
|
|
25
|
-
// router,
|
|
26
|
-
PdfViewer,
|
|
27
|
-
pdfViewer,
|
|
28
|
-
placeholder
|
|
29
|
-
}
|
|
1
|
+
import util from '@epxing/core/src/runtime-utils/util'
|
|
2
|
+
// axios / mixins 已随 T17 迁 @epxing/core;barrel 暂经相对路径引用真身保持导出面不变(T23 收敛 barrel)
|
|
3
|
+
// ADR-009:跨包引用必须用裸说明符(单包构建外置为 @epxing/core 依赖;相对路径会把 core 打进 utils 产物)
|
|
4
|
+
import axios from '@epxing/core/src/axios'
|
|
5
|
+
import Config from './Config'
|
|
6
|
+
import FieldFactory from '@epxing/core/src/runtime-utils/fieldFactory'
|
|
7
|
+
import Meta from '@epxing/core/src/runtime-utils/meta'
|
|
8
|
+
import Page from './page'
|
|
9
|
+
import http from '@epxing/core/src/api'
|
|
10
|
+
import mixin from '@epxing/core/src/mixins/global'
|
|
11
|
+
// import router from '@epxing/core/src/router'
|
|
12
|
+
import PdfViewer from '@epxing/core/src/runtime-utils/pdf.viewer'
|
|
13
|
+
// 统一的 #{path} 占位符解析(见 placeholder.js 头注释:存量有 8 种不同语义的复制品)
|
|
14
|
+
import placeholder from './placeholder'
|
|
15
|
+
const pdfViewer = new PdfViewer()
|
|
16
|
+
export {
|
|
17
|
+
axios,
|
|
18
|
+
Config,
|
|
19
|
+
FieldFactory,
|
|
20
|
+
Meta,
|
|
21
|
+
Page,
|
|
22
|
+
util,
|
|
23
|
+
http,
|
|
24
|
+
mixin,
|
|
25
|
+
// router,
|
|
26
|
+
PdfViewer,
|
|
27
|
+
pdfViewer,
|
|
28
|
+
placeholder
|
|
29
|
+
}
|
package/src/meta.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// 兼容旧路径;新代码从 @epxing/core 导入。
|
|
2
|
-
export { default } from '@epxing/core/src/runtime-utils/meta'
|
|
1
|
+
// 兼容旧路径;新代码从 @epxing/core 导入。
|
|
2
|
+
export { default } from '@epxing/core/src/runtime-utils/meta'
|
package/src/pdf.viewer.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// 兼容旧路径;新代码从 @epxing/core 导入。
|
|
2
|
-
export { default } from '@epxing/core/src/runtime-utils/pdf.viewer'
|
|
1
|
+
// 兼容旧路径;新代码从 @epxing/core 导入。
|
|
2
|
+
export { default } from '@epxing/core/src/runtime-utils/pdf.viewer'
|
package/src/public.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export { default as Config } from './Config'
|
|
2
|
-
export { default as Page } from './page'
|
|
3
|
-
export { default as placeholder } from './placeholder'
|
|
4
|
-
export * from './placeholder'
|
|
5
|
-
export * from './date-helper'
|
|
6
|
-
export * from './dom-helper'
|
|
7
|
-
export { default as storage, getXsrfToken, setXsrfToken } from './storage'
|
|
8
|
-
export { default as cookie } from './storage'
|
|
9
|
-
export { default as moment, default as dateTime, createMoment } from './moment-compat'
|
|
10
|
-
export { default as lodash } from './collection'
|
|
11
|
-
export * from './collection'
|
|
1
|
+
export { default as Config } from './Config'
|
|
2
|
+
export { default as Page } from './page'
|
|
3
|
+
export { default as placeholder } from './placeholder'
|
|
4
|
+
export * from './placeholder'
|
|
5
|
+
export * from './date-helper'
|
|
6
|
+
export * from './dom-helper'
|
|
7
|
+
export { default as storage, getXsrfToken, setXsrfToken } from './storage'
|
|
8
|
+
export { default as cookie } from './storage'
|
|
9
|
+
export { default as moment, default as dateTime, createMoment } from './moment-compat'
|
|
10
|
+
export { default as lodash } from './collection'
|
|
11
|
+
export * from './collection'
|
package/src/util.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// 兼容旧路径;新代码从 @epxing/core 导入。
|
|
2
|
-
export { default } from '@epxing/core/src/runtime-utils/util'
|
|
1
|
+
// 兼容旧路径;新代码从 @epxing/core 导入。
|
|
2
|
+
export { default } from '@epxing/core/src/runtime-utils/util'
|
package/src/wiki-path.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki 路径工具。
|
|
3
|
+
*
|
|
4
|
+
* 规则必须与后端 `WikiPaths` 一致:正文里的相对链接是作者按目录写的,
|
|
5
|
+
* 两边解析口径不同就会出现「后端认得、前端点不开」,而这正是这套设计要消灭的问题。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** 拆出锚点。 */
|
|
9
|
+
export function splitAnchor (href) {
|
|
10
|
+
const s = String(href || '')
|
|
11
|
+
const i = s.indexOf('#')
|
|
12
|
+
return i < 0 ? { path: s, anchor: '' } : { path: s.slice(0, i), anchor: s.slice(i + 1) }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** 外链不参与站内解析。 */
|
|
16
|
+
export function isExternal (href) {
|
|
17
|
+
return /^(https?:)?\/\//i.test(String(href || '')) ||
|
|
18
|
+
/^(mailto|tel|data|javascript):/i.test(String(href || ''))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** 页表与接口使用 Store 的规范页标识;这里只解码并统一分隔符,不猜扩展名。 */
|
|
22
|
+
export function pagePath (path) {
|
|
23
|
+
return decodePath(path)
|
|
24
|
+
.replace(/\\/g, '/')
|
|
25
|
+
.split('/')
|
|
26
|
+
.filter(seg => seg && seg !== '.')
|
|
27
|
+
.join('/')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 相对链接 → 站内绝对路径。
|
|
32
|
+
*
|
|
33
|
+
* `../` 必须真的回退一级,不能只做字符串拼接——后端曾经就栽在这里:
|
|
34
|
+
* 规范化时保留了 `../`,导致 `../implementation/05-sop.md` 永远匹配不上任何页。
|
|
35
|
+
*/
|
|
36
|
+
export function resolvePath (fromPath, href) {
|
|
37
|
+
const split = splitAnchor(href)
|
|
38
|
+
const path = decodePath(split.path)
|
|
39
|
+
const anchor = decodeAnchor(split.anchor)
|
|
40
|
+
if (!path) return { path: pagePath(fromPath), anchor }
|
|
41
|
+
if (isExternal(path)) return { path: '', anchor: '' }
|
|
42
|
+
|
|
43
|
+
const abs = path.startsWith('/')
|
|
44
|
+
const baseDir = abs ? [] : String(fromPath || '').split('/').slice(0, -1)
|
|
45
|
+
const parts = abs ? [] : baseDir.slice()
|
|
46
|
+
|
|
47
|
+
for (const seg of path.replace(/^\//, '').split('/')) {
|
|
48
|
+
if (!seg || seg === '.') continue
|
|
49
|
+
if (seg === '..') {
|
|
50
|
+
if (!parts.length) return { path: '', anchor: '' }
|
|
51
|
+
parts.pop()
|
|
52
|
+
continue
|
|
53
|
+
}
|
|
54
|
+
parts.push(seg)
|
|
55
|
+
}
|
|
56
|
+
return { path: pagePath(parts.join('/')), anchor }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 站点地址:`#/wiki/{客户}/{系统}/{空间}/{页路径}`,锚点挂 hash。
|
|
61
|
+
*
|
|
62
|
+
* 保留当前路由的前三段而不是自己拼——客户与系统段是权限边界的一部分,
|
|
63
|
+
* 在前端重新组装容易拼错,也容易被人改成别的租户去试。
|
|
64
|
+
*/
|
|
65
|
+
export function siteUrl (route, path, anchor) {
|
|
66
|
+
const routePath = pagePath(path)
|
|
67
|
+
const out = {
|
|
68
|
+
name: route.name,
|
|
69
|
+
params: { ...route.params, path: routePath },
|
|
70
|
+
query: {}
|
|
71
|
+
}
|
|
72
|
+
if (route.name === 'wikiView') {
|
|
73
|
+
// `/wiki/view` 这条路由没有路径段,params.path 落不到地址里。
|
|
74
|
+
// 不管用这一点会一口气错三样:地址栏始终是同一个 `#/wiki/view`,
|
|
75
|
+
// 刷新读不回当前页,浏览器历史里堆的全是同一条、返回看着像没反应。
|
|
76
|
+
// 所以这条路由上换页走 query,并且必须把 `w`(空间)原样带上:
|
|
77
|
+
// 丢了它,下一次读页就没有空间 ID,后端只能报「页不存在」——看着像页被删了。
|
|
78
|
+
out.query = { path: routePath }
|
|
79
|
+
if (route.query.w) out.query.w = route.query.w
|
|
80
|
+
// p / rev / h 属于那一条引用(冻结在某一版),换到别的页之后就不成立了,
|
|
81
|
+
// 留着会让 syncFromRoute 继续按引用读,点哪一页都回到引用那一页。
|
|
82
|
+
}
|
|
83
|
+
// 两种站点路由换页都必须保留预览模式和返回地址。
|
|
84
|
+
const contextKeys = ['mode', 'from', 'back']
|
|
85
|
+
contextKeys.forEach(key => {
|
|
86
|
+
if (route.query[key]) out.query[key] = route.query[key]
|
|
87
|
+
})
|
|
88
|
+
if (anchor) out.hash = '#' + anchor
|
|
89
|
+
return out
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 从聊天页打开 Wiki 的统一入口。
|
|
94
|
+
*
|
|
95
|
+
* `mode=preview` 决定能力边界,`from/back` 只决定返回去向。两者分开后,分享链接可以
|
|
96
|
+
* 去掉聊天会话地址但继续保持只读,不会把分享接收者送进发起人的聊天路由。
|
|
97
|
+
*/
|
|
98
|
+
export function chatPreviewRoute (route, wikiId, pageId, anchor) {
|
|
99
|
+
const query = {
|
|
100
|
+
w: wikiId,
|
|
101
|
+
mode: 'preview',
|
|
102
|
+
from: 'chat',
|
|
103
|
+
back: route.fullPath
|
|
104
|
+
}
|
|
105
|
+
if (pageId) query.p = pageId
|
|
106
|
+
if (anchor) query.h = anchor
|
|
107
|
+
const client = route.params.client
|
|
108
|
+
// 新窗口没有聊天页的 Vuex 上下文,必须把租户写进地址。
|
|
109
|
+
// Wiki 属于该租户的平台系统,与聊天智能体所在的业务系统无关。
|
|
110
|
+
if (client) {
|
|
111
|
+
delete query.w
|
|
112
|
+
return { name: 'wikiSite', params: { client, system: 'epxing-frame', wiki: wikiId }, query }
|
|
113
|
+
}
|
|
114
|
+
return { name: 'wikiView', query }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** 兼容旧聊天链接:在加载应用配置之前,恢复 back 中明确携带的租户。 */
|
|
118
|
+
export function restoreChatWikiRoute (route) {
|
|
119
|
+
if (route.name !== 'wikiView' || route.query.from !== 'chat' || !route.query.w) return null
|
|
120
|
+
const back = route.query.back
|
|
121
|
+
const match = typeof back === 'string' && /^\/(?:app|hall)\/([\w-]+)(?:\/|\?|$)/.exec(back)
|
|
122
|
+
if (!match || match[1] === 'role' || match[1] === 'login') return null
|
|
123
|
+
const { w, ...query } = route.query
|
|
124
|
+
return {
|
|
125
|
+
name: 'wikiSite',
|
|
126
|
+
params: { client: match[1], system: 'epxing-frame', wiki: w },
|
|
127
|
+
query,
|
|
128
|
+
hash: route.hash,
|
|
129
|
+
replace: true
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 绝对路径 → 从某一页看过去的相对链接。与后端 `WikiPaths.relativize` 同一套规则。
|
|
135
|
+
*
|
|
136
|
+
* 手写相对路径是死链的头号来源——数错一层 `../` 就指到不存在的地方,
|
|
137
|
+
* 而写的时候看不出来,要等体检或者别人点开才发现。所以内链一律由平台算好、只允许从选择器选。
|
|
138
|
+
*
|
|
139
|
+
* 结果保留目标页的 Store 规范标识:无扩展名、`.md`、`.html` 都不在前端改写。
|
|
140
|
+
*/
|
|
141
|
+
export function relativize (fromPath, toPath) {
|
|
142
|
+
const from = pagePath(fromPath).split('/').slice(0, -1)
|
|
143
|
+
const to = pagePath(toPath).split('/')
|
|
144
|
+
let common = 0
|
|
145
|
+
while (common < from.length && common < to.length - 1 && from[common] === to[common]) common++
|
|
146
|
+
const up = from.slice(common).map(() => '../').join('')
|
|
147
|
+
return up + to.slice(common).join('/')
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function decodePath (value) {
|
|
151
|
+
try {
|
|
152
|
+
return decodeURI(String(value || ''))
|
|
153
|
+
} catch (e) {
|
|
154
|
+
return String(value || '')
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function decodeAnchor (value) {
|
|
159
|
+
try {
|
|
160
|
+
return decodeURIComponent(String(value || ''))
|
|
161
|
+
} catch (e) {
|
|
162
|
+
return String(value || '')
|
|
163
|
+
}
|
|
164
|
+
}
|