@axewo/fin-micro 0.0.0-stage → 1.0.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.
- package/README.md +125 -2
- package/cli/index.mjs +240 -0
- package/dist/browser.cjs +1 -0
- package/dist/browser.mjs +167 -0
- package/dist/core.cjs +1 -0
- package/dist/core.mjs +640 -0
- package/dist/iframe.cjs +1 -0
- package/dist/iframe.mjs +146 -0
- package/dist/index.cjs +1 -0
- package/dist/index.mjs +28 -0
- package/dist/router-view-impl-C1KG6mxu.mjs +76 -0
- package/dist/router-view-impl-CgLEalx4.cjs +1 -0
- package/dist/runtime.cjs +1 -0
- package/dist/runtime.mjs +148 -0
- package/dist/sdk.cjs +1 -0
- package/dist/sdk.mjs +82 -0
- package/dist/types/browser/index.d.ts +42 -0
- package/dist/types/core/index.d.ts +63 -0
- package/dist/types/iframe/index.d.ts +77 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/runtime/index.d.ts +21 -0
- package/dist/types/runtime/lifecycle.d.ts +23 -0
- package/dist/types/sdk/index.d.ts +338 -0
- package/dist/types/vue/index.d.ts +91 -0
- package/dist/types/vue/router-view-impl.d.ts +41 -0
- package/dist/types/vue/router-view.d.ts +42 -0
- package/dist/types/vue/tab-context.d.ts +6 -0
- package/dist/vue.cjs +1 -0
- package/dist/vue.mjs +166 -0
- package/package.json +91 -3
- package/scaffold/base/index.html +12 -0
- package/scaffold/base/package.json.template +29 -0
- package/scaffold/base/src/components/.gitkeep +1 -0
- package/scaffold/base/src/components/AppProviders.vue +25 -0
- package/scaffold/base/src/hooks/.gitkeep +1 -0
- package/scaffold/base/src/layout/.gitkeep +1 -0
- package/scaffold/base/src/locales/.gitkeep +1 -0
- package/scaffold/base/src/locales/index.ts +7 -0
- package/scaffold/base/src/main.ts +14 -0
- package/scaffold/base/src/router/.gitkeep +1 -0
- package/scaffold/base/src/stores/.gitkeep +1 -0
- package/scaffold/base/src/styles/index.css +18 -0
- package/scaffold/base/src/types/.gitkeep +1 -0
- package/scaffold/base/src/utils/.gitkeep +1 -0
- package/scaffold/base/src/utils/requestUtils.ts +123 -0
- package/scaffold/base/src/views/.gitkeep +1 -0
- package/scaffold/base/tsconfig.json +16 -0
- package/scaffold/base/vite.config.ts +8 -0
- package/scaffold/host/.env.example +5 -0
- package/scaffold/host/src/App.vue +16 -0
- package/scaffold/host/src/bootstrap.ts +18 -0
- package/scaffold/host/src/hooks/usePlatformSession.ts +59 -0
- package/scaffold/host/src/layout/HostHeader.vue +9 -0
- package/scaffold/host/src/layout/HostLayout.vue +124 -0
- package/scaffold/host/src/layout/HostMenu.vue +14 -0
- package/scaffold/host/src/layout/HostTabs.vue +14 -0
- package/scaffold/host/src/layout/HostWorkspace.vue +14 -0
- package/scaffold/host/src/platform.ts +208 -0
- package/scaffold/host/src/types/platform.ts +12 -0
- package/scaffold/host/src/utils/request.ts +15 -0
- package/scaffold/host/src/views/LoginView.vue +38 -0
- package/scaffold/vue/src/App.vue +24 -0
- package/scaffold/vue/src/bootstrap.ts +71 -0
- package/scaffold/vue/src/bridge/session.ts +16 -0
- package/scaffold/vue/src/main.ts +10 -0
- package/scaffold/vue/src/router/index.ts +14 -0
- package/scaffold/vue/src/views/DetailView.vue +48 -0
- package/scaffold/vue/src/views/ListView.vue +51 -0
- package/scaffold/vue/src/views/NotFoundView.vue +1 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createMemoryHistory, createRouter, createWebHashHistory } from 'vue-router'
|
|
2
|
+
|
|
3
|
+
/** 嵌入模式使用 memory history 不争用宿主 URL;独立模式使用 hash 路由便于静态部署。 */
|
|
4
|
+
export function createMicroRouter(embedded: boolean) {
|
|
5
|
+
return createRouter({
|
|
6
|
+
history: embedded ? createMemoryHistory() : createWebHashHistory(),
|
|
7
|
+
routes: [
|
|
8
|
+
{ path: '/', redirect: '/list' },
|
|
9
|
+
{ path: '/list', component: () => import('../views/ListView.vue') },
|
|
10
|
+
{ path: '/detail', component: () => import('../views/DetailView.vue') },
|
|
11
|
+
{ path: '/:pathMatch(.*)*', component: () => import('../views/NotFoundView.vue') },
|
|
12
|
+
],
|
|
13
|
+
})
|
|
14
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import { useRoute, useRouter } from 'vue-router'
|
|
4
|
+
import { useMicroPage, useMicroTab } from '@axewo/fin-micro'
|
|
5
|
+
import { useBridgeSession } from '../bridge/session'
|
|
6
|
+
const { bridge } = useBridgeSession()
|
|
7
|
+
const tab = bridge ? useMicroTab() : undefined
|
|
8
|
+
const sdk = bridge && tab ? useMicroPage(bridge, tab) : undefined
|
|
9
|
+
const route = useRoute()
|
|
10
|
+
const router = useRouter()
|
|
11
|
+
const draft = ref('')
|
|
12
|
+
const dirty = ref(false)
|
|
13
|
+
const message = ref('')
|
|
14
|
+
// 缓存停用不注销守卫;关闭非活动脏页也必须确认。浏览器退出与 LRU 淘汰仍需业务持久化保护。
|
|
15
|
+
// useMicroPage 在真正卸载时统一 dispose,会释放本 SDK 注册的守卫,无需再登记重复清理钩子。
|
|
16
|
+
sdk?.beforeLeave(() => !dirty.value || window.confirm('存在未保存的演示草稿,确认离开?'))
|
|
17
|
+
|
|
18
|
+
/** 仅演示标记已保存,不宣称写入后台;真实业务必须 await 保存成功后才清除 dirty。 */
|
|
19
|
+
function save(): void { dirty.value = false; message.value = '演示草稿已标记保存,未写入服务器' }
|
|
20
|
+
|
|
21
|
+
/** SDK 固定绑定创建时的原页面,即使等待期间切换页签,也不关闭或刷新其他页面。 */
|
|
22
|
+
async function action(type: 'close' | 'refresh' | 'back'): Promise<void> {
|
|
23
|
+
try {
|
|
24
|
+
if (!sdk) {
|
|
25
|
+
if (type === 'refresh') { draft.value = ''; dirty.value = false }
|
|
26
|
+
else if (!dirty.value || window.confirm('确认丢弃演示草稿?')) await router.push('/list')
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
if (type === 'close') await sdk.closeCurrent()
|
|
30
|
+
else if (type === 'refresh') await sdk.refreshCurrent()
|
|
31
|
+
else await sdk.back()
|
|
32
|
+
} catch (error) { message.value = String(error) }
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
35
|
+
<template>
|
|
36
|
+
<section class="panel">
|
|
37
|
+
<h2>详情 {{ route.query.id }}</h2>
|
|
38
|
+
<p>切换宿主页签保留草稿;刷新/关闭只影响本页生命周期。</p>
|
|
39
|
+
<el-input v-model="draft" type="textarea" placeholder="编辑演示草稿" @input="dirty = true" />
|
|
40
|
+
<div class="actions">
|
|
41
|
+
<el-button type="primary" @click="save">标记保存(演示)</el-button>
|
|
42
|
+
<el-button @click="action('refresh')">刷新本页</el-button>
|
|
43
|
+
<el-button @click="action('close')">关闭本页</el-button>
|
|
44
|
+
<el-button @click="action('back')">返回来源</el-button>
|
|
45
|
+
</div>
|
|
46
|
+
<p role="status">{{ dirty ? '存在未保存草稿' : '无未保存草稿' }} · {{ message }}</p>
|
|
47
|
+
</section>
|
|
48
|
+
</template>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import { useRouter } from 'vue-router'
|
|
4
|
+
import { FCrudTable, type TableConfig } from '@axewo/fin-ui'
|
|
5
|
+
import { useMicroPage, useMicroTab } from '@axewo/fin-micro'
|
|
6
|
+
import { useBridgeSession } from '../bridge/session'
|
|
7
|
+
const { bridge } = useBridgeSession()
|
|
8
|
+
const router = useRouter()
|
|
9
|
+
// SDK 在 setup 中绑定缓存边界的固定 tab.key;后续异步操作不会误操作另一个活动页。
|
|
10
|
+
const tab = bridge ? useMicroTab() : undefined
|
|
11
|
+
const sdk = bridge && tab ? useMicroPage(bridge, tab) : undefined
|
|
12
|
+
const message = ref('')
|
|
13
|
+
/** 组件异常只展示文本,兼容公开版本未提供强类型事件声明的情况。 */
|
|
14
|
+
function reportError(error: unknown): void { message.value = error instanceof Error ? error.message : String(error) }
|
|
15
|
+
interface RecordRow { id: number; name: string }
|
|
16
|
+
// 最小内存适配器仅演示组件 API;每个页面独立数据,刷新会重置,生产请替换为真实业务请求。
|
|
17
|
+
let rows: RecordRow[] = [{ id: 1, name: '示例记录' }]
|
|
18
|
+
let nextId = 2
|
|
19
|
+
const tableConfig: TableConfig = {
|
|
20
|
+
rowKey: 'id', title: '示例记录', pagination: false,
|
|
21
|
+
columns: [
|
|
22
|
+
{ field: 'id', label: '编号', width: 100 },
|
|
23
|
+
{ field: 'name', label: '名称', formItem: { component: 'FInput', required: true, componentProps: { maxlength: 80 } } },
|
|
24
|
+
],
|
|
25
|
+
requestConfig: { api: async () => ({ list: rows.map(row => ({ ...row })), total: rows.length }) },
|
|
26
|
+
crudConfig: {
|
|
27
|
+
// 由 FCrudTable 统一生成新增/编辑弹框及删除确认,不另造重复表单。
|
|
28
|
+
createApi: async data => { rows.push({ id: nextId++, name: String(data.name) }) },
|
|
29
|
+
updateApi: async data => { rows = rows.map(row => row.id === data.id ? { ...row, name: String(data.name) } : row) },
|
|
30
|
+
deleteApi: async data => { rows = rows.filter(row => row.id !== data.id) },
|
|
31
|
+
onSuccess: () => { message.value = '演示内存数据已更新(刷新后重置)' },
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** 同应用详情用页面 SDK 打开宿主页签;独立模式才使用普通 router,错误留在原页面。 */
|
|
36
|
+
async function openDetail(): Promise<void> {
|
|
37
|
+
try {
|
|
38
|
+
if (sdk && bridge) await sdk.openTab({ appId: bridge.appId, tabId: `${bridge.appId}:detail:1`, title: '示例详情 1', route: '/detail?id=1' })
|
|
39
|
+
else await router.push('/detail?id=1')
|
|
40
|
+
} catch (error) { message.value = String(error) }
|
|
41
|
+
}
|
|
42
|
+
</script>
|
|
43
|
+
<template>
|
|
44
|
+
<section class="panel">
|
|
45
|
+
<h1>__PROJECT_NAME__</h1>
|
|
46
|
+
<p>以下 CRUD 为内存示例,非生产业务接口;新增、编辑和删除均使用 fin-ui 内置流程。</p>
|
|
47
|
+
<div class="actions"><el-button @click="openDetail">打开详情页</el-button></div>
|
|
48
|
+
<p v-if="message" role="status">{{ message }}</p>
|
|
49
|
+
<FCrudTable :table-config="tableConfig" @error="reportError" />
|
|
50
|
+
</section>
|
|
51
|
+
</template>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<template><section class="panel"><h2>页面不存在</h2><p>请检查宿主菜单 route 与 src/router/index.ts 的页面注册配置。</p></section></template>
|