@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.
- package/README.md +1 -1
- package/package.json +14 -14
- package/skills/lab-flow-designer/SKILL.md +612 -593
- package/skills/lab-flow-designer/embedded-template/SKILL.md +103 -88
- package/skills/lab-flow-designer/embedded-template/pools//345/205/245/345/217/243/346/261/240.md +21 -12
- package/skills/lab-flow-designer/embedded-template/pools//345/207/272/345/217/243/346/261/240.md +21 -12
- 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
- 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
- package/skills/lab-flow-designer/references/agentic-lab-processer.md +122 -78
- package/skills/lab-flow-designer/references/agentic-lab-sdk.md +534 -361
- package/skills/lab-flow-designer/references/rhea-api/README.md +7 -7
- package/skills/lab-flow-designer/references/rhea-api/execute_process_batch.md +58 -58
- package/skills/lab-flow-designer/references/skill-package-layout.md +268 -204
- 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
- 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
- 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
- package/skills/lab-flow-designer/testing/test-processer.mjs +1240 -1075
- package/skills/lab-nocobase-flow-generator/SKILL.md +164 -164
- 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
- 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
- package/skills/lab-nocobase-flow-generator/references/doc-standard.md +84 -84
- package/skills/lab-nocobase-flow-generator/references/runtime-api.md +224 -224
- 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
- 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
- package/skills/lab-orbit-component-builder/SKILL.md +353 -353
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/.env.local.example +27 -27
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/.eslintignore +7 -7
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/.eslintrc.cjs +88 -88
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/.nvmrc +1 -1
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/AgenticAppAPI.md +268 -268
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/Jenkinsfile +106 -106
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/OrbitAPI.md +453 -453
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/README.md +176 -176
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/public/index.html +12 -12
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/App.vue +151 -151
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/components/DevOpenerLauncher.vue +143 -143
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/global.d.ts +77 -77
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/main.ts +308 -308
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/mockXNBBitable.ts +119 -119
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/shims-vue.d.ts +6 -6
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/utils/devOpenerHost.ts +75 -75
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/index.html +13 -13
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/package.json +60 -60
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/api/agenticlabTickets.ts +110 -110
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/entries/bitable.ts +4 -4
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/entries/custom-page.ts +4 -4
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/index.ts +1 -1
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/styles/orbit-quasar-host.scss +19 -19
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/types/context.ts +15 -15
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/types/xnb-context.ts +70 -70
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useBitablePage.ts +189 -189
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useSuperCellDemo.ts +257 -257
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useSuperTableBitableLifecycle.ts +555 -555
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/openerInitParams.ts +158 -158
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/openerTicketIds.ts +32 -32
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/orbitHttpClient.ts +110 -110
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/request.ts +92 -92
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/views/bitable.vue +67 -67
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/views/custom-page.vue +140 -140
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/tsconfig.json +45 -45
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/vite.config.ts +170 -170
- package/skills/lab-orbit-component-builder/examples/xnb-component-template/vite.dev.config.ts +58 -58
- package/skills/lab-orbit-component-builder/references/flow-document-human-ui.md +65 -65
- package/skills/lab-orbit-component-builder/references/orbit-vue-conventions.md +133 -133
- package/skills/lab-orbit-component-builder/references/pool-schema-to-columns.md +67 -67
- package/skills/lab-orbit-component-builder/references/vue-template-checklist.md +179 -179
- package/skills/lab-orbit-component-builder/references/xnb-context-vue-props.md +49 -49
- package/skills/lab-orbit-component-builder/references/xnbitable-vue-parity.md +32 -32
|
@@ -1,151 +1,151 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="dev-shell" :class="{ 'dev-shell--child': isChildPage }">
|
|
3
|
-
<DevOpenerLauncher v-if="!isChildPage" class="dev-shell__launcher" />
|
|
4
|
-
<q-banner v-else rounded dense class="dev-child-hint q-ma-sm">
|
|
5
|
-
Opener 子页联调 · trace: <code>{{ childTrace }}</code> — 初始化结果见下方组件(成功则出现刷新/提交按钮)
|
|
6
|
-
</q-banner>
|
|
7
|
-
<div class="entry">
|
|
8
|
-
<View ref="sheetRef" :xnbContext="xnbContext" />
|
|
9
|
-
</div>
|
|
10
|
-
</div>
|
|
11
|
-
</template>
|
|
12
|
-
|
|
13
|
-
<script lang="ts">
|
|
14
|
-
import { computed, defineComponent, reactive, ref } from 'vue'
|
|
15
|
-
import { Notify, Loading } from 'quasar'
|
|
16
|
-
import { DevXNBBitable } from './mockXNBBitable'
|
|
17
|
-
import DevOpenerLauncher from './components/DevOpenerLauncher.vue'
|
|
18
|
-
import { isDevOpenerChildPage } from './utils/devOpenerHost'
|
|
19
|
-
|
|
20
|
-
export default defineComponent({
|
|
21
|
-
components: { DevOpenerLauncher },
|
|
22
|
-
setup () {
|
|
23
|
-
const isChildPage = isDevOpenerChildPage()
|
|
24
|
-
const childTrace = computed(() => new URLSearchParams(window.location.search).get('trace') || '—')
|
|
25
|
-
const cellParams = reactive({
|
|
26
|
-
bookPath: '/dev/notebook/doe',
|
|
27
|
-
uid: 'dev-cell-001'
|
|
28
|
-
})
|
|
29
|
-
const viewRef = ref()
|
|
30
|
-
|
|
31
|
-
const DEV_REQUEST_URL = import.meta.env.VITE_REQUEST_URL || ''
|
|
32
|
-
|
|
33
|
-
const userData: Record<string, any> = {
|
|
34
|
-
projectURL: JSON.stringify({ request_url: DEV_REQUEST_URL })
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const xnbContext = {
|
|
38
|
-
bookPath: cellParams.bookPath,
|
|
39
|
-
cellUid: cellParams.uid,
|
|
40
|
-
XNBUtil: {
|
|
41
|
-
async getWikiTables (_url: string): Promise<any> {
|
|
42
|
-
return { bitable: 'dev-bitable', tables: [] }
|
|
43
|
-
},
|
|
44
|
-
async getLarkBitableById (_bitable: string, _tableId: string, _opts?: any): Promise<any[]> {
|
|
45
|
-
return []
|
|
46
|
-
},
|
|
47
|
-
async batchCreateRecords (_opts: any): Promise<any> {
|
|
48
|
-
return { records: [] }
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
notifySuccess (msg: string): void {
|
|
52
|
-
Notify.create({ type: 'positive', message: String(msg), position: 'top', timeout: 3000 })
|
|
53
|
-
},
|
|
54
|
-
notifyError (msg: any): void {
|
|
55
|
-
const text = msg instanceof Error ? msg.message : String(msg)
|
|
56
|
-
Notify.create({ type: 'negative', message: text, position: 'top', timeout: 5000 })
|
|
57
|
-
},
|
|
58
|
-
loadingShow (opts?: any): void {
|
|
59
|
-
Loading.show(typeof opts === 'string' ? { message: opts } : opts)
|
|
60
|
-
},
|
|
61
|
-
loadingHide (): void {
|
|
62
|
-
Loading.hide()
|
|
63
|
-
},
|
|
64
|
-
userData,
|
|
65
|
-
getUserData (): Record<string, any> {
|
|
66
|
-
return userData
|
|
67
|
-
},
|
|
68
|
-
updateUserData (data: any): void {
|
|
69
|
-
Object.assign(userData, data)
|
|
70
|
-
},
|
|
71
|
-
mergeUserData (data: any): void {
|
|
72
|
-
Object.assign(userData, data)
|
|
73
|
-
},
|
|
74
|
-
getInstanceById (_id: string): any { return null },
|
|
75
|
-
getInstanceValueById (_id: string): any { return null },
|
|
76
|
-
setInstanceValueById (_id: string, _value: any): void { /* noop */ },
|
|
77
|
-
async saveBitableConfig (_bitable: Record<string, any>): Promise<void> {
|
|
78
|
-
localStorage.setItem('DEV_BITABLE_CONFIG', JSON.stringify(_bitable))
|
|
79
|
-
},
|
|
80
|
-
async getBitableConfig (): Promise<string> {
|
|
81
|
-
return localStorage.getItem('DEV_BITABLE_CONFIG') || '{}'
|
|
82
|
-
},
|
|
83
|
-
XNBBitable: DevXNBBitable
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
window.xnb.store.set('params', cellParams)
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
isChildPage,
|
|
90
|
-
childTrace,
|
|
91
|
-
cellParams,
|
|
92
|
-
viewRef,
|
|
93
|
-
xnbContext
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
})
|
|
97
|
-
</script>
|
|
98
|
-
|
|
99
|
-
<style lang="scss">
|
|
100
|
-
html,
|
|
101
|
-
body,
|
|
102
|
-
#app {
|
|
103
|
-
margin: 0;
|
|
104
|
-
padding: 0;
|
|
105
|
-
height: 100%;
|
|
106
|
-
width: 100%;
|
|
107
|
-
overflow: hidden;
|
|
108
|
-
box-sizing: border-box;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
#app {
|
|
112
|
-
font-family: Arial, Helvetica, sans-serif;
|
|
113
|
-
-webkit-font-smoothing: antialiased;
|
|
114
|
-
-moz-osx-font-smoothing: grayscale;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.dev-shell {
|
|
118
|
-
display: flex;
|
|
119
|
-
flex-direction: column;
|
|
120
|
-
height: 100%;
|
|
121
|
-
width: 100%;
|
|
122
|
-
box-sizing: border-box;
|
|
123
|
-
&--child .entry {
|
|
124
|
-
flex: 1;
|
|
125
|
-
min-height: 0;
|
|
126
|
-
}
|
|
127
|
-
&__launcher {
|
|
128
|
-
flex-shrink: 0;
|
|
129
|
-
margin: 8px 8px 0;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.dev-child-hint {
|
|
134
|
-
flex-shrink: 0;
|
|
135
|
-
background: #fffbeb;
|
|
136
|
-
border: 1px solid #f0e4b8;
|
|
137
|
-
code {
|
|
138
|
-
font-size: 0.75rem;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
.entry {
|
|
143
|
-
font-family: Arial, Helvetica, sans-serif;
|
|
144
|
-
box-sizing: border-box;
|
|
145
|
-
flex: 1;
|
|
146
|
-
min-height: 0;
|
|
147
|
-
width: 100%;
|
|
148
|
-
margin: 0;
|
|
149
|
-
overflow-y: auto;
|
|
150
|
-
}
|
|
151
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div class="dev-shell" :class="{ 'dev-shell--child': isChildPage }">
|
|
3
|
+
<DevOpenerLauncher v-if="!isChildPage" class="dev-shell__launcher" />
|
|
4
|
+
<q-banner v-else rounded dense class="dev-child-hint q-ma-sm">
|
|
5
|
+
Opener 子页联调 · trace: <code>{{ childTrace }}</code> — 初始化结果见下方组件(成功则出现刷新/提交按钮)
|
|
6
|
+
</q-banner>
|
|
7
|
+
<div class="entry">
|
|
8
|
+
<View ref="sheetRef" :xnbContext="xnbContext" />
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import { computed, defineComponent, reactive, ref } from 'vue'
|
|
15
|
+
import { Notify, Loading } from 'quasar'
|
|
16
|
+
import { DevXNBBitable } from './mockXNBBitable'
|
|
17
|
+
import DevOpenerLauncher from './components/DevOpenerLauncher.vue'
|
|
18
|
+
import { isDevOpenerChildPage } from './utils/devOpenerHost'
|
|
19
|
+
|
|
20
|
+
export default defineComponent({
|
|
21
|
+
components: { DevOpenerLauncher },
|
|
22
|
+
setup () {
|
|
23
|
+
const isChildPage = isDevOpenerChildPage()
|
|
24
|
+
const childTrace = computed(() => new URLSearchParams(window.location.search).get('trace') || '—')
|
|
25
|
+
const cellParams = reactive({
|
|
26
|
+
bookPath: '/dev/notebook/doe',
|
|
27
|
+
uid: 'dev-cell-001'
|
|
28
|
+
})
|
|
29
|
+
const viewRef = ref()
|
|
30
|
+
|
|
31
|
+
const DEV_REQUEST_URL = import.meta.env.VITE_REQUEST_URL || ''
|
|
32
|
+
|
|
33
|
+
const userData: Record<string, any> = {
|
|
34
|
+
projectURL: JSON.stringify({ request_url: DEV_REQUEST_URL })
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const xnbContext = {
|
|
38
|
+
bookPath: cellParams.bookPath,
|
|
39
|
+
cellUid: cellParams.uid,
|
|
40
|
+
XNBUtil: {
|
|
41
|
+
async getWikiTables (_url: string): Promise<any> {
|
|
42
|
+
return { bitable: 'dev-bitable', tables: [] }
|
|
43
|
+
},
|
|
44
|
+
async getLarkBitableById (_bitable: string, _tableId: string, _opts?: any): Promise<any[]> {
|
|
45
|
+
return []
|
|
46
|
+
},
|
|
47
|
+
async batchCreateRecords (_opts: any): Promise<any> {
|
|
48
|
+
return { records: [] }
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
notifySuccess (msg: string): void {
|
|
52
|
+
Notify.create({ type: 'positive', message: String(msg), position: 'top', timeout: 3000 })
|
|
53
|
+
},
|
|
54
|
+
notifyError (msg: any): void {
|
|
55
|
+
const text = msg instanceof Error ? msg.message : String(msg)
|
|
56
|
+
Notify.create({ type: 'negative', message: text, position: 'top', timeout: 5000 })
|
|
57
|
+
},
|
|
58
|
+
loadingShow (opts?: any): void {
|
|
59
|
+
Loading.show(typeof opts === 'string' ? { message: opts } : opts)
|
|
60
|
+
},
|
|
61
|
+
loadingHide (): void {
|
|
62
|
+
Loading.hide()
|
|
63
|
+
},
|
|
64
|
+
userData,
|
|
65
|
+
getUserData (): Record<string, any> {
|
|
66
|
+
return userData
|
|
67
|
+
},
|
|
68
|
+
updateUserData (data: any): void {
|
|
69
|
+
Object.assign(userData, data)
|
|
70
|
+
},
|
|
71
|
+
mergeUserData (data: any): void {
|
|
72
|
+
Object.assign(userData, data)
|
|
73
|
+
},
|
|
74
|
+
getInstanceById (_id: string): any { return null },
|
|
75
|
+
getInstanceValueById (_id: string): any { return null },
|
|
76
|
+
setInstanceValueById (_id: string, _value: any): void { /* noop */ },
|
|
77
|
+
async saveBitableConfig (_bitable: Record<string, any>): Promise<void> {
|
|
78
|
+
localStorage.setItem('DEV_BITABLE_CONFIG', JSON.stringify(_bitable))
|
|
79
|
+
},
|
|
80
|
+
async getBitableConfig (): Promise<string> {
|
|
81
|
+
return localStorage.getItem('DEV_BITABLE_CONFIG') || '{}'
|
|
82
|
+
},
|
|
83
|
+
XNBBitable: DevXNBBitable
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
window.xnb.store.set('params', cellParams)
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
isChildPage,
|
|
90
|
+
childTrace,
|
|
91
|
+
cellParams,
|
|
92
|
+
viewRef,
|
|
93
|
+
xnbContext
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
</script>
|
|
98
|
+
|
|
99
|
+
<style lang="scss">
|
|
100
|
+
html,
|
|
101
|
+
body,
|
|
102
|
+
#app {
|
|
103
|
+
margin: 0;
|
|
104
|
+
padding: 0;
|
|
105
|
+
height: 100%;
|
|
106
|
+
width: 100%;
|
|
107
|
+
overflow: hidden;
|
|
108
|
+
box-sizing: border-box;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
#app {
|
|
112
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
113
|
+
-webkit-font-smoothing: antialiased;
|
|
114
|
+
-moz-osx-font-smoothing: grayscale;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.dev-shell {
|
|
118
|
+
display: flex;
|
|
119
|
+
flex-direction: column;
|
|
120
|
+
height: 100%;
|
|
121
|
+
width: 100%;
|
|
122
|
+
box-sizing: border-box;
|
|
123
|
+
&--child .entry {
|
|
124
|
+
flex: 1;
|
|
125
|
+
min-height: 0;
|
|
126
|
+
}
|
|
127
|
+
&__launcher {
|
|
128
|
+
flex-shrink: 0;
|
|
129
|
+
margin: 8px 8px 0;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.dev-child-hint {
|
|
134
|
+
flex-shrink: 0;
|
|
135
|
+
background: #fffbeb;
|
|
136
|
+
border: 1px solid #f0e4b8;
|
|
137
|
+
code {
|
|
138
|
+
font-size: 0.75rem;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.entry {
|
|
143
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
144
|
+
box-sizing: border-box;
|
|
145
|
+
flex: 1;
|
|
146
|
+
min-height: 0;
|
|
147
|
+
width: 100%;
|
|
148
|
+
margin: 0;
|
|
149
|
+
overflow-y: auto;
|
|
150
|
+
}
|
|
151
|
+
</style>
|
|
@@ -1,143 +1,143 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<q-banner rounded dense class="dev-opener-launcher q-mb-sm">
|
|
3
|
-
<div class="text-subtitle2 q-mb-xs">Opener 联调(模拟宿主打开子页)</div>
|
|
4
|
-
<p class="text-caption text-grey-8 q-mb-sm">
|
|
5
|
-
点击下方按钮在新窗口打开子页;子页通过 <code>?trace=</code> 与 <code>postMessage</code> 拉取下方 JSON。
|
|
6
|
-
组件:<strong>{{ componentId }}</strong>
|
|
7
|
-
</p>
|
|
8
|
-
<q-input
|
|
9
|
-
v-model="payloadText"
|
|
10
|
-
type="textarea"
|
|
11
|
-
autogrow
|
|
12
|
-
dense
|
|
13
|
-
outlined
|
|
14
|
-
label="模拟 opener payload(JSON)"
|
|
15
|
-
:error="parseError != null"
|
|
16
|
-
:error-message="parseError || undefined"
|
|
17
|
-
class="q-mb-sm"
|
|
18
|
-
/>
|
|
19
|
-
<div class="row items-center q-gutter-sm flex-wrap">
|
|
20
|
-
<q-btn
|
|
21
|
-
color="primary"
|
|
22
|
-
dense
|
|
23
|
-
unelevated
|
|
24
|
-
label="以 opener 方式打开子页"
|
|
25
|
-
:disable="parseError != null"
|
|
26
|
-
@click="onOpenChild"
|
|
27
|
-
/>
|
|
28
|
-
<span v-if="lastTrace" class="text-caption text-grey-7">
|
|
29
|
-
最近 trace: <code>{{ lastTrace }}</code>
|
|
30
|
-
<span v-if="childBlocked" class="text-negative">(弹窗被拦截,请允许本站点弹窗)</span>
|
|
31
|
-
</span>
|
|
32
|
-
</div>
|
|
33
|
-
</q-banner>
|
|
34
|
-
</template>
|
|
35
|
-
|
|
36
|
-
<script lang="ts">
|
|
37
|
-
import { defineComponent, onMounted, onUnmounted, ref, watch } from 'vue'
|
|
38
|
-
import { parseDevOpenerInitFromEnv } from '@/utils/openerInitParams'
|
|
39
|
-
import {
|
|
40
|
-
createDevOpenerTrace,
|
|
41
|
-
installDevOpenerHost,
|
|
42
|
-
openDevOpenerChild
|
|
43
|
-
} from '../utils/devOpenerHost'
|
|
44
|
-
import type { DevOpenerHostHandle } from '../utils/devOpenerHost'
|
|
45
|
-
|
|
46
|
-
const DEFAULT_PAYLOAD = {
|
|
47
|
-
ticket_ids: [450, 453],
|
|
48
|
-
valve_id: 0
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function defaultPayloadText (): string {
|
|
52
|
-
const fromEnv = parseDevOpenerInitFromEnv()
|
|
53
|
-
if (fromEnv != null) {
|
|
54
|
-
try {
|
|
55
|
-
return JSON.stringify(fromEnv, null, 2)
|
|
56
|
-
} catch {
|
|
57
|
-
/* fall through */
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return JSON.stringify(DEFAULT_PAYLOAD, null, 2)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function parsePayloadJson (text: string): { value: unknown | null; error: string | null } {
|
|
64
|
-
const trimmed = text.trim()
|
|
65
|
-
if (trimmed === '') return { value: null, error: 'JSON 不能为空' }
|
|
66
|
-
try {
|
|
67
|
-
return { value: JSON.parse(trimmed) as unknown, error: null }
|
|
68
|
-
} catch {
|
|
69
|
-
return { value: null, error: '不是合法 JSON' }
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export default defineComponent({
|
|
74
|
-
name: 'DevOpenerLauncher',
|
|
75
|
-
setup () {
|
|
76
|
-
const componentId = import.meta.env.VITE_COMPONENT_ID || 'bitable'
|
|
77
|
-
const payloadText = ref(defaultPayloadText())
|
|
78
|
-
const parseError = ref<string | null>(null)
|
|
79
|
-
const lastTrace = ref<string | null>(null)
|
|
80
|
-
const childBlocked = ref(false)
|
|
81
|
-
|
|
82
|
-
let hostHandle: DevOpenerHostHandle | null = null
|
|
83
|
-
|
|
84
|
-
function syncParseError (): void {
|
|
85
|
-
parseError.value = parsePayloadJson(payloadText.value).error
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function getPayload (): unknown {
|
|
89
|
-
const { value, error } = parsePayloadJson(payloadText.value)
|
|
90
|
-
if (error != null) throw new Error(error)
|
|
91
|
-
return value
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function onOpenChild (): void {
|
|
95
|
-
syncParseError()
|
|
96
|
-
if (parseError.value != null) return
|
|
97
|
-
|
|
98
|
-
const trace = createDevOpenerTrace()
|
|
99
|
-
lastTrace.value = trace
|
|
100
|
-
childBlocked.value = false
|
|
101
|
-
|
|
102
|
-
const child = openDevOpenerChild(trace)
|
|
103
|
-
if (child == null) {
|
|
104
|
-
childBlocked.value = true
|
|
105
|
-
console.warn('[devOpenerHost] window.open 返回 null,可能被浏览器拦截')
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
watch(payloadText, () => {
|
|
110
|
-
syncParseError()
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
onMounted(() => {
|
|
114
|
-
syncParseError()
|
|
115
|
-
hostHandle = installDevOpenerHost(() => getPayload())
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
onUnmounted(() => {
|
|
119
|
-
hostHandle?.dispose()
|
|
120
|
-
hostHandle = null
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
componentId,
|
|
125
|
-
payloadText,
|
|
126
|
-
parseError,
|
|
127
|
-
lastTrace,
|
|
128
|
-
childBlocked,
|
|
129
|
-
onOpenChild
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
})
|
|
133
|
-
</script>
|
|
134
|
-
|
|
135
|
-
<style scoped lang="scss">
|
|
136
|
-
.dev-opener-launcher {
|
|
137
|
-
background: #f0f7ff;
|
|
138
|
-
border: 1px solid #c5d9f0;
|
|
139
|
-
code {
|
|
140
|
-
font-size: 0.75rem;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<q-banner rounded dense class="dev-opener-launcher q-mb-sm">
|
|
3
|
+
<div class="text-subtitle2 q-mb-xs">Opener 联调(模拟宿主打开子页)</div>
|
|
4
|
+
<p class="text-caption text-grey-8 q-mb-sm">
|
|
5
|
+
点击下方按钮在新窗口打开子页;子页通过 <code>?trace=</code> 与 <code>postMessage</code> 拉取下方 JSON。
|
|
6
|
+
组件:<strong>{{ componentId }}</strong>
|
|
7
|
+
</p>
|
|
8
|
+
<q-input
|
|
9
|
+
v-model="payloadText"
|
|
10
|
+
type="textarea"
|
|
11
|
+
autogrow
|
|
12
|
+
dense
|
|
13
|
+
outlined
|
|
14
|
+
label="模拟 opener payload(JSON)"
|
|
15
|
+
:error="parseError != null"
|
|
16
|
+
:error-message="parseError || undefined"
|
|
17
|
+
class="q-mb-sm"
|
|
18
|
+
/>
|
|
19
|
+
<div class="row items-center q-gutter-sm flex-wrap">
|
|
20
|
+
<q-btn
|
|
21
|
+
color="primary"
|
|
22
|
+
dense
|
|
23
|
+
unelevated
|
|
24
|
+
label="以 opener 方式打开子页"
|
|
25
|
+
:disable="parseError != null"
|
|
26
|
+
@click="onOpenChild"
|
|
27
|
+
/>
|
|
28
|
+
<span v-if="lastTrace" class="text-caption text-grey-7">
|
|
29
|
+
最近 trace: <code>{{ lastTrace }}</code>
|
|
30
|
+
<span v-if="childBlocked" class="text-negative">(弹窗被拦截,请允许本站点弹窗)</span>
|
|
31
|
+
</span>
|
|
32
|
+
</div>
|
|
33
|
+
</q-banner>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script lang="ts">
|
|
37
|
+
import { defineComponent, onMounted, onUnmounted, ref, watch } from 'vue'
|
|
38
|
+
import { parseDevOpenerInitFromEnv } from '@/utils/openerInitParams'
|
|
39
|
+
import {
|
|
40
|
+
createDevOpenerTrace,
|
|
41
|
+
installDevOpenerHost,
|
|
42
|
+
openDevOpenerChild
|
|
43
|
+
} from '../utils/devOpenerHost'
|
|
44
|
+
import type { DevOpenerHostHandle } from '../utils/devOpenerHost'
|
|
45
|
+
|
|
46
|
+
const DEFAULT_PAYLOAD = {
|
|
47
|
+
ticket_ids: [450, 453],
|
|
48
|
+
valve_id: 0
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function defaultPayloadText (): string {
|
|
52
|
+
const fromEnv = parseDevOpenerInitFromEnv()
|
|
53
|
+
if (fromEnv != null) {
|
|
54
|
+
try {
|
|
55
|
+
return JSON.stringify(fromEnv, null, 2)
|
|
56
|
+
} catch {
|
|
57
|
+
/* fall through */
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return JSON.stringify(DEFAULT_PAYLOAD, null, 2)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function parsePayloadJson (text: string): { value: unknown | null; error: string | null } {
|
|
64
|
+
const trimmed = text.trim()
|
|
65
|
+
if (trimmed === '') return { value: null, error: 'JSON 不能为空' }
|
|
66
|
+
try {
|
|
67
|
+
return { value: JSON.parse(trimmed) as unknown, error: null }
|
|
68
|
+
} catch {
|
|
69
|
+
return { value: null, error: '不是合法 JSON' }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default defineComponent({
|
|
74
|
+
name: 'DevOpenerLauncher',
|
|
75
|
+
setup () {
|
|
76
|
+
const componentId = import.meta.env.VITE_COMPONENT_ID || 'bitable'
|
|
77
|
+
const payloadText = ref(defaultPayloadText())
|
|
78
|
+
const parseError = ref<string | null>(null)
|
|
79
|
+
const lastTrace = ref<string | null>(null)
|
|
80
|
+
const childBlocked = ref(false)
|
|
81
|
+
|
|
82
|
+
let hostHandle: DevOpenerHostHandle | null = null
|
|
83
|
+
|
|
84
|
+
function syncParseError (): void {
|
|
85
|
+
parseError.value = parsePayloadJson(payloadText.value).error
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function getPayload (): unknown {
|
|
89
|
+
const { value, error } = parsePayloadJson(payloadText.value)
|
|
90
|
+
if (error != null) throw new Error(error)
|
|
91
|
+
return value
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function onOpenChild (): void {
|
|
95
|
+
syncParseError()
|
|
96
|
+
if (parseError.value != null) return
|
|
97
|
+
|
|
98
|
+
const trace = createDevOpenerTrace()
|
|
99
|
+
lastTrace.value = trace
|
|
100
|
+
childBlocked.value = false
|
|
101
|
+
|
|
102
|
+
const child = openDevOpenerChild(trace)
|
|
103
|
+
if (child == null) {
|
|
104
|
+
childBlocked.value = true
|
|
105
|
+
console.warn('[devOpenerHost] window.open 返回 null,可能被浏览器拦截')
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
watch(payloadText, () => {
|
|
110
|
+
syncParseError()
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
onMounted(() => {
|
|
114
|
+
syncParseError()
|
|
115
|
+
hostHandle = installDevOpenerHost(() => getPayload())
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
onUnmounted(() => {
|
|
119
|
+
hostHandle?.dispose()
|
|
120
|
+
hostHandle = null
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
componentId,
|
|
125
|
+
payloadText,
|
|
126
|
+
parseError,
|
|
127
|
+
lastTrace,
|
|
128
|
+
childBlocked,
|
|
129
|
+
onOpenChild
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
</script>
|
|
134
|
+
|
|
135
|
+
<style scoped lang="scss">
|
|
136
|
+
.dev-opener-launcher {
|
|
137
|
+
background: #f0f7ff;
|
|
138
|
+
border: 1px solid #c5d9f0;
|
|
139
|
+
code {
|
|
140
|
+
font-size: 0.75rem;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
</style>
|