@pactor-app/skills 1.34.0 → 1.40.0

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.
Files changed (49) hide show
  1. package/package.json +1 -1
  2. package/pactor-dsl/SKILL.md +28 -1
  3. package/pactor-dsl/references/dsl-authoring.md +174 -36
  4. package/pactor-prd/SKILL.md +20 -21
  5. package/pactor-prd/references/acceptance-checklist.md +1 -1
  6. package/pactor-prd/references/component-mapping.md +1 -1
  7. package/pactor-prd/references/data-api.md +37 -0
  8. package/pactor-prd/references/incremental-wireframe-delta.md +8 -9
  9. package/pactor-prd/references/page-inventory-and-files.md +2 -2
  10. package/pactor-prd/references/page-templates.md +59 -12
  11. package/pactor-prd/references/project-structure.md +1 -1
  12. package/pactor-prd/template/README.md +4 -4
  13. package/pactor-prd/template/app/api/d/[...parts]/route.ts +80 -0
  14. package/pactor-prd/template/app/layout.tsx +1 -3
  15. package/pactor-prd/template/next.config.js +2 -2
  16. package/pactor-prd/template/pnpm-lock.yaml +97 -97
  17. package/pactor-prd/template/src/pactor/App.tsx +3 -2
  18. package/pactor-prd/template/src/pactor/actions.ts +5 -431
  19. package/pactor-prd/template/src/pactor/components/index.ts +1 -4
  20. package/pactor-prd/template/src/pactor/config.ts +12 -4
  21. package/pactor-prd/template/src/server/yaml/common/dashboard.yaml +1 -1
  22. package/pactor-prd/template/src/server/yaml/common/login.yaml +46 -75
  23. package/pactor-prd/template/src/server/yaml/models/data-list.yaml +4 -4
  24. package/pactor-prd/template/src/server/yaml/provider/provider-detail.yaml +2 -2
  25. package/pactor-prd/template/src/server/yaml/provider/provider-edit.yaml +1 -1
  26. package/pactor-prd/template/src/server/yaml/provider/provider-list.yaml +1 -1
  27. package/pactor-prd/template/src/server/yaml/route/route-detail.yaml +1 -1
  28. package/pactor-prd/template/src/server/yaml/route/route-edit.yaml +1 -1
  29. package/pactor-prd/template/src/server/yaml/route/route-list.yaml +1 -1
  30. package/pactor-prd/template/src/server/yaml/sitemap.yaml +2 -6
  31. package/pactor-prd/references/mock-data-routes.md +0 -66
  32. package/pactor-prd/template/app/api/data/[...parts]/route.ts +0 -160
  33. package/pactor-prd/template/app/login.css +0 -122
  34. package/pactor-prd/template/src/pactor/components/chip-filter.tsx +0 -89
  35. package/pactor-prd/template/src/pactor/components/chip-node.tsx +0 -46
  36. package/pactor-prd/template/src/pactor/mocks/audit-mock.ts +0 -403
  37. package/pactor-prd/template/src/pactor/mocks/call-logs-mock.ts +0 -875
  38. package/pactor-prd/template/src/pactor/mocks/client-debug-mock.ts +0 -188
  39. package/pactor-prd/template/src/pactor/mocks/client-templates-mock.ts +0 -497
  40. package/pactor-prd/template/src/pactor/mocks/clients-mock.ts +0 -483
  41. package/pactor-prd/template/src/pactor/mocks/costs-mock.ts +0 -406
  42. package/pactor-prd/template/src/pactor/mocks/dashboard-mock.ts +0 -192
  43. package/pactor-prd/template/src/pactor/mocks/data-list-mock.ts +0 -84
  44. package/pactor-prd/template/src/pactor/mocks/model-debug-mock.ts +0 -144
  45. package/pactor-prd/template/src/pactor/mocks/models-mock.ts +0 -799
  46. package/pactor-prd/template/src/pactor/mocks/ops-usage-mock.ts +0 -806
  47. package/pactor-prd/template/src/pactor/mocks/providers-mock.ts +0 -424
  48. package/pactor-prd/template/src/pactor/mocks/routes-mock.ts +0 -604
  49. package/pactor-prd/template/src/pactor/services.ts +0 -200
@@ -1,438 +1,12 @@
1
1
  /**
2
- * 页面级自定义动作(调试台等场景的示例实现
3
- * model-debug-actions.ts,合并为单文件),经 SitemapApp 的 `actions` prop
4
- * 全局注册。
5
- * DSL 表达式不支持数组操作 / 定时器 / 剪贴板,故对话状态变更、流式模拟、
6
- * 身份联动选项计算收敛在此处;handler 经 ctx.context.state 直接读写页面
2
+ * 页面级自定义动作注册表,经 SitemapApp 的 `actions` prop 全局注册。
3
+ * 模板默认为空;需要 DSL 表达式做不到的能力(数组操作 / 定时器 / 剪贴板等)
4
+ * 时在此注册自定义动作,handler 可经 ctx.context.state 直接读写页面
7
5
  * StateStore,写入即触发 DSL 树重渲染(与内置 setState 动作同一通道)。
8
6
  *
9
- * ActionHandler 类型见 @pactor-app/runtime;此处按结构化子集声明参数类型
10
- * (handler 只需已求值的 action.params 与 state 读写),赋值给 SitemapApp
11
- * actions 选项时由 TS 结构化检查兼容性(1.22.0 签名:
12
- * (action: ActionConfig, ctx: ActionContext) => ActionResult | Promise<…>)。
7
+ * ActionHandler 类型见 @pactor-app/runtime。
13
8
  */
14
9
 
15
10
  import type { ActionHandler } from "@pactor-app/runtime";
16
11
 
17
- import {
18
- appKeyOptionsOf,
19
- routeOptionsOf,
20
- routeTagOptionsOf,
21
- simulateClientCall,
22
- type ClientDebugRound,
23
- } from "./mocks/client-debug-mock";
24
- import { getProvider } from "./mocks/providers-mock";
25
- import {
26
- capabilitiesOf,
27
- modelOptionsOf,
28
- paramDefaultsOf,
29
- simulateModelCall,
30
- supportsReasoning,
31
- testConnection,
32
- } from "./mocks/model-debug-mock";
33
- import { streamText, type DebugChatMessage } from "./components/debug-chat";
34
-
35
- /** SitemapApp actions 选项 handler 的结构化最小契约(ActionHandler 子集) */
36
- export interface DebugActionContext {
37
- context: {
38
- state: {
39
- get: (path: string) => unknown;
40
- set: (patch: Record<string, unknown>) => void;
41
- };
42
- };
43
- }
44
-
45
- export type DebugAction = (
46
- action: { params?: Record<string, unknown> },
47
- ctx: DebugActionContext,
48
- ) => { ok: boolean };
49
-
50
- function str(value: unknown): string {
51
- return typeof value === "string" ? value : "";
52
- }
53
-
54
- function num(value: unknown): number | undefined {
55
- return typeof value === "number" ? value : undefined;
56
- }
57
-
58
- export function createClientDebugActions(): Record<string, DebugAction> {
59
- /** 流式定时器的停止闭包(停止生成 / 清空对话 / 下一次发送前取消) */
60
- let stopCurrent: (() => void) | null = null;
61
-
62
- /** 流式收尾:assistant 消息落定 + 轮次写入 selectedRound(右侧返回报文此时可见) */
63
- const finalize = (
64
- ctx: DebugActionContext,
65
- round: ClientDebugRound,
66
- assistantId: string,
67
- finalText: string,
68
- stopped: boolean,
69
- ) => {
70
- const messages = (
71
- (ctx.context.state.get("messages") as DebugChatMessage[]) ?? []
72
- ).map((m) =>
73
- m.id === assistantId
74
- ? {
75
- ...m,
76
- content: finalText,
77
- streaming: false,
78
- meta: `Token ${round.tokensIn}/${round.tokensOut} · TTFT ${round.ttftMs}ms · 延迟 ${round.latencyMs}ms${stopped ? " · 已停止" : ""}`,
79
- }
80
- : m,
81
- );
82
- ctx.context.state.set({
83
- messages,
84
- selectedRound: round,
85
- selectedRoundId: round.id,
86
- streaming: false,
87
- });
88
- stopCurrent = null;
89
- };
90
-
91
- return {
92
- /** 切换客户端:联动 AppKey(取该客户端唯一一把)、授权路由与上下文 */
93
- "clientDebug.selectClient": (action, ctx) => {
94
- const clientCode = str(action.params?.clientCode);
95
- const appKeys = appKeyOptionsOf(clientCode);
96
- ctx.context.state.set({
97
- clientCode,
98
- appKeyOptions: appKeys,
99
- appKeyId: appKeys[0]?.value ?? "",
100
- routeOptions: routeOptionsOf(clientCode),
101
- routeCode: "",
102
- tagOptions: [],
103
- routeTag: "",
104
- });
105
- return { ok: true };
106
- },
107
-
108
- /** 切换授权路由:联动 RouteTag 选项 */
109
- "clientDebug.selectRoute": (action, ctx) => {
110
- const routeCode = str(action.params?.routeCode);
111
- ctx.context.state.set({
112
- routeCode,
113
- tagOptions: routeTagOptionsOf(routeCode),
114
- routeTag: "",
115
- });
116
- return { ok: true };
117
- },
118
-
119
- /** 发送:模拟完整链路调用,流式渲染 assistant 回复 */
120
- "clientDebug.send": (action, ctx) => {
121
- const state = ctx.context.state;
122
- if (state.get("streaming")) return { ok: false };
123
- const clientCode = str(state.get("clientCode"));
124
- const appKeyId = str(state.get("appKeyId"));
125
- const routeCode = str(state.get("routeCode"));
126
- const text = str(action.params?.text);
127
- if (!clientCode || !appKeyId || !routeCode || !text.trim()) {
128
- return { ok: false };
129
- }
130
-
131
- const roundCount = Number(state.get("roundCount") ?? 0);
132
- const round = simulateClientCall(
133
- {
134
- clientCode,
135
- appKeyId,
136
- routeCode,
137
- channel: str(state.get("channel")),
138
- routeTag: str(state.get("routeTag")),
139
- user: str(state.get("user")),
140
- },
141
- text,
142
- roundCount + 1,
143
- );
144
- const assistantId = `${round.id}-a`;
145
- const messages: DebugChatMessage[] = [
146
- ...((state.get("messages") as DebugChatMessage[]) ?? []),
147
- { id: `${round.id}-u`, role: "user", content: text, round },
148
- {
149
- id: assistantId,
150
- role: "assistant",
151
- content: "",
152
- round,
153
- streaming: true,
154
- },
155
- ];
156
- state.set({
157
- messages,
158
- streaming: true,
159
- roundCount: roundCount + 1,
160
- // 流结束后再写入 selectedRound(PRD:返回报文在流结束后刷新)
161
- selectedRound: null,
162
- selectedRoundId: round.id,
163
- tab: "request",
164
- });
165
-
166
- let latest = "";
167
- const cancel = streamText(
168
- round.reply,
169
- (chunk) => {
170
- latest = chunk;
171
- const cur =
172
- (ctx.context.state.get("messages") as DebugChatMessage[]) ?? [];
173
- ctx.context.state.set({
174
- messages: cur.map((m) =>
175
- m.id === assistantId ? { ...m, content: chunk } : m,
176
- ),
177
- });
178
- },
179
- () => finalize(ctx, round, assistantId, round.reply, false),
180
- );
181
- stopCurrent = () => {
182
- cancel();
183
- finalize(ctx, round, assistantId, latest || round.reply.slice(0, 12), true);
184
- };
185
- return { ok: true };
186
- },
187
-
188
- /** 停止生成:取消定时器并按当前片段收尾 */
189
- "clientDebug.stop": (_action, ctx) => {
190
- stopCurrent?.();
191
- if (ctx.context.state.get("streaming")) {
192
- ctx.context.state.set({ streaming: false });
193
- }
194
- return { ok: true };
195
- },
196
-
197
- /** 清空对话:清空本地会话(不影响已落库调用日志) */
198
- "clientDebug.clear": (_action, ctx) => {
199
- stopCurrent?.();
200
- stopCurrent = null;
201
- ctx.context.state.set({
202
- messages: [],
203
- selectedRound: null,
204
- selectedRoundId: "",
205
- roundCount: 0,
206
- streaming: false,
207
- });
208
- return { ok: true };
209
- },
210
-
211
- /** 复制报文到剪贴板(DSL 无剪贴板能力,经动作桥接) */
212
- "clientDebug.copy": (action) => {
213
- const text = action.params?.text;
214
- if (typeof text === "string" && text) {
215
- void navigator.clipboard?.writeText(text);
216
- }
217
- return { ok: true };
218
- },
219
- };
220
- }
221
-
222
- export function createModelDebugActions(): Record<string, DebugAction> {
223
- let stopCurrent: (() => void) | null = null;
224
- let seq = 0;
225
-
226
- /** assistant 消息收尾(流式完成 / 停止生成共用) */
227
- const finalize = (
228
- ctx: DebugActionContext,
229
- id: string,
230
- patch: Partial<DebugChatMessage>,
231
- ) => {
232
- const messages = (
233
- (ctx.context.state.get("messages") as DebugChatMessage[]) ?? []
234
- ).map((m) => (m.id === id ? { ...m, ...patch } : m));
235
- ctx.context.state.set({ messages, streaming: false });
236
- stopCurrent = null;
237
- };
238
-
239
- return {
240
- /** 切换供应商:联动刷新模型列表并清空已选模型与连接状态 */
241
- "modelDebug.selectProvider": (action, ctx) => {
242
- const providerCode = str(action.params?.providerCode);
243
- ctx.context.state.set({
244
- providerCode,
245
- modelOptions: modelOptionsOf(providerCode),
246
- modelCode: "",
247
- conn: null,
248
- showReasoning: false,
249
- canStream: true,
250
- canTools: false,
251
- temperature: undefined,
252
- topP: undefined,
253
- maxTokens: undefined,
254
- streamingOn: true,
255
- toolsOn: false,
256
- });
257
- return { ok: true };
258
- },
259
-
260
- /** 切换模型:回填默认参数 + 按 Capability 计算参数显隐/开关可用性 */
261
- "modelDebug.selectModel": (action, ctx) => {
262
- const modelCode = str(action.params?.modelCode);
263
- const caps = capabilitiesOf(modelCode);
264
- const defaults = paramDefaultsOf(modelCode);
265
- ctx.context.state.set({
266
- modelCode,
267
- conn: null,
268
- temperature: defaults.temperature,
269
- topP: defaults.topP,
270
- maxTokens: defaults.maxTokens,
271
- reasoningEffort: defaults.reasoningEffort ?? "medium",
272
- showReasoning: supportsReasoning(modelCode),
273
- canStream: caps.length === 0 || caps.includes("Streaming"),
274
- canTools: caps.includes("Tool Calling"),
275
- streamingOn: caps.includes("Streaming"),
276
- toolsOn: false,
277
- });
278
- return { ok: true };
279
- },
280
-
281
- /** 连接测试:不发对话,仅探测凭证与 Endpoint 可达性(模拟 600ms 探测延迟) */
282
- "modelDebug.testConnection": (_action, ctx) => {
283
- const state = ctx.context.state;
284
- const providerCode = str(state.get("providerCode"));
285
- if (!providerCode || !str(state.get("modelCode")) || state.get("testing")) {
286
- return { ok: false };
287
- }
288
- state.set({ testing: true, conn: null });
289
- setTimeout(() => {
290
- ctx.context.state.set({
291
- conn: testConnection(providerCode),
292
- testing: false,
293
- });
294
- }, 600);
295
- return { ok: true };
296
- },
297
-
298
- /** 发送:直连供应商模型(不经过 AppKey / Route 业务链路) */
299
- "modelDebug.send": (action, ctx) => {
300
- const state = ctx.context.state;
301
- if (state.get("streaming")) return { ok: false };
302
- const providerCode = str(state.get("providerCode"));
303
- const modelCode = str(state.get("modelCode"));
304
- const text = str(action.params?.text);
305
- if (!providerCode || !modelCode || !text.trim()) return { ok: false };
306
-
307
- seq += 1;
308
- const msgId = `m-${seq}`;
309
- const messages = (state.get("messages") as DebugChatMessage[]) ?? [];
310
- const userMsg: DebugChatMessage = {
311
- id: `${msgId}-u`,
312
- role: "user",
313
- content: text,
314
- };
315
-
316
- // 上游/网关失败(凭证未配置):对话区以错误消息展示摘要(PRD 交互规则 3)
317
- const provider = getProvider(providerCode);
318
- if (provider && provider.keyStatus !== "configured") {
319
- state.set({
320
- messages: [
321
- ...messages,
322
- userMsg,
323
- {
324
- id: `${msgId}-e`,
325
- role: "error",
326
- content: `请求失败:Provider「${provider.displayName}」${
327
- provider.keyStatus === "pending"
328
- ? "API Key 待配置"
329
- : "未配置 API Key"
330
- },请先在 Provider 页完成凭证配置。`,
331
- },
332
- ],
333
- });
334
- return { ok: true };
335
- }
336
-
337
- const streamingOn =
338
- state.get("streamingOn") === true && state.get("canStream") !== false;
339
- const result = simulateModelCall(
340
- providerCode,
341
- modelCode,
342
- str(state.get("systemPrompt")),
343
- {
344
- temperature: num(state.get("temperature")),
345
- topP: num(state.get("topP")),
346
- maxTokens: num(state.get("maxTokens")),
347
- reasoningEffort:
348
- state.get("showReasoning") === true
349
- ? str(state.get("reasoningEffort"))
350
- : undefined,
351
- streaming: streamingOn,
352
- tools:
353
- state.get("toolsOn") === true && state.get("canTools") === true,
354
- },
355
- text,
356
- );
357
- const meta = `Token ${result.tokensIn}/${result.tokensOut} · TTFT ${result.ttftMs}ms · 延迟 ${result.latencyMs}ms · 上游 ${result.status}`;
358
-
359
- // 非流式:直接落定完整回复
360
- if (!streamingOn) {
361
- state.set({
362
- messages: [
363
- ...messages,
364
- userMsg,
365
- {
366
- id: msgId,
367
- role: "assistant",
368
- content: result.reply,
369
- meta,
370
- },
371
- ],
372
- });
373
- return { ok: true };
374
- }
375
-
376
- // 流式:边收边渲染;可停止生成
377
- state.set({
378
- messages: [
379
- ...messages,
380
- userMsg,
381
- { id: msgId, role: "assistant", content: "", streaming: true },
382
- ],
383
- streaming: true,
384
- });
385
- let latest = "";
386
- const cancel = streamText(
387
- result.reply,
388
- (chunk) => {
389
- latest = chunk;
390
- const cur =
391
- (ctx.context.state.get("messages") as DebugChatMessage[]) ?? [];
392
- ctx.context.state.set({
393
- messages: cur.map((m) =>
394
- m.id === msgId ? { ...m, content: chunk } : m,
395
- ),
396
- });
397
- },
398
- () => finalize(ctx, msgId, { streaming: false, meta }),
399
- );
400
- stopCurrent = () => {
401
- cancel();
402
- finalize(ctx, msgId, {
403
- content: latest || result.reply.slice(0, 12),
404
- streaming: false,
405
- meta: `${meta} · 已停止`,
406
- });
407
- };
408
- return { ok: true };
409
- },
410
-
411
- /** 停止生成 */
412
- "modelDebug.stop": (_action, ctx) => {
413
- stopCurrent?.();
414
- if (ctx.context.state.get("streaming")) {
415
- ctx.context.state.set({ streaming: false });
416
- }
417
- return { ok: true };
418
- },
419
-
420
- /** 清空对话(不影响服务端) */
421
- "modelDebug.clear": (_action, ctx) => {
422
- stopCurrent?.();
423
- stopCurrent = null;
424
- ctx.context.state.set({ messages: [], streaming: false });
425
- return { ok: true };
426
- },
427
- };
428
- }
429
-
430
- /**
431
- * SitemapApp 全局动作注册表(clientDebug.* / modelDebug.*)。
432
- * 单例:两组动作名不相交;同一时刻 PageOutlet 只挂载一个页面,
433
- * 各页面的流式停止闭包互不干扰。
434
- */
435
- export const pactorActions: Record<string, ActionHandler> = {
436
- ...createClientDebugActions(),
437
- ...createModelDebugActions(),
438
- };
12
+ export const pactorActions: Record<string, ActionHandler> = {};
@@ -3,9 +3,8 @@
3
3
  /**
4
4
  * 页面 DSL 引用的自定义组件注册表(页面级自定义组件
5
5
  * `components={{...}}`),经 SitemapApp 的 `components` prop 全局注册。
6
+ * ChipFilter / ChipNode 快筛组件已内置在 @pactor-app/ui,无需在此注册。
6
7
  */
7
- import { ChipNode } from "./chip-node";
8
- import { ChipFilter } from "./chip-filter";
9
8
  import { StatusBadge } from "./status-badge";
10
9
  import { LogStatus } from "./log-status";
11
10
  import { DebugChat } from "./debug-chat";
@@ -13,8 +12,6 @@ import { CardLink, StatusToggleIcon, TextLink } from "./card-links";
13
12
  import { ThemeSwitcher } from "./theme-switcher";
14
13
 
15
14
  export const pactorComponents: Record<string, unknown> = {
16
- ChipNode,
17
- ChipFilter,
18
15
  StatusBadge,
19
16
  LogStatus,
20
17
  DebugChat,
@@ -19,10 +19,18 @@ export const pageEndpoint = (pageId: string) =>
19
19
  `/api/public/pages/${pageId}`;
20
20
 
21
21
  /**
22
- * 外部接口基准地址(SitemapApp baseUrl)。
22
+ * 客户端接口基准地址(SitemapApp baseUrl)。
23
+ * 数据接口全部同源经转发层(app/api/d/[...parts])调用,故为空字符串
24
+ * (相对路径由浏览器按同源解析)。
25
+ */
26
+ export const apiBaseUrl = "";
27
+
28
+ /**
29
+ * 服务端接口基准地址(转发层的目标地址,仅服务端路由使用)。
23
30
  * 由 next.config.js 的 API_BASE_URLS 按构建环境(APP_ENV:
24
31
  * build / build:dev / build:test → production / development / test)
25
- * 解析,经 env 配置内联进客户端包;缺省回退本地开发地址。
32
+ * 解析并内联;缺省回退本地开发占位(不存在 → 转发层回退空数据)。
33
+ * 所有需要服务端接口地址的位置统一从这里导入。
26
34
  */
27
- export const apiBaseUrl =
28
- process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:9011";
35
+ export const serverBaseUrl =
36
+ process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:9011/backend";
@@ -15,7 +15,7 @@ dataSources:
15
15
  autoLoad: true
16
16
  request:
17
17
  method: GET
18
- url: /api/data/dashboard
18
+ url: /api/d/dashboard
19
19
  params:
20
20
  start: ${state.range.start}
21
21
  end: ${state.range.end}
@@ -1,7 +1,11 @@
1
- # 登录页 DSL:卡片结构 + 提交/错误提示/跳转闭环,视觉样式在 app/login.css。
2
- # 全屏渐变外壳(login-page 类)由 sitemap.yaml 的 login 布局提供,
3
- # 提交动作为内置 request(POST /api/auth/login 写会话 cookie)+ app.reload
4
- # 整页重载,sitemap 端点按已登录会话重新下发。
1
+ # 登录页 DSL:type: Login 业务组件(packages/ui components/business/Login/),
2
+ # 布局(layout: split / centered / brand-card / overlap / backdrop)与修饰
3
+ # (brandSide / brandRatio / authVariant / brandPanelBackground / decor)正交组合,
4
+ # 品牌区/文案/辅助入口/页脚全部 props 化,样式走语义令牌(深浅色/换肤自适应),
5
+ # 可配置项权威定义见 openspec/specs/ui-login-component 与组件源码。
6
+ # 提交闭环由 DSL 编排:内置 request(POST /api/auth/login 写会话 cookie)
7
+ # + 结果判空 + 失败/成功 message + app.reload 整页重载,sitemap 端点按已登录
8
+ # 会话重新下发。页面使用 sitemap.yaml 的 login 布局(纯 PageOutlet)。
5
9
  dsl: "1.0"
6
10
  page:
7
11
  id: login
@@ -10,75 +14,42 @@ page:
10
14
  description: 登录页
11
15
 
12
16
  body:
13
- type: Card
17
+ type: Login
14
18
  props:
15
- className: login-card
16
- children:
17
- - type: Text
18
- props:
19
- text: RESTRICTED ACCESS
20
- className: login-eyebrow
21
- - type: Text
22
- props:
23
- text: 管理后台登录
24
- className: login-heading
25
- - type: Text
26
- props:
27
- text: 仅已分配平台审核角色的管理人员可以访问。
28
- type: secondary
29
- className: login-subtitle
30
- - type: Form
31
- props:
32
- name: login
33
- style: { marginTop: 16 }
34
- events:
35
- onSubmit:
36
- - id: loginResult
37
- action: request
38
- params:
39
- method: POST
40
- url: http://localhost:9011/api/auth/login
41
- body:
42
- username: ${event.username}
43
- password: ${event.password}
44
- - action: if
45
- params:
46
- condition: ${actions.loginResult == null || actions.loginResult.token == null}
47
- then:
48
- - action: message
49
- params:
50
- messageType: error
51
- text: 用户名或密码错误(演示账号 admin / pactor123)
52
- - action: if
53
- params:
54
- condition: ${actions.loginResult != null && actions.loginResult.token != null}
55
- then:
56
- - action: message
57
- params:
58
- messageType: success
59
- text: 登录成功,正在跳转…
60
- - action: app.reload
61
- params: { to: / }
62
- children:
63
- - type: Input
64
- props:
65
- name: username
66
- label: 用户名
67
- placeholder: 请输入用户名
68
- rules:
69
- - { required: true, message: 请输入用户名 }
70
- - type: Input
71
- props:
72
- name: password
73
- label: 密码
74
- type: password
75
- placeholder: 请输入密码
76
- rules:
77
- - { required: true, message: 请输入密码 }
78
- - type: Button
79
- props:
80
- text: 登 录
81
- variant: primary
82
- submit: true
83
- size: large
84
- style: { width: 100%, marginTop: 8 }
19
+ layout: split
20
+ authVariant: card
21
+ brand:
22
+ name: Pactor Console
23
+ title: 管理后台登录
24
+ description: 仅已分配平台审核角色的管理人员可以访问。
25
+ title: 登录
26
+ subtitle: 使用管理员账号登录控制台(演示账号 admin / pactor123)
27
+ submitText: 登 录
28
+ events:
29
+ onSubmit:
30
+ - id: loginResult
31
+ action: request
32
+ params:
33
+ method: POST
34
+ url: http://localhost:9011/api/auth/login
35
+ body:
36
+ username: ${event.username}
37
+ password: ${event.password}
38
+ - action: if
39
+ params:
40
+ condition: ${actions.loginResult == null || actions.loginResult.token == null}
41
+ then:
42
+ - action: message
43
+ params:
44
+ messageType: error
45
+ text: 用户名或密码错误(演示账号 admin / pactor123)
46
+ - action: if
47
+ params:
48
+ condition: ${actions.loginResult != null && actions.loginResult.token != null}
49
+ then:
50
+ - action: message
51
+ params:
52
+ messageType: success
53
+ text: 登录成功,正在跳转…
54
+ - action: app.reload
55
+ params: { to: / }
@@ -21,7 +21,7 @@ dataSources:
21
21
  autoLoad: true
22
22
  request:
23
23
  method: GET
24
- url: /api/data/data-list
24
+ url: /api/d/data-list
25
25
  params:
26
26
  keyword: ${state.keyword}
27
27
  status: ${state.status}
@@ -30,7 +30,7 @@ dataSources:
30
30
  autoLoad: false
31
31
  request:
32
32
  method: GET
33
- url: /api/data/data-list/${state.editingId}
33
+ url: /api/d/data-list/${state.editingId}
34
34
  body:
35
35
  type: Page
36
36
  children:
@@ -68,7 +68,7 @@ body:
68
68
  params:
69
69
  editingId: ""
70
70
  fType: ""
71
- - action: reload # 清空 editing 数据(editingId 为空 → mock 返回空对象)
71
+ - action: reload # 清空 editing 数据(editingId 为空 → 空对象)
72
72
  params:
73
73
  dataSource: editing
74
74
  - action: overlay.open # 锚点 &entityDrawer 在此定义,表格行内用 *entityDrawer 引用
@@ -93,7 +93,7 @@ body:
93
93
  - action: request
94
94
  params:
95
95
  method: POST
96
- url: /api/data/ops/data-list-save
96
+ url: /api/d/ops/data-list-save
97
97
  body:
98
98
  id: ${state.editingId}
99
99
  name: ${event.name}
@@ -12,12 +12,12 @@ dataSources:
12
12
  autoLoad: true
13
13
  request:
14
14
  method: GET
15
- url: /api/data/providers/${route.params.code}
15
+ url: /api/d/providers/${route.params.code}
16
16
  upstream:
17
17
  type: http
18
18
  request:
19
19
  method: GET
20
- url: /api/data/providers/${route.params.code}/pull-models
20
+ url: /api/d/providers/${route.params.code}/pull-models
21
21
  body:
22
22
  type: Page
23
23
  children:
@@ -10,7 +10,7 @@ dataSources:
10
10
  autoLoad: true
11
11
  request:
12
12
  method: GET
13
- url: /api/data/providers/${route.params.code}
13
+ url: /api/d/providers/${route.params.code}
14
14
  body:
15
15
  type: Page
16
16
  children: