@xtalpi/agentic-lab-skills 0.0.9 → 0.0.11

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 (68) hide show
  1. package/README.md +1 -1
  2. package/package.json +14 -14
  3. package/skills/lab-flow-designer/SKILL.md +612 -593
  4. package/skills/lab-flow-designer/embedded-template/SKILL.md +103 -88
  5. package/skills/lab-flow-designer/embedded-template/pools//345/205/245/345/217/243/346/261/240.md +21 -12
  6. package/skills/lab-flow-designer/embedded-template/pools//345/207/272/345/217/243/346/261/240.md +21 -12
  7. package/skills/lab-flow-designer/embedded-template/scripts//347/244/272/344/276/213/346/225/260/346/215/256/344/270/216/346/240/241/351/252/214/351/227/250/346/216/247.js +142 -142
  8. package/skills/lab-flow-designer/embedded-template/valves//347/244/272/344/276/213/346/225/260/346/215/256/344/270/216/346/240/241/351/252/214/351/227/250/346/216/247.md +114 -99
  9. package/skills/lab-flow-designer/references/agentic-lab-processer.md +122 -78
  10. package/skills/lab-flow-designer/references/agentic-lab-sdk.md +534 -361
  11. package/skills/lab-flow-designer/references/rhea-api/README.md +7 -7
  12. package/skills/lab-flow-designer/references/rhea-api/execute_process_batch.md +58 -58
  13. package/skills/lab-flow-designer/references/skill-package-layout.md +268 -204
  14. package/skills/lab-flow-designer/references//344/270/232/345/212/241/346/265/201/347/250/213/346/226/207/346/241/243/346/240/207/345/207/206.md +216 -208
  15. package/skills/lab-flow-designer/templates//344/270/232/345/212/241/346/265/201/347/250/213/346/226/207/346/241/243/346/250/241/346/235/277.md +192 -169
  16. package/skills/lab-flow-designer/templates//344/270/232/345/212/241/346/265/201/347/250/213/346/226/207/346/241/243/347/244/272/344/276/213.md +207 -197
  17. package/skills/lab-flow-designer/testing/test-processer.mjs +1240 -1075
  18. package/skills/lab-nocobase-flow-generator/SKILL.md +164 -164
  19. package/skills/lab-nocobase-flow-generator/examples/setting/350/241/250/350/216/267/345/217/226/345/244/226/351/203/250/346/234/215/345/212/241.js +70 -70
  20. package/skills/lab-nocobase-flow-generator/examples//346/237/245/350/257/242/345/214/226/345/255/246/345/223/201/344/277/241/346/201/257.js +30 -30
  21. package/skills/lab-nocobase-flow-generator/references/doc-standard.md +84 -84
  22. package/skills/lab-nocobase-flow-generator/references/runtime-api.md +224 -224
  23. package/skills/lab-nocobase-flow-generator/templates//350/204/232/346/234/254/351/200/273/350/276/221/346/226/207/346/241/243/346/250/241/346/235/277.md +121 -121
  24. package/skills/lab-nocobase-flow-generator/templates//350/204/232/346/234/254/351/200/273/350/276/221/346/226/207/346/241/243/347/244/272/344/276/213.md +67 -67
  25. package/skills/lab-orbit-component-builder/SKILL.md +353 -353
  26. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.env.local.example +27 -27
  27. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.eslintignore +7 -7
  28. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.eslintrc.cjs +88 -88
  29. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.nvmrc +1 -1
  30. package/skills/lab-orbit-component-builder/examples/xnb-component-template/AgenticAppAPI.md +268 -268
  31. package/skills/lab-orbit-component-builder/examples/xnb-component-template/Jenkinsfile +106 -106
  32. package/skills/lab-orbit-component-builder/examples/xnb-component-template/OrbitAPI.md +453 -453
  33. package/skills/lab-orbit-component-builder/examples/xnb-component-template/README.md +176 -176
  34. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/public/index.html +12 -12
  35. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/App.vue +151 -151
  36. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/components/DevOpenerLauncher.vue +143 -143
  37. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/global.d.ts +77 -77
  38. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/main.ts +308 -308
  39. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/mockXNBBitable.ts +119 -119
  40. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/shims-vue.d.ts +6 -6
  41. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/utils/devOpenerHost.ts +75 -75
  42. package/skills/lab-orbit-component-builder/examples/xnb-component-template/index.html +13 -13
  43. package/skills/lab-orbit-component-builder/examples/xnb-component-template/package.json +60 -60
  44. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/api/agenticlabTickets.ts +110 -110
  45. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/entries/bitable.ts +4 -4
  46. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/entries/custom-page.ts +4 -4
  47. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/index.ts +1 -1
  48. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/styles/orbit-quasar-host.scss +19 -19
  49. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/types/context.ts +15 -15
  50. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/types/xnb-context.ts +70 -70
  51. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useBitablePage.ts +189 -189
  52. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useSuperCellDemo.ts +257 -257
  53. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useSuperTableBitableLifecycle.ts +555 -555
  54. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/openerInitParams.ts +158 -158
  55. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/openerTicketIds.ts +32 -32
  56. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/orbitHttpClient.ts +110 -110
  57. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/request.ts +92 -92
  58. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/views/bitable.vue +67 -67
  59. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/views/custom-page.vue +140 -140
  60. package/skills/lab-orbit-component-builder/examples/xnb-component-template/tsconfig.json +45 -45
  61. package/skills/lab-orbit-component-builder/examples/xnb-component-template/vite.config.ts +170 -170
  62. package/skills/lab-orbit-component-builder/examples/xnb-component-template/vite.dev.config.ts +58 -58
  63. package/skills/lab-orbit-component-builder/references/flow-document-human-ui.md +65 -65
  64. package/skills/lab-orbit-component-builder/references/orbit-vue-conventions.md +133 -133
  65. package/skills/lab-orbit-component-builder/references/pool-schema-to-columns.md +67 -67
  66. package/skills/lab-orbit-component-builder/references/vue-template-checklist.md +179 -179
  67. package/skills/lab-orbit-component-builder/references/xnb-context-vue-props.md +49 -49
  68. package/skills/lab-orbit-component-builder/references/xnbitable-vue-parity.md +32 -32
@@ -1,92 +1,92 @@
1
- interface RequestOptions {
2
- method: string
3
- url: string
4
- headers?: Record<string, string>
5
- query?: Record<string, string | number | boolean | string[] | null | undefined>
6
- body?: any
7
- }
8
-
9
- interface RequestResponse<T = any> {
10
- data: T
11
- headers: Record<string, string>
12
- }
13
-
14
- async function getToken (): Promise<string> {
15
- try {
16
- return await window.xnb.choreo.getUserToken()
17
- } catch {
18
- return ''
19
- }
20
- }
21
-
22
- async function request<T = any> (options: RequestOptions): Promise<T> {
23
- const token = await getToken()
24
-
25
- const headers: Record<string, string> = {
26
- 'Content-Type': 'application/json',
27
- ...options.headers
28
- }
29
- if (token) {
30
- headers.Authorization = `Bearer ${token}`
31
- }
32
-
33
- const httpOptions: any = {
34
- method: options.method.toUpperCase(),
35
- url: options.url,
36
- headers,
37
- responseType: window.xnb.http.ResponseType.JSON
38
- }
39
-
40
- if (options.query) {
41
- httpOptions.query = options.query
42
- }
43
-
44
- if (options.body !== undefined) {
45
- httpOptions.body = window.xnb.http.Body.json(options.body)
46
- }
47
-
48
- const res: RequestResponse<T> = await window.xnb.http.client.request(httpOptions)
49
- return res.data
50
- }
51
-
52
- export async function get<T = any> (
53
- url: string,
54
- query?: Record<string, string | number | boolean | string[] | null | undefined>,
55
- headers?: Record<string, string>
56
- ): Promise<T> {
57
- return request<T>({ method: 'GET', url, query, headers })
58
- }
59
-
60
- export async function post<T = any> (
61
- url: string,
62
- body?: any,
63
- headers?: Record<string, string>
64
- ): Promise<T> {
65
- return request<T>({ method: 'POST', url, body, headers })
66
- }
67
-
68
- export async function put<T = any> (
69
- url: string,
70
- body?: any,
71
- headers?: Record<string, string>
72
- ): Promise<T> {
73
- return request<T>({ method: 'PUT', url, body, headers })
74
- }
75
-
76
- export async function del<T = any> (
77
- url: string,
78
- query?: Record<string, string | number | boolean | string[] | null | undefined>,
79
- headers?: Record<string, string>
80
- ): Promise<T> {
81
- return request<T>({ method: 'DELETE', url, query, headers })
82
- }
83
-
84
- export async function patch<T = any> (
85
- url: string,
86
- body?: any,
87
- headers?: Record<string, string>
88
- ): Promise<T> {
89
- return request<T>({ method: 'PATCH', url, body, headers })
90
- }
91
-
92
- export default request
1
+ interface RequestOptions {
2
+ method: string
3
+ url: string
4
+ headers?: Record<string, string>
5
+ query?: Record<string, string | number | boolean | string[] | null | undefined>
6
+ body?: any
7
+ }
8
+
9
+ interface RequestResponse<T = any> {
10
+ data: T
11
+ headers: Record<string, string>
12
+ }
13
+
14
+ async function getToken (): Promise<string> {
15
+ try {
16
+ return await window.xnb.choreo.getUserToken()
17
+ } catch {
18
+ return ''
19
+ }
20
+ }
21
+
22
+ async function request<T = any> (options: RequestOptions): Promise<T> {
23
+ const token = await getToken()
24
+
25
+ const headers: Record<string, string> = {
26
+ 'Content-Type': 'application/json',
27
+ ...options.headers
28
+ }
29
+ if (token) {
30
+ headers.Authorization = `Bearer ${token}`
31
+ }
32
+
33
+ const httpOptions: any = {
34
+ method: options.method.toUpperCase(),
35
+ url: options.url,
36
+ headers,
37
+ responseType: window.xnb.http.ResponseType.JSON
38
+ }
39
+
40
+ if (options.query) {
41
+ httpOptions.query = options.query
42
+ }
43
+
44
+ if (options.body !== undefined) {
45
+ httpOptions.body = window.xnb.http.Body.json(options.body)
46
+ }
47
+
48
+ const res: RequestResponse<T> = await window.xnb.http.client.request(httpOptions)
49
+ return res.data
50
+ }
51
+
52
+ export async function get<T = any> (
53
+ url: string,
54
+ query?: Record<string, string | number | boolean | string[] | null | undefined>,
55
+ headers?: Record<string, string>
56
+ ): Promise<T> {
57
+ return request<T>({ method: 'GET', url, query, headers })
58
+ }
59
+
60
+ export async function post<T = any> (
61
+ url: string,
62
+ body?: any,
63
+ headers?: Record<string, string>
64
+ ): Promise<T> {
65
+ return request<T>({ method: 'POST', url, body, headers })
66
+ }
67
+
68
+ export async function put<T = any> (
69
+ url: string,
70
+ body?: any,
71
+ headers?: Record<string, string>
72
+ ): Promise<T> {
73
+ return request<T>({ method: 'PUT', url, body, headers })
74
+ }
75
+
76
+ export async function del<T = any> (
77
+ url: string,
78
+ query?: Record<string, string | number | boolean | string[] | null | undefined>,
79
+ headers?: Record<string, string>
80
+ ): Promise<T> {
81
+ return request<T>({ method: 'DELETE', url, query, headers })
82
+ }
83
+
84
+ export async function patch<T = any> (
85
+ url: string,
86
+ body?: any,
87
+ headers?: Record<string, string>
88
+ ): Promise<T> {
89
+ return request<T>({ method: 'PATCH', url, body, headers })
90
+ }
91
+
92
+ export default request
@@ -1,67 +1,67 @@
1
- <template>
2
- <div class="orbit-quasar-host q-pa-md">
3
- <q-banner v-if="openerInitError" rounded dense class="error-banner q-mb-sm">
4
- {{ openerErrorText }}
5
- </q-banner>
6
-
7
- <div v-if="openerInitReady && props.xnbContext.XNBBitable" class="row items-center q-gutter-xs q-mb-sm flex-wrap">
8
- <span class="text-subtitle2 q-mr-sm">超级表格</span>
9
- <q-btn dense outline label="刷新" :loading="busyRefresh" :disable="!!openerInitError" @click="onRefresh" />
10
- <q-btn dense outline label="检查" :loading="busyCheck" :disable="!!openerInitError" @click="onCheck" />
11
- <q-btn color="primary" dense unelevated label="提交" :loading="busySubmit" :disable="!!openerInitError" @click="onSubmit" />
12
- <span v-if="lastRowCount > 0" class="row-count">{{ lastRowCount }} 条</span>
13
- </div>
14
-
15
- <q-banner v-else-if="openerInitReady && !props.xnbContext.XNBBitable" rounded dense class="info-banner">
16
- 未注入 XNBBitable
17
- </q-banner>
18
- </div>
19
- </template>
20
-
21
- <script lang="ts" setup>
22
- /**
23
- * 模板内演示用超级表格工具栏示例(非业务交付物)。
24
- * lab-orbit-component-builder 技能:向用户目标目录产出时勿原样复制本文件;请按流程文档新建具语义的 `src/views/<业务>.vue` 并参考此处写法。
25
- *
26
- * 刷新 / 提交:在 `useBitablePage` 内经 Quasar 对话框确认后再执行。
27
- */
28
- import { useBitablePage } from '@/use/useBitablePage'
29
- import type { XnbSuperCellContext } from '@/types/xnb-context'
30
-
31
- console.info(`[OrbitComponent] v${__APP_VERSION__} (skill: ${__APP_SKILL__})`)
32
-
33
- const props = defineProps<{
34
- xnbContext: XnbSuperCellContext
35
- }>()
36
-
37
- const {
38
- openerInitReady,
39
- openerInitError,
40
- openerErrorText,
41
- busyRefresh,
42
- busyCheck,
43
- busySubmit,
44
- lastRowCount,
45
- onRefresh,
46
- onCheck,
47
- onSubmit
48
- } = useBitablePage(() => props.xnbContext)
49
- </script>
50
-
51
- <style scoped lang="scss">
52
- @import '@/styles/orbit-quasar-host.scss';
53
-
54
- .error-banner {
55
- background: #FEF2F2;
56
- border-left: 3px solid #ffbe7d;
57
- }
58
- .info-banner {
59
- background: #FFFFFF;
60
- border: 1px solid #E5E5E3;
61
- color: #6B6B6B;
62
- }
63
- .row-count {
64
- font-size: 0.75rem;
65
- color: #6B6B6B;
66
- }
67
- </style>
1
+ <template>
2
+ <div class="orbit-quasar-host q-pa-md">
3
+ <q-banner v-if="openerInitError" rounded dense class="error-banner q-mb-sm">
4
+ {{ openerErrorText }}
5
+ </q-banner>
6
+
7
+ <div v-if="openerInitReady && props.xnbContext.XNBBitable" class="row items-center q-gutter-xs q-mb-sm flex-wrap">
8
+ <span class="text-subtitle2 q-mr-sm">超级表格</span>
9
+ <q-btn dense outline label="刷新" :loading="busyRefresh" :disable="!!openerInitError" @click="onRefresh" />
10
+ <q-btn dense outline label="检查" :loading="busyCheck" :disable="!!openerInitError" @click="onCheck" />
11
+ <q-btn color="primary" dense unelevated label="提交" :loading="busySubmit" :disable="!!openerInitError" @click="onSubmit" />
12
+ <span v-if="lastRowCount > 0" class="row-count">{{ lastRowCount }} 条</span>
13
+ </div>
14
+
15
+ <q-banner v-else-if="openerInitReady && !props.xnbContext.XNBBitable" rounded dense class="info-banner">
16
+ 未注入 XNBBitable
17
+ </q-banner>
18
+ </div>
19
+ </template>
20
+
21
+ <script lang="ts" setup>
22
+ /**
23
+ * 模板内演示用超级表格工具栏示例(非业务交付物)。
24
+ * lab-orbit-component-builder 技能:向用户目标目录产出时勿原样复制本文件;请按流程文档新建具语义的 `src/views/<业务>.vue` 并参考此处写法。
25
+ *
26
+ * 刷新 / 提交:在 `useBitablePage` 内经 Quasar 对话框确认后再执行。
27
+ */
28
+ import { useBitablePage } from '@/use/useBitablePage'
29
+ import type { XnbSuperCellContext } from '@/types/xnb-context'
30
+
31
+ console.info(`[OrbitComponent] v${__APP_VERSION__} (skill: ${__APP_SKILL__})`)
32
+
33
+ const props = defineProps<{
34
+ xnbContext: XnbSuperCellContext
35
+ }>()
36
+
37
+ const {
38
+ openerInitReady,
39
+ openerInitError,
40
+ openerErrorText,
41
+ busyRefresh,
42
+ busyCheck,
43
+ busySubmit,
44
+ lastRowCount,
45
+ onRefresh,
46
+ onCheck,
47
+ onSubmit
48
+ } = useBitablePage(() => props.xnbContext)
49
+ </script>
50
+
51
+ <style scoped lang="scss">
52
+ @import '@/styles/orbit-quasar-host.scss';
53
+
54
+ .error-banner {
55
+ background: #FEF2F2;
56
+ border-left: 3px solid #ffbe7d;
57
+ }
58
+ .info-banner {
59
+ background: #FFFFFF;
60
+ border: 1px solid #E5E5E3;
61
+ color: #6B6B6B;
62
+ }
63
+ .row-count {
64
+ font-size: 0.75rem;
65
+ color: #6B6B6B;
66
+ }
67
+ </style>
@@ -1,140 +1,140 @@
1
- <!--
2
- 模板内演示用多区页面示例(非业务交付物)。
3
- lab-orbit-component-builder 技能:向用户目标目录产出时勿原样复制本文件;请按流程文档新建具语义的 views 与 entries。
4
-
5
- 场景:复杂多组件页面(不使用超级表格 / XNBBitable)
6
- 入口文件名:custom-page.vue(与 xnb-components 中 id 一致)
7
-
8
- 仅占位布局:顶栏 + 侧栏 + 多卡片主区;与 bitable(超级表格 Cell)分离,后续可单独扩展。
9
- -->
10
- <template>
11
- <div class="orbit-quasar-host multi-page-demo">
12
- <header class="demo-header row items-center q-px-md">
13
- <div class="text-weight-medium">自定义多区页面(custom-page)</div>
14
- <q-space />
15
- <q-chip dense outline color="grey-8">无 XNBBitable / 子 Cell</q-chip>
16
- </header>
17
-
18
- <div class="demo-body row no-wrap">
19
- <aside class="demo-aside q-pa-sm">
20
- <div class="text-caption text-grey-7 q-mb-sm">侧栏占位</div>
21
- <q-list bordered separator dense class="rounded-borders bg-white">
22
- <q-item clickable v-ripple v-for="nav in navItems" :key="nav.id">
23
- <q-item-section>{{ nav.label }}</q-item-section>
24
- </q-item>
25
- </q-list>
26
- </aside>
27
-
28
- <main class="demo-main col q-pa-md">
29
- <p class="hint q-mb-md">
30
- 入口文件 <code>src/views/custom-page.vue</code>。用于「多区域、多卡片、无超级表格」类页面;
31
- <code>xnbContext</code> 仍可从宿主注入(见下方节选)。可与
32
- <code>bitable</code> 场景独立演进。
33
- </p>
34
- <div class="row q-col-gutter-md">
35
- <div class="col-12 col-md-4" v-for="card in cards" :key="card.id">
36
- <q-card flat bordered class="full-height">
37
- <q-card-section class="text-subtitle2">{{ card.title }}</q-card-section>
38
- <q-card-section class="text-caption text-grey-7">{{ card.desc }}</q-card-section>
39
- </q-card>
40
- </div>
41
- </div>
42
- <q-expansion-item
43
- class="q-mt-md rounded-borders bordered bg-white"
44
- label="当前 xnbContext(节选)"
45
- header-class="text-body2"
46
- dense
47
- >
48
- <q-card flat>
49
- <q-card-section>
50
- <pre class="ctx-pre">{{ summary }}</pre>
51
- </q-card-section>
52
- </q-card>
53
- </q-expansion-item>
54
- </main>
55
- </div>
56
- </div>
57
- </template>
58
-
59
- <script lang="ts" setup>
60
- import { computed, withDefaults } from 'vue'
61
-
62
- export type XnbContextPageLike = {
63
- bookPath?: string
64
- cellUid?: string
65
- [key: string]: unknown
66
- }
67
-
68
- const props = withDefaults(
69
- defineProps<{
70
- xnbContext?: XnbContextPageLike
71
- }>(),
72
- {
73
- xnbContext: () => ({})
74
- }
75
- )
76
-
77
- const navItems = [
78
- { id: 'a', label: '模块占位 A' },
79
- { id: 'b', label: '模块占位 B' },
80
- { id: 'c', label: '模块占位 C' }
81
- ]
82
-
83
- const cards = [
84
- { id: '1', title: '区域 1', desc: '实际功能组件、表格或图表等可放此处。' },
85
- { id: '2', title: '区域 2', desc: '与区域 1 并列,演示多列布局。' },
86
- { id: '3', title: '区域 3', desc: '后续可替换为真实功能模块。' }
87
- ]
88
-
89
- const summary = computed(() => {
90
- const c = props.xnbContext || {}
91
- return JSON.stringify(
92
- { bookPath: c.bookPath, cellUid: c.cellUid },
93
- null,
94
- 2
95
- )
96
- })
97
- </script>
98
-
99
- <style scoped lang="scss">
100
- @import '@/styles/orbit-quasar-host.scss';
101
-
102
- .multi-page-demo {
103
- box-sizing: border-box;
104
- height: 100%;
105
- display: flex;
106
- flex-direction: column;
107
- font-family: system-ui, -apple-system, sans-serif;
108
- color: #1a1a1a;
109
- }
110
- .demo-header {
111
- min-height: 48px;
112
- border-bottom: 1px solid #e0e0e0;
113
- background: #fafafa;
114
- }
115
- .demo-body {
116
- flex: 1;
117
- min-height: 0;
118
- overflow: auto;
119
- }
120
- .demo-aside {
121
- width: 200px;
122
- flex-shrink: 0;
123
- border-right: 1px solid #e0e0e0;
124
- background: #fcfcfc;
125
- }
126
- .demo-main {
127
- min-width: 0;
128
- }
129
- .hint {
130
- margin: 0;
131
- color: #555;
132
- font-size: 0.9rem;
133
- line-height: 1.5;
134
- }
135
- .ctx-pre {
136
- margin: 0;
137
- font-size: 12px;
138
- overflow: auto;
139
- }
140
- </style>
1
+ <!--
2
+ 模板内演示用多区页面示例(非业务交付物)。
3
+ lab-orbit-component-builder 技能:向用户目标目录产出时勿原样复制本文件;请按流程文档新建具语义的 views 与 entries。
4
+
5
+ 场景:复杂多组件页面(不使用超级表格 / XNBBitable)
6
+ 入口文件名:custom-page.vue(与 xnb-components 中 id 一致)
7
+
8
+ 仅占位布局:顶栏 + 侧栏 + 多卡片主区;与 bitable(超级表格 Cell)分离,后续可单独扩展。
9
+ -->
10
+ <template>
11
+ <div class="orbit-quasar-host multi-page-demo">
12
+ <header class="demo-header row items-center q-px-md">
13
+ <div class="text-weight-medium">自定义多区页面(custom-page)</div>
14
+ <q-space />
15
+ <q-chip dense outline color="grey-8">无 XNBBitable / 子 Cell</q-chip>
16
+ </header>
17
+
18
+ <div class="demo-body row no-wrap">
19
+ <aside class="demo-aside q-pa-sm">
20
+ <div class="text-caption text-grey-7 q-mb-sm">侧栏占位</div>
21
+ <q-list bordered separator dense class="rounded-borders bg-white">
22
+ <q-item clickable v-ripple v-for="nav in navItems" :key="nav.id">
23
+ <q-item-section>{{ nav.label }}</q-item-section>
24
+ </q-item>
25
+ </q-list>
26
+ </aside>
27
+
28
+ <main class="demo-main col q-pa-md">
29
+ <p class="hint q-mb-md">
30
+ 入口文件 <code>src/views/custom-page.vue</code>。用于「多区域、多卡片、无超级表格」类页面;
31
+ <code>xnbContext</code> 仍可从宿主注入(见下方节选)。可与
32
+ <code>bitable</code> 场景独立演进。
33
+ </p>
34
+ <div class="row q-col-gutter-md">
35
+ <div class="col-12 col-md-4" v-for="card in cards" :key="card.id">
36
+ <q-card flat bordered class="full-height">
37
+ <q-card-section class="text-subtitle2">{{ card.title }}</q-card-section>
38
+ <q-card-section class="text-caption text-grey-7">{{ card.desc }}</q-card-section>
39
+ </q-card>
40
+ </div>
41
+ </div>
42
+ <q-expansion-item
43
+ class="q-mt-md rounded-borders bordered bg-white"
44
+ label="当前 xnbContext(节选)"
45
+ header-class="text-body2"
46
+ dense
47
+ >
48
+ <q-card flat>
49
+ <q-card-section>
50
+ <pre class="ctx-pre">{{ summary }}</pre>
51
+ </q-card-section>
52
+ </q-card>
53
+ </q-expansion-item>
54
+ </main>
55
+ </div>
56
+ </div>
57
+ </template>
58
+
59
+ <script lang="ts" setup>
60
+ import { computed, withDefaults } from 'vue'
61
+
62
+ export type XnbContextPageLike = {
63
+ bookPath?: string
64
+ cellUid?: string
65
+ [key: string]: unknown
66
+ }
67
+
68
+ const props = withDefaults(
69
+ defineProps<{
70
+ xnbContext?: XnbContextPageLike
71
+ }>(),
72
+ {
73
+ xnbContext: () => ({})
74
+ }
75
+ )
76
+
77
+ const navItems = [
78
+ { id: 'a', label: '模块占位 A' },
79
+ { id: 'b', label: '模块占位 B' },
80
+ { id: 'c', label: '模块占位 C' }
81
+ ]
82
+
83
+ const cards = [
84
+ { id: '1', title: '区域 1', desc: '实际功能组件、表格或图表等可放此处。' },
85
+ { id: '2', title: '区域 2', desc: '与区域 1 并列,演示多列布局。' },
86
+ { id: '3', title: '区域 3', desc: '后续可替换为真实功能模块。' }
87
+ ]
88
+
89
+ const summary = computed(() => {
90
+ const c = props.xnbContext || {}
91
+ return JSON.stringify(
92
+ { bookPath: c.bookPath, cellUid: c.cellUid },
93
+ null,
94
+ 2
95
+ )
96
+ })
97
+ </script>
98
+
99
+ <style scoped lang="scss">
100
+ @import '@/styles/orbit-quasar-host.scss';
101
+
102
+ .multi-page-demo {
103
+ box-sizing: border-box;
104
+ height: 100%;
105
+ display: flex;
106
+ flex-direction: column;
107
+ font-family: system-ui, -apple-system, sans-serif;
108
+ color: #1a1a1a;
109
+ }
110
+ .demo-header {
111
+ min-height: 48px;
112
+ border-bottom: 1px solid #e0e0e0;
113
+ background: #fafafa;
114
+ }
115
+ .demo-body {
116
+ flex: 1;
117
+ min-height: 0;
118
+ overflow: auto;
119
+ }
120
+ .demo-aside {
121
+ width: 200px;
122
+ flex-shrink: 0;
123
+ border-right: 1px solid #e0e0e0;
124
+ background: #fcfcfc;
125
+ }
126
+ .demo-main {
127
+ min-width: 0;
128
+ }
129
+ .hint {
130
+ margin: 0;
131
+ color: #555;
132
+ font-size: 0.9rem;
133
+ line-height: 1.5;
134
+ }
135
+ .ctx-pre {
136
+ margin: 0;
137
+ font-size: 12px;
138
+ overflow: auto;
139
+ }
140
+ </style>