@oj-module/cli 0.2.68 → 0.2.71
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/devkit/README.md +10 -8
- package/devkit/framework-dev.md +1 -1
- package/devkit/manual.md +45 -19
- package/devkit/module-dev-and-cdn-playground.md +20 -14
- package/devkit/publish-walkthrough.md +132 -43
- package/devkit/wecom-customer-reauth-guide.md +110 -0
- package/package.json +2 -2
- package/shell-dist/assets/{runtime.1xzahckt10.js → runtime.7x99hmm020.js} +2 -2
- package/shell-dist/bundles/oj-market-0.2.0.tgz +0 -0
- package/shell-dist/bundles/oj-market-0.2.0.tgz.sig +8 -0
- package/shell-dist/index.html +4 -4
- package/shell-dist/versions.json +3 -3
- package/src/__tests__/list.test.ts +7 -7
- package/src/__tests__/oj-health-host.test.ts +19 -0
- package/src/__tests__/site-tenant-header.test.ts +2 -2
- package/src/__tests__/templates-builtin-list.test.ts +47 -0
- package/src/__tests__/templates-schema-columns.test.ts +11 -2
- package/src/__tests__/templates-tenant-scope.test.ts +2 -3
- package/src/__tests__/users-roles-display.test.ts +84 -0
- package/src/bundle.ts +1 -1
- package/src/contract/__tests__/market-client.integration.test.ts +23 -22
- package/src/enable.ts +2 -2
- package/src/init.ts +45 -0
- package/src/install.ts +5 -5
- package/src/lifecycle/__tests__/install.test.ts +29 -29
- package/src/lifecycle/__tests__/market-bundle.test.ts +87 -0
- package/src/lifecycle/__tests__/publish.test.ts +8 -10
- package/src/lifecycle/__tests__/trust.test.ts +14 -14
- package/src/lifecycle/__tests__/uninstall.test.ts +4 -4
- package/src/list.ts +3 -3
- package/src/market/__tests__/bootstrap.test.ts +24 -7
- package/src/market/__tests__/failure-playbook.test.ts +0 -1
- package/src/market/__tests__/remote-push.test.ts +228 -0
- package/src/market/__tests__/verify.test.ts +45 -207
- package/src/market/bootstrap.ts +12 -7
- package/src/market/command.ts +33 -35
- package/src/market/db-seed.ts +129 -0
- package/src/market/failure-playbook.ts +3 -9
- package/src/market/fixture.ts +2 -6
- package/src/market/publish.ts +145 -89
- package/src/market/remote-push.ts +236 -0
- package/src/market/trial.ts +2 -2
- package/src/market/verify.ts +17 -270
- package/src/market/walkthrough.ts +38 -63
- package/src/oj.ts +13 -2
- package/src/preview.ts +5 -3
- package/src/publish.ts +3 -2
- package/src/scaffold-guard.ts +4 -0
- package/src/site.ts +1 -1
- package/src/trust.ts +8 -8
- package/src/uninstall.ts +2 -2
- package/src/usage.ts +23 -21
- package/templates/config.yaml +22 -3
- package/templates/global.d.ts +6 -4
- package/templates/init.include.yaml +16 -11
- package/templates/openapi.json +3971 -3663
- package/templates/src/.ojm-builtin.json +13 -0
- package/templates/src/README.md +5 -2
- package/templates/src/app/api/_platform/README.md +3 -2
- package/templates/src/app/api/_platform/_lifecycle/atomic.ts +7 -2
- package/templates/src/app/api/_platform/_lifecycle/bundle-converge.ts +158 -0
- package/templates/src/app/api/_platform/_lifecycle/history.ts +3 -2
- package/templates/src/app/api/_platform/_lifecycle/installer.ts +25 -5
- package/templates/src/app/api/_platform/_lifecycle/local-archive.ts +61 -0
- package/templates/src/app/api/_platform/_lifecycle/manifest-of-upload.ts +62 -0
- package/templates/src/app/api/_platform/_lifecycle/steps/preflight.ts +12 -2
- package/templates/src/app/api/_platform/_lifecycle/steps/reload.ts +4 -1
- package/templates/src/app/api/_platform/_lifecycle/steps/smoke.ts +8 -2
- package/templates/src/app/api/_platform/_lifecycle/types.ts +1 -1
- package/templates/src/app/api/_platform/_lifecycle/uninstall.ts +14 -5
- package/templates/src/app/api/_platform/_shared/service/domain/users.ts +7 -1
- package/templates/src/app/api/_platform/_shared/site-facade.ts +31 -0
- package/templates/src/app/api/_platform/manifest.yaml +1 -2
- package/templates/src/app/api/_platform/migrations/0003__market_catalog.mysql.sql +6 -0
- package/templates/src/app/api/_platform/migrations/0003__market_catalog.pg.sql +6 -0
- package/templates/src/app/api/_platform/migrations/0003__market_catalog.sql +18 -0
- package/templates/src/app/api/_platform/migrations/0004__market_drop_source_seq.mysql.sql +6 -0
- package/templates/src/app/api/_platform/migrations/0004__market_drop_source_seq.pg.sql +6 -0
- package/templates/src/app/api/_platform/migrations/0004__market_drop_source_seq.sql +6 -0
- package/templates/src/app/api/_platform/migrations/0005__market_sig_registry.mysql.sql +8 -0
- package/templates/src/app/api/_platform/migrations/0005__market_sig_registry.pg.sql +8 -0
- package/templates/src/app/api/_platform/migrations/0005__market_sig_registry.sql +8 -0
- package/templates/src/app/api/_platform/schema.yaml +8 -11
- package/templates/src/app/api/_platform/seed.mysql.sql +1 -1
- package/templates/src/app/api/_platform/seed.pg.sql +1 -1
- package/templates/src/app/api/_platform/seed.sql +1 -1
- package/templates/src/app/api/auth/_shared/wecom/sync.ts +6 -0
- package/templates/src/app/api/system/users/api.ts +3 -0
- package/templates/src/app/web/_platform/__client/api.schemas.ts +0 -113
- package/templates/src/app/web/_platform/__client/index.ts +1 -333
- package/templates/src/app/web/system/__client/api.schemas.ts +2 -0
- package/templates/src/app/web/system/locales/en-US.json +15 -1
- package/templates/src/app/web/system/locales/zh-CN.json +15 -1
- package/templates/src/app/web/system/pages/departments/sync-bar.tsx +9 -3
- package/templates/src/app/web/system/pages/roles/index.tsx +4 -8
- package/templates/src/app/web/system/pages/roles/role-label.ts +26 -0
- package/templates/src/app/web/system/pages/solutions/index.tsx +110 -0
- package/templates/src/app/web/system/pages/solutions/market-entry.ts +46 -0
- package/templates/src/app/web/system/pages/users/index.tsx +12 -2
- package/templates/src/app/web/system/pages/users/match-keyword.ts +19 -0
- package/templates/src/app/web/system/pages/users/roles.tsx +43 -14
- package/templates/src/app/web/system/routes.ts +18 -1
- package/templates/src/{app/api/_platform/market → oj-market/api}/api.ts +475 -592
- package/templates/src/oj-market/api/backfill.ts +221 -0
- package/templates/src/{app/api/_platform/market → oj-market/api}/bootstrap.ts +2 -2
- package/templates/src/oj-market/api/cdn/api.ts +312 -0
- package/templates/src/oj-market/api/cdn/shared.ts +104 -0
- package/templates/src/oj-market/api/cdn/signed-auth.ts +75 -0
- package/templates/src/oj-market/api/manifest.yaml +8 -0
- package/templates/src/oj-market/solution.yaml +21 -0
- package/templates/src/oj-market/web/__client/api.schemas.ts +167 -0
- package/templates/src/oj-market/web/__client/index.ts +509 -0
- package/templates/src/oj-market/web/__tests__/marketClient.fake.ts +6 -6
- package/templates/src/oj-market/web/api/client.ts +6 -6
- package/templates/src/oj-market/web/api/defaultClient.ts +31 -25
- package/templates/src/oj-market/web/entry.ts +5 -3
- package/templates/src/oj-market/web/hooks/useMarket.ts +6 -6
- package/templates/src/oj-market/web/pages/MarketApp.tsx +20 -3
- package/templates/src/oj-market/web/publish/locales/en-US.json +1 -1
- package/templates/src/oj-market/web/publish/locales/zh-CN.json +1 -1
- package/templates/src/oj-market/web/publish/pages/history.tsx +2 -11
- package/templates/src/oj-market/web/routes.ts +12 -0
- package/templates/src/oj-market/web/types.ts +14 -8
- package/templates/tests/lifecycle/anonymous-wiring.spec.ts +65 -0
- package/templates/tests/lifecycle/backfill.spec.ts +392 -0
- package/templates/tests/lifecycle/bootstrap.spec.ts +1 -1
- package/templates/tests/lifecycle/bundle-converge.spec.ts +264 -0
- package/templates/tests/lifecycle/cdn-upload.spec.ts +661 -0
- package/templates/tests/lifecycle/deploy-smoke.spec.ts +25 -0
- package/templates/tests/lifecycle/exec-grant.spec.ts +38 -0
- package/templates/tests/lifecycle/installer.spec.ts +36 -0
- package/templates/tests/lifecycle/market-api.spec.ts +448 -803
- package/templates/tests/lifecycle/preflight.spec.ts +18 -0
- package/templates/tests/lifecycle/trust.spec.ts +2 -2
- package/templates/tests/lifecycle/uninstall.spec.ts +36 -2
- package/templates/tests/lifecycle/verify-checks.spec.ts +1 -1
- package/templates/tests/rbac-users.spec.ts +8 -0
- package/templates/tests/solutions-entry.spec.ts +55 -0
- package/templates/tsconfig.paths.json +1 -0
- package/templates/types/stream-probes/stream-handlers.ts +34 -0
- package/templates/web.config.ts +6 -6
- package/vendor/host-versions.json +3 -3
- package/bin/oj +0 -4
- package/src/market/__tests__/build-index.test.ts +0 -641
- package/src/market/__tests__/sharding.test.ts +0 -90
- package/src/market/__tests__/yank-ledger.test.ts +0 -60
- package/src/market/build-index.ts +0 -526
- package/src/market/index-builder.ts +0 -149
- package/src/market/sharding.ts +0 -94
- package/src/market/yank-ledger.ts +0 -91
- package/templates/src/app/api/_platform/_lifecycle/source-seq.ts +0 -88
- package/templates/src/app/api/_platform/market/index-source.ts +0 -112
- package/templates/tests/lifecycle/source-seq.spec.ts +0 -55
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// 方案安装入口的纯推导(Phase B T3):页面只做 query + 渲染,状态口径收这里,
|
|
2
|
+
// 与 roles/visible-roles 同范式(展示层逻辑可单测,不入 React 组件)。
|
|
3
|
+
// 数据源:GET /api/oj-market/index 的行(superadmin;R29 第一方编排面,平台内置)。
|
|
4
|
+
|
|
5
|
+
/** index 行中本入口消费的最小形状(完整行见 oj-market api IndexRow,catchall 契约) */
|
|
6
|
+
export interface SolutionsRow {
|
|
7
|
+
name: string
|
|
8
|
+
latest: string | null
|
|
9
|
+
installed: string | null
|
|
10
|
+
upgradable: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type MarketEntry = { kind: "absent" } | { kind: "installable", latest: string } | { kind: "installed", installed: string, latest: string | null, upgradable: boolean };
|
|
14
|
+
|
|
15
|
+
/** 市场包入口状态:目录无行(出厂未装且未回填)/ 可安装 / 已装(含可升级位) */
|
|
16
|
+
export function marketEntryOf(list: SolutionsRow[]): MarketEntry {
|
|
17
|
+
const row = list.find(r => r.name === "oj-market");
|
|
18
|
+
if (row === undefined)
|
|
19
|
+
return { kind: "absent" };
|
|
20
|
+
if (row.installed === null)
|
|
21
|
+
return row.latest === null ? { kind: "absent" } : { kind: "installable", latest: row.latest };
|
|
22
|
+
return { kind: "installed", installed: row.installed, latest: row.latest, upgradable: row.upgradable };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** 任务记录的最小消费形状(TaskRecord 真源:api/_platform/_lifecycle/types.ts) */
|
|
26
|
+
export interface TaskLike {
|
|
27
|
+
status: string
|
|
28
|
+
progress: number
|
|
29
|
+
message: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type TaskOutcome = { kind: "running", progress: number, message: string } | { kind: "done" } | { kind: "needsTrust" } | { kind: "failed", message: string };
|
|
33
|
+
|
|
34
|
+
/** 任务终态 → 入口渲染口径:needs_trust 是非成功态(TOFU 确认前不得绿) */
|
|
35
|
+
export function taskOutcomeOf(rec: TaskLike): TaskOutcome {
|
|
36
|
+
switch (rec.status) {
|
|
37
|
+
case "running":
|
|
38
|
+
return { kind: "running", progress: rec.progress, message: rec.message };
|
|
39
|
+
case "done":
|
|
40
|
+
return { kind: "done" };
|
|
41
|
+
case "needs_trust":
|
|
42
|
+
return { kind: "needsTrust" };
|
|
43
|
+
default:
|
|
44
|
+
return { kind: "failed", message: rec.message };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -14,6 +14,7 @@ import { buildTreeData, subtreeIds } from "../departments/tree";
|
|
|
14
14
|
import { explainError, isForbidden } from "../errors";
|
|
15
15
|
import { ForbiddenPanel } from "../forbidden";
|
|
16
16
|
import { canManageUser } from "./can-manage";
|
|
17
|
+
import { matchUserKeyword } from "./match-keyword";
|
|
17
18
|
|
|
18
19
|
type UserRow = SystemUsersGetData[number];
|
|
19
20
|
|
|
@@ -42,6 +43,7 @@ export default function UsersPage() {
|
|
|
42
43
|
const [pwdTarget, setPwdTarget] = useState<UserRow | null>(null);
|
|
43
44
|
const [pwdForm] = Form.useForm<{ password: string }>();
|
|
44
45
|
const [deptId, setDeptId] = useState<number | null>(null);
|
|
46
|
+
const [keyword, setKeyword] = useState("");
|
|
45
47
|
|
|
46
48
|
const usersQuery = useQuery({ queryKey: ["system", "users"], queryFn: systemUsersGet });
|
|
47
49
|
// 与部门页共用同一份缓存键:那边改完部门,这边的筛选树也跟着新
|
|
@@ -83,8 +85,9 @@ export default function UsersPage() {
|
|
|
83
85
|
const scope = useMemo(() => (deptId == null ? null : subtreeIds(deptRows, [deptId])), [deptRows, deptId]);
|
|
84
86
|
const visibleUsers = useMemo(() => {
|
|
85
87
|
const all = usersQuery.data ?? [];
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
const scoped = scope ? all.filter(u => u.departments.some(d => scope.has(d.id))) : all;
|
|
89
|
+
return scoped.filter(u => matchUserKeyword(u, keyword));
|
|
90
|
+
}, [usersQuery.data, scope, keyword]);
|
|
88
91
|
|
|
89
92
|
if (usersQuery.error && isForbidden(usersQuery.error))
|
|
90
93
|
return <ForbiddenPanel t={t} error={usersQuery.error} />;
|
|
@@ -158,6 +161,13 @@ export default function UsersPage() {
|
|
|
158
161
|
<Button type="primary" icon={<PlusOutlined />} onClick={() => setCreateOpen(true)}>
|
|
159
162
|
{t("system:users.create")}
|
|
160
163
|
</Button>
|
|
164
|
+
<Input
|
|
165
|
+
allowClear
|
|
166
|
+
style={{ width: 220 }}
|
|
167
|
+
placeholder={t("system:users.searchPlaceholder")}
|
|
168
|
+
value={keyword}
|
|
169
|
+
onChange={e => setKeyword(e.target.value)}
|
|
170
|
+
/>
|
|
161
171
|
<TreeSelect
|
|
162
172
|
allowClear
|
|
163
173
|
showSearch
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 用户列表关键词搜索(纯函数,BDD 用例见 cli __tests__/users-roles-display.test.ts)。
|
|
3
|
+
*
|
|
4
|
+
* 口径(20261106-1811 计划文档):users 表无 nickname 列,「昵称与 display」按
|
|
5
|
+
* username(账号)+ display_name(显示名/昵称)匹配,大小写不敏感;空白关键字 = 全可见。
|
|
6
|
+
* 名单一页全量,过滤在前端做(与部门筛选同口径)。
|
|
7
|
+
*/
|
|
8
|
+
export interface UserKeywordRow {
|
|
9
|
+
username: string
|
|
10
|
+
display_name: string | null
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function matchUserKeyword(row: UserKeywordRow, keyword: string): boolean {
|
|
14
|
+
const kw = keyword.trim().toLowerCase();
|
|
15
|
+
if (!kw)
|
|
16
|
+
return true;
|
|
17
|
+
const tail = row.display_name ?? "";
|
|
18
|
+
return row.username.toLowerCase().includes(kw) || tail.toLowerCase().includes(kw);
|
|
19
|
+
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import type { SystemRolesGetData } from "../../__client";
|
|
1
2
|
import { useUserStore } from "@oj-module/runtime";
|
|
2
3
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
3
|
-
import { App, Button, Card, Checkbox, Space } from "antd";
|
|
4
|
-
import { useState } from "react";
|
|
4
|
+
import { App, Button, Card, Checkbox, Divider, Space, Typography } from "antd";
|
|
5
|
+
import { useMemo, useState } from "react";
|
|
6
|
+
|
|
5
7
|
import { useTranslation } from "react-i18next";
|
|
6
8
|
|
|
7
9
|
import { useNavigate, useParams } from "react-router";
|
|
8
|
-
|
|
9
10
|
import { systemRolesGet, systemUsersGet, systemUsersRolesPut } from "../../__client";
|
|
10
11
|
import { explainError, isForbidden } from "../errors";
|
|
11
12
|
import { ForbiddenPanel } from "../forbidden";
|
|
13
|
+
import { roleLabel } from "../roles/role-label";
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* 成员资格(AC1-7):整集替换某用户角色。后端无 GET 单用户端点,
|
|
@@ -18,6 +20,9 @@ import { ForbiddenPanel } from "../forbidden";
|
|
|
18
20
|
* 授予 admin 已下放到租户内,否则企业租户永远配不出管理员(平台 superadmin 因租户
|
|
19
21
|
* 隔离查不到企业租户的用户)。但 **superadmin 仍只许 superadmin 授**——它握着跨租户
|
|
20
22
|
* 权限,故这里对非 superadmin 直接把该选项置灰,比让他提交后吃 403 清楚。
|
|
23
|
+
*
|
|
24
|
+
* 展示(20261106-1811):角色名按语言名称(key)解析(与角色页共用 roleLabel),
|
|
25
|
+
* 并按模块分组——角色行自带 module 字段,组标题显示模块名原文。
|
|
21
26
|
*/
|
|
22
27
|
export default function UserRolesPage() {
|
|
23
28
|
const { t } = useTranslation();
|
|
@@ -35,6 +40,18 @@ export default function UserRolesPage() {
|
|
|
35
40
|
const usersQuery = useQuery({ queryKey: ["system", "users"], queryFn: systemUsersGet });
|
|
36
41
|
const rolesQuery = useQuery({ queryKey: ["system", "roles"], queryFn: systemRolesGet });
|
|
37
42
|
|
|
43
|
+
// 按模块分组(组内保持 listRoles 的 name 排序);模块名原文作组标题。
|
|
44
|
+
// 位置在提前 return 之前——hooks 不得落在条件分支里
|
|
45
|
+
const groups = useMemo(() => {
|
|
46
|
+
const byModule = new Map<string, SystemRolesGetData>();
|
|
47
|
+
for (const r of rolesQuery.data ?? []) {
|
|
48
|
+
const list = byModule.get(r.module) ?? [];
|
|
49
|
+
list.push(r);
|
|
50
|
+
byModule.set(r.module, list);
|
|
51
|
+
}
|
|
52
|
+
return [...byModule.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
53
|
+
}, [rolesQuery.data]);
|
|
54
|
+
|
|
38
55
|
const saveMut = useMutation({
|
|
39
56
|
mutationFn: (roles: string[]) => systemUsersRolesPut({ query: { uid: Number(uid) }, body: { roles } }),
|
|
40
57
|
onSuccess: () => {
|
|
@@ -55,18 +72,30 @@ export default function UserRolesPage() {
|
|
|
55
72
|
|
|
56
73
|
return (
|
|
57
74
|
<Card title={`${t("system:userRoles.title")}: ${user?.username ?? `#${uid}`}`}>
|
|
58
|
-
<Space direction="vertical">
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
<Space direction="vertical" style={{ width: "100%" }}>
|
|
76
|
+
{groups.map(([mod, rows]) => {
|
|
77
|
+
const names = new Set(rows.map(r => r.name));
|
|
78
|
+
return (
|
|
79
|
+
<div key={mod}>
|
|
80
|
+
<Typography.Text strong>{mod}</Typography.Text>
|
|
81
|
+
<div style={{ paddingLeft: 12, paddingTop: 4 }}>
|
|
82
|
+
<Checkbox.Group
|
|
83
|
+
options={rows.map(r => ({
|
|
84
|
+
label: `${roleLabel(r, t)}${r.deprecated ? t("system:userRoles.deprecated") : ""}`,
|
|
85
|
+
value: r.name,
|
|
86
|
+
// 非 superadmin 授不了平台级角色:置灰,提交后 403 太晚也太含糊
|
|
87
|
+
disabled: r.name === "superadmin" && !isSuper,
|
|
88
|
+
}))}
|
|
89
|
+
// 整集替换语义不变:每组只回显/改动本组名下的选中项
|
|
90
|
+
value={value.filter(v => names.has(v))}
|
|
91
|
+
onChange={vals => setSelected([...value.filter(v => !names.has(v)), ...vals])}
|
|
92
|
+
/>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
96
|
+
})}
|
|
69
97
|
{value.length === 0 ? <span>{t("system:userRoles.none")}</span> : null}
|
|
98
|
+
<Divider style={{ margin: "8px 0" }} />
|
|
70
99
|
<Button
|
|
71
100
|
type="primary"
|
|
72
101
|
disabled={isSelf || selected === null}
|
|
@@ -4,6 +4,10 @@ import { SettingOutlined } from "@ant-design/icons";
|
|
|
4
4
|
|
|
5
5
|
import { createElement, lazy } from "react";
|
|
6
6
|
|
|
7
|
+
// 方案安装入口(Phase B T3):平台内置编排面 /api/oj-market/*(api 随脚手架内置,R29
|
|
8
|
+
// 第一方专用)由 system 域代管。用生成物明示的 bindRequest 逃生门而非
|
|
9
|
+
// createOjMarketClient 工厂——后者 DEV 有跨模块认领告警(该 client 名义属 oj-market)。
|
|
10
|
+
import { bindRequest as bindMarketRequest } from "../../../oj-market/web/__client";
|
|
7
11
|
import { createSystemClient } from "./__client";
|
|
8
12
|
|
|
9
13
|
const Users = lazy(() => import("./pages/users"));
|
|
@@ -13,6 +17,7 @@ const Roles = lazy(() => import("./pages/roles"));
|
|
|
13
17
|
const Oplog = lazy(() => import("./pages/oplog"));
|
|
14
18
|
const Settings = lazy(() => import("./pages/settings"));
|
|
15
19
|
const WecomAdmin = lazy(() => import("./pages/wecom"));
|
|
20
|
+
const Solutions = lazy(() => import("./pages/solutions"));
|
|
16
21
|
|
|
17
22
|
/**
|
|
18
23
|
* `/system` 根的角色门禁(对齐后端 assertSystemAdmin,access.ts:87)——
|
|
@@ -75,6 +80,12 @@ export const routes: AppRouteRecordRaw[] = [
|
|
|
75
80
|
Component: Settings,
|
|
76
81
|
handle: { title: "system:menu.settings", roles: ["superadmin"] },
|
|
77
82
|
},
|
|
83
|
+
{
|
|
84
|
+
// 方案安装(Phase B T3,出厂未装态的首装入口):仅超管可见可访问
|
|
85
|
+
path: "/system/solutions",
|
|
86
|
+
Component: Solutions,
|
|
87
|
+
handle: { title: "system:menu.solutions", roles: ["superadmin"] },
|
|
88
|
+
},
|
|
78
89
|
{
|
|
79
90
|
// 企微代开发后台(服务商运营面):仅超管可见(路由级 roles + 页面内二次判定)
|
|
80
91
|
path: "/system/wecom",
|
|
@@ -85,7 +96,13 @@ export const routes: AppRouteRecordRaw[] = [
|
|
|
85
96
|
},
|
|
86
97
|
];
|
|
87
98
|
|
|
88
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* 构造即接线:登记 /system 前缀 + 绑定 scoped request(D11 前缀收敛);
|
|
101
|
+
* 另登记 /oj-market(平台内置市场编排面,R29 第一方)并绑定其生成 client——
|
|
102
|
+
* 方案安装页(/system/solutions)出厂未装态即经此调用安装端点。
|
|
103
|
+
*/
|
|
89
104
|
export async function onInit(ctx: ModuleContext) {
|
|
90
105
|
createSystemClient(ctx);
|
|
106
|
+
ctx.register.apiPrefix("/oj-market");
|
|
107
|
+
bindMarketRequest(ctx.utils.request);
|
|
91
108
|
}
|