@done-coding/admin-core 0.8.3-alpha.0 → 0.9.1-alpha.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/docs/nested-config-paradigm.md +80 -0
- package/es/bridge/config-hook.mjs +37 -0
- package/es/bridge/index.mjs +157 -62
- package/es/bridge/plugin.mjs +29 -0
- package/es/bridge/theme.mjs +65 -0
- package/es/components/app-layout/AppBody.vue.mjs +1 -1
- package/es/components/app-layout/AppBody.vue2.mjs +47 -49
- package/es/components/app-layout/AppBreadcrumb.vue.mjs +1 -1
- package/es/components/app-layout/AppBreadcrumb.vue2.mjs +35 -41
- package/es/components/app-layout/AppFooter.vue.mjs +2 -2
- package/es/components/app-layout/AppFooter.vue2.mjs +8 -8
- package/es/components/app-layout/AppHeader.vue.mjs +1 -1
- package/es/components/app-layout/AppHeader.vue2.mjs +60 -69
- package/es/components/app-layout/AppLayout.vue.mjs +2 -2
- package/es/components/app-layout/AppLayout.vue2.mjs +95 -93
- package/es/components/app-layout/AppSidebar.vue.mjs +2 -2
- package/es/components/app-layout/AppSidebar.vue2.mjs +79 -82
- package/es/components/app-layout/AppTheme.vue.mjs +7 -0
- package/es/components/app-layout/AppTheme.vue2.mjs +38 -0
- package/es/components/data-view/DataListView.vue.mjs +2 -2
- package/es/components/data-view/DataListView.vue2.mjs +36 -36
- package/es/components/display/ActionConfirm.vue2.mjs +16 -16
- package/es/components/display/HeightProvider.vue.mjs +10 -10
- package/es/components/display/TabsHeader.vue.mjs +4 -4
- package/es/components/display/TabsHeader.vue2.mjs +34 -34
- package/es/components/display/TabsMain.vue.mjs +40 -39
- package/es/components/display/TabsRefineFlow.vue.mjs +30 -28
- package/es/components/form/FormItem.vue.mjs +1 -1
- package/es/components/form/FormItem.vue2.mjs +75 -81
- package/es/components/form/FormItemNestForm.vue.mjs +7 -0
- package/es/components/form/FormItemNestForm.vue2.mjs +49 -0
- package/es/components/form/FormItemNestFormList.vue.mjs +7 -0
- package/es/components/form/FormItemNestFormList.vue2.mjs +137 -0
- package/es/components/form/FormMain.vue.mjs +5 -147
- package/es/components/form/FormMain.vue2.mjs +160 -2
- package/es/components/form/FormRadioGroup.vue.mjs +42 -49
- package/es/components/form/FormSearch.vue.mjs +2 -2
- package/es/components/form/FormSearch.vue2.mjs +122 -128
- package/es/components/form/FormSelect.vue.mjs +34 -40
- package/es/components/form/FormSubmitBtn.vue.mjs +23 -28
- package/es/components/form/FormSubmitPanel.vue.mjs +2 -2
- package/es/components/form/FormSubmitPanel.vue2.mjs +29 -28
- package/es/components/form/FormTree.vue.mjs +16 -21
- package/es/components/form/FormVerifyCode.vue.mjs +37 -43
- package/es/components/form/FormVerifyImage.vue.mjs +2 -2
- package/es/components/form/FormVerifyImage.vue2.mjs +36 -41
- package/es/components/form/nest-form-item-list.mjs +71 -0
- package/es/components/form/nest-form-item.mjs +42 -0
- package/es/components/form/nest-registry.mjs +7 -0
- package/es/components/form/use-nest-form-list.mjs +22 -0
- package/es/components/form/use-nest-form.mjs +34 -0
- package/es/components/form/use-nest-layout-scale.mjs +14 -0
- package/es/components/form/utils.mjs +77 -61
- package/es/components/list-page/ListPage.vue.mjs +2 -2
- package/es/components/list-page/ListPage.vue2.mjs +134 -139
- package/es/components/menu/MenuItemSub.vue.mjs +41 -48
- package/es/components/menu/MenuTree.vue.mjs +58 -65
- package/es/components/misc/AutoRefresh.vue.mjs +2 -2
- package/es/components/misc/AutoRefresh.vue2.mjs +44 -51
- package/es/components/misc/AutoRefreshGroup.vue.mjs +2 -2
- package/es/components/misc/AutoRefreshGroup.vue2.mjs +37 -43
- package/es/components/modal/ConfirmModal.vue.mjs +3 -4
- package/es/components/modal/ConfirmModal.vue2.mjs +83 -111
- package/es/components/modal/DetailModal.vue.mjs +38 -41
- package/es/components/panel/PanelEditSwitch.vue.mjs +1 -1
- package/es/components/panel/PanelEditSwitch.vue2.mjs +50 -55
- package/es/components/panel/PanelItemNestForm.vue.mjs +7 -0
- package/es/components/panel/PanelItemNestForm.vue2.mjs +69 -0
- package/es/components/panel/PanelItemNestPanel.vue.mjs +34 -0
- package/es/components/panel/PanelItemNestPanel.vue2.mjs +4 -0
- package/es/components/panel/PanelMain.vue.mjs +1 -1
- package/es/components/panel/PanelMain.vue2.mjs +72 -72
- package/es/components/panel/nest-panel-form.mjs +53 -0
- package/es/components/panel/nest-panel-item.mjs +25 -0
- package/es/components/table/TableMain.vue.mjs +2 -2
- package/es/components/table/TableMain.vue2.mjs +221 -229
- package/es/components/table/TableToolbar.vue.mjs +2 -2
- package/es/components/table/TableToolbar.vue2.mjs +115 -126
- package/es/hooks/use-admin-theme-apply.mjs +84 -0
- package/es/hooks/use-admin-viewport-apply.mjs +27 -0
- package/es/index.mjs +190 -153
- package/es/inject/key.mjs +15 -6
- package/es/store/app.mjs +75 -84
- package/es/style.css +1 -1
- package/es/utils/theme-scale.mjs +37 -0
- package/package.json +2 -4
- package/types/bridge/config-hook.d.ts +91 -0
- package/types/bridge/index.d.ts +108 -8
- package/types/bridge/plugin.d.ts +39 -0
- package/types/bridge/theme.d.ts +85 -0
- package/types/components/app-layout/AppTheme.vue.d.ts +2 -0
- package/types/components/app-layout/types.d.ts +1 -1
- package/types/components/form/FormItem.vue.d.ts +12 -12
- package/types/components/form/FormItemNestForm.vue.d.ts +36 -0
- package/types/components/form/FormItemNestFormList.vue.d.ts +63 -0
- package/types/components/form/FormMain.vue.d.ts +2 -2
- package/types/components/form/FormSearch.vue.d.ts +2 -2
- package/types/components/form/FormTree.vue.d.ts +50 -50
- package/types/components/form/index.d.ts +9 -1
- package/types/components/form/nest-form-item-list.d.ts +63 -0
- package/types/components/form/nest-form-item.d.ts +36 -0
- package/types/components/form/nest-registry.d.ts +22 -0
- package/types/components/form/types.d.ts +2 -0
- package/types/components/form/use-nest-form-list.d.ts +20 -0
- package/types/components/form/use-nest-form.d.ts +26 -0
- package/types/components/form/use-nest-layout-scale.d.ts +17 -0
- package/types/components/form/utils.d.ts +26 -1
- package/types/components/menu/MenuTree.vue.d.ts +10 -10
- package/types/components/modal/ModalShelf.vue.d.ts +1 -1
- package/types/components/panel/PanelItemNestForm.vue.d.ts +35 -0
- package/types/components/panel/PanelItemNestPanel.vue.d.ts +22 -0
- package/types/components/panel/index.d.ts +5 -1
- package/types/components/panel/nest-panel-form.d.ts +38 -0
- package/types/components/panel/nest-panel-item.d.ts +28 -0
- package/types/components/panel/types.d.ts +2 -0
- package/types/components/table/TableMain.vue.d.ts +3 -3
- package/types/hooks/activated.d.ts +2 -2
- package/types/hooks/feel-size.d.ts +1 -1
- package/types/hooks/index.d.ts +2 -0
- package/types/hooks/menus-dispatch.d.ts +5 -5
- package/types/hooks/use-admin-theme-apply.d.ts +17 -0
- package/types/hooks/use-admin-viewport-apply.d.ts +15 -0
- package/types/hooks/use-breakpoint.d.ts +1 -1
- package/types/inject/key.d.ts +46 -1
- package/types/store/app.d.ts +138 -59
- package/types/utils/index.d.ts +1 -0
- package/types/utils/theme-scale.d.ts +35 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const l = (s) => {
|
|
2
|
+
const t = s.trim().replace(/^#/, "");
|
|
3
|
+
if (t.length === 3) {
|
|
4
|
+
const n = parseInt(t[0] + t[0], 16), r = parseInt(t[1] + t[1], 16), e = parseInt(t[2] + t[2], 16);
|
|
5
|
+
return [n, r, e].some(Number.isNaN) ? null : [n, r, e];
|
|
6
|
+
}
|
|
7
|
+
if (t.length === 6) {
|
|
8
|
+
const n = parseInt(t.slice(0, 2), 16), r = parseInt(t.slice(2, 4), 16), e = parseInt(t.slice(4, 6), 16);
|
|
9
|
+
return [n, r, e].some(Number.isNaN) ? null : [n, r, e];
|
|
10
|
+
}
|
|
11
|
+
return null;
|
|
12
|
+
}, o = (s, t, n) => {
|
|
13
|
+
const r = (e) => Math.min(255, Math.max(0, Math.round(e))).toString(16).padStart(2, "0");
|
|
14
|
+
return `#${r(s)}${r(t)}${r(n)}`;
|
|
15
|
+
}, i = (s, t, n) => {
|
|
16
|
+
const r = l(s), e = l(t);
|
|
17
|
+
return !r || !e ? t : o(
|
|
18
|
+
r[0] * n + e[0] * (1 - n),
|
|
19
|
+
r[1] * n + e[1] * (1 - n),
|
|
20
|
+
r[2] * n + e[2] * (1 - n)
|
|
21
|
+
);
|
|
22
|
+
}, a = (s, t) => {
|
|
23
|
+
const n = t === "light" ? "#ffffff" : "#141414", r = t === "light" ? "#000000" : "#ffffff", e = (c) => i(n, s, c / 10);
|
|
24
|
+
return {
|
|
25
|
+
base: s,
|
|
26
|
+
"light-3": e(3),
|
|
27
|
+
"light-5": e(5),
|
|
28
|
+
"light-7": e(7),
|
|
29
|
+
"light-8": e(8),
|
|
30
|
+
"light-9": e(9),
|
|
31
|
+
"dark-2": i(r, s, 0.2)
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export {
|
|
35
|
+
a as themeScaleDerive,
|
|
36
|
+
i as themeScaleMix
|
|
37
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@done-coding/admin-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1-alpha.0",
|
|
4
4
|
"description": "后台管理核心",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "lib/index.cjs",
|
|
@@ -60,8 +60,6 @@
|
|
|
60
60
|
"jsdom": "^29.1.0",
|
|
61
61
|
"less": "^4.2.0",
|
|
62
62
|
"typescript": "^5.2.2",
|
|
63
|
-
"unplugin-auto-import": "^0.17.8",
|
|
64
|
-
"unplugin-vue-components": "^0.26.0",
|
|
65
63
|
"vite": "^5.2.0",
|
|
66
64
|
"vite-plugin-dts": "^4.5.4",
|
|
67
65
|
"vitest": "^1.6.1",
|
|
@@ -81,5 +79,5 @@
|
|
|
81
79
|
"node": ">=18.0.0",
|
|
82
80
|
"pnpm": ">=9.0.0"
|
|
83
81
|
},
|
|
84
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "6924deab3afbbc45ec75501f9a888ae0eb3d0648"
|
|
85
83
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { DeepReadonly } from 'vue';
|
|
2
|
+
import { AppBaseInfo, AppLayoutHeaderConfig, AppLayoutFooterConfig, AppLayoutSidebarConfig, AppLayoutBreadcrumbConfig, AppLayoutBodyConfig, AppLayoutViewportConfig, AppThemeConfig, AppLayoutConfig } from './index';
|
|
3
|
+
/**
|
|
4
|
+
* 可 update 的响应式配置字段 key 联合(插件系统一期 7 个 + viewport 边框期补 1 = 8 个)。
|
|
5
|
+
*
|
|
6
|
+
* #插件系统一期:bridge 的布局/主题/基础信息字段下沉为 reactive 响应式,
|
|
7
|
+
* 经 `update(key, partial)` 单字段一级浅合并触发。viewport 边框期新增
|
|
8
|
+
* `APP_LAYOUT_VIEWPORT_CONFIG`(同属布局子,纳入本联合 + layoutAggregate)。
|
|
9
|
+
* 其余 init 字段(env / cache / router 族 / userInfoAccess)非响应式范围,[MUST NOT] 纳入本联合。
|
|
10
|
+
*/
|
|
11
|
+
export type UpdatableConfigKey = "APP_BASE_INFO" | "APP_LAYOUT_HEADER_CONFIG" | "APP_LAYOUT_FOOTER_CONFIG" | "APP_LAYOUT_SIDEBAR_CONFIG" | "APP_LAYOUT_BREADCRUMB_CONFIG" | "APP_LAYOUT_BODY_CONFIG" | "APP_LAYOUT_VIEWPORT_CONFIG" | "APP_THEME_CONFIG";
|
|
12
|
+
/**
|
|
13
|
+
* 7 个可 update 字段 key → 值类型映射。
|
|
14
|
+
*
|
|
15
|
+
* `update<K>(key, partial)` 的 `partial` 类型经 `Partial<UpdatableConfigMap[K]>`
|
|
16
|
+
* 推导;`createBridgeConfigHook` 的 init 入参亦以本映射约束(见 `BridgeConfigInit`)。
|
|
17
|
+
*/
|
|
18
|
+
export interface UpdatableConfigMap {
|
|
19
|
+
/** 应用基础信息 */
|
|
20
|
+
APP_BASE_INFO: AppBaseInfo;
|
|
21
|
+
/** 应用布局-header 配置 */
|
|
22
|
+
APP_LAYOUT_HEADER_CONFIG: AppLayoutHeaderConfig;
|
|
23
|
+
/** 应用布局-footer 配置 */
|
|
24
|
+
APP_LAYOUT_FOOTER_CONFIG: AppLayoutFooterConfig;
|
|
25
|
+
/** 应用布局-sidebar 配置 */
|
|
26
|
+
APP_LAYOUT_SIDEBAR_CONFIG: AppLayoutSidebarConfig;
|
|
27
|
+
/** 应用布局-面包屑配置 */
|
|
28
|
+
APP_LAYOUT_BREADCRUMB_CONFIG: AppLayoutBreadcrumbConfig;
|
|
29
|
+
/** 应用布局-页面主体配置 */
|
|
30
|
+
APP_LAYOUT_BODY_CONFIG: AppLayoutBodyConfig;
|
|
31
|
+
/** 应用布局-视口边框配置 */
|
|
32
|
+
APP_LAYOUT_VIEWPORT_CONFIG: AppLayoutViewportConfig;
|
|
33
|
+
/** 应用主题配置 */
|
|
34
|
+
APP_THEME_CONFIG: AppThemeConfig;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* `createBridgeConfigHook` 入参类型——7 个本期响应式字段的初值(= `UpdatableConfigMap`)。
|
|
38
|
+
*
|
|
39
|
+
* 由 `createAdminBridge` 闭包内从 `options` 的对应 7 字段直传;入参字段对象将被
|
|
40
|
+
* 直接 `reactive()` 化(方案 A,[MUST NOT] 浅拷贝),故 [MUST] 为去 freeze 后的非
|
|
41
|
+
* frozen 裸对象(app 端去字段级 freeze 保证)。
|
|
42
|
+
*/
|
|
43
|
+
export type BridgeConfigInit = UpdatableConfigMap;
|
|
44
|
+
/**
|
|
45
|
+
* configHook 内部返回契约——`update` 方法 + 8 个对外 readonly 视图。
|
|
46
|
+
*
|
|
47
|
+
* **不对外 export**:`createBridgeConfigHook` / 本 interface / 上述类型符号 [MUST NOT]
|
|
48
|
+
* 在 `bridge/index.ts` re-export(守封装边界)。`bridge/index.ts` 仅内部 import 工厂,
|
|
49
|
+
* 把 `update` 与各 `roXxx` 视图组装进 `AdminBridge` 公开面。
|
|
50
|
+
*
|
|
51
|
+
* 7 个 readonly 视图各为对应 reactive 子配置的 `readonly()` 深只读包装;`roLayout`
|
|
52
|
+
* 为 5 布局子的 `reactive({...})` 聚合的 readonly 包装——5 字段指向各 reactive 子配置,
|
|
53
|
+
* 任一布局子 `update` 原地改经叶子代理同步跟随(Vue reactive 深度转换保留嵌套响应式),零拷贝。
|
|
54
|
+
*/
|
|
55
|
+
export interface BridgeConfigHook {
|
|
56
|
+
/** 单字段一级浅合并 update(`Object.assign` 派发到对应 reactive 子配置) */
|
|
57
|
+
update: <K extends UpdatableConfigKey>(key: K, partial: Partial<UpdatableConfigMap[K]>) => void;
|
|
58
|
+
/** 应用基础信息对外只读视图 */
|
|
59
|
+
roBaseInfo: DeepReadonly<AppBaseInfo>;
|
|
60
|
+
/** 应用布局-header 配置对外只读视图 */
|
|
61
|
+
roHeader: DeepReadonly<AppLayoutHeaderConfig>;
|
|
62
|
+
/** 应用布局-footer 配置对外只读视图 */
|
|
63
|
+
roFooter: DeepReadonly<AppLayoutFooterConfig>;
|
|
64
|
+
/** 应用布局-sidebar 配置对外只读视图 */
|
|
65
|
+
roSidebar: DeepReadonly<AppLayoutSidebarConfig>;
|
|
66
|
+
/** 应用布局-面包屑配置对外只读视图 */
|
|
67
|
+
roBreadcrumb: DeepReadonly<AppLayoutBreadcrumbConfig>;
|
|
68
|
+
/** 应用布局-页面主体配置对外只读视图 */
|
|
69
|
+
roBody: DeepReadonly<AppLayoutBodyConfig>;
|
|
70
|
+
/** 应用布局-视口边框配置对外只读视图 */
|
|
71
|
+
roViewport: DeepReadonly<AppLayoutViewportConfig>;
|
|
72
|
+
/** 应用主题配置对外只读视图 */
|
|
73
|
+
roTheme: DeepReadonly<AppThemeConfig>;
|
|
74
|
+
/**
|
|
75
|
+
* 应用布局聚合配置只读视图(5 布局子 reactive 聚合的 readonly 包装)。
|
|
76
|
+
*
|
|
77
|
+
* `reactive({header: reactiveHeader, ...})` 5 字段指向各 reactive 子配置,任一布局子
|
|
78
|
+
* update 原地改经叶子代理同步跟随(Vue reactive 深度转换保留嵌套响应式),零拷贝。
|
|
79
|
+
*/
|
|
80
|
+
roLayout: DeepReadonly<AppLayoutConfig>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* bridge 响应式配置 hook 工厂。
|
|
84
|
+
*
|
|
85
|
+
* 接收 7 个本期字段初值,逐字段 `reactive()` 化(方案 A:直接 reactive 入参对象,
|
|
86
|
+
* [MUST NOT] 浅拷贝),内部把 5 布局子聚合为 `layoutAggregate = reactive({...})`,
|
|
87
|
+
* 对外返回 `update`(单字段一级浅合并 `Object.assign`,[MUST NOT] 深合并 / merge / clone)+
|
|
88
|
+
* 7 个 `readonly()` 视图 + 1 个 `roLayout`(readonly 聚合视图)。每次 `createAdminBridge`
|
|
89
|
+
* 调用各自闭包内构造一份,零模块级单例(守实例隔离)。
|
|
90
|
+
*/
|
|
91
|
+
export declare function createBridgeConfigHook(init: BridgeConfigInit): BridgeConfigHook;
|
package/types/bridge/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { App, DeepReadonly, Ref } from 'vue';
|
|
1
2
|
import { RouteRecordRaw } from 'vue-router';
|
|
2
3
|
import { createUseState } from './state';
|
|
3
4
|
import { createGenerateRouteMetaRawTree } from './route';
|
|
5
|
+
import { UpdatableConfigKey, UpdatableConfigMap } from './config-hook';
|
|
6
|
+
import { AdminBridgePluginLike } from './plugin';
|
|
7
|
+
import { AdminThemeModule } from './theme';
|
|
4
8
|
export { createUseState, type UseStateOptions } from './state';
|
|
5
9
|
export { createGenerateRouteMetaRawTree, type RouteMetaDefaultConfig, } from './route';
|
|
6
10
|
export { createStorageWithNamespace } from './storage';
|
|
@@ -37,6 +41,7 @@ export interface AdminBridgeRegisterOptions<UserInfo = unknown, LoginParams = un
|
|
|
37
41
|
/** 刷新 token api(#C 期签名最简化:core 不感知业务 shape,直传 refreshToken string;业务方 wrap 内自打包业务约定的入参 shape,如 `{Authorization: rt}`),增量可选 */
|
|
38
42
|
refreshTokenApi?: (refreshToken: string) => Promise<string>;
|
|
39
43
|
}
|
|
44
|
+
export type { AdminBridgePlugin, AdminBridgePluginBridgeSlice, AdminBridgePluginContext, AdminBridgePluginInstall, AdminBridgePluginLike, } from './plugin';
|
|
40
45
|
/**
|
|
41
46
|
* pinia persist storage 适配器最小接口。
|
|
42
47
|
*
|
|
@@ -75,6 +80,24 @@ export interface AppThemeColor {
|
|
|
75
80
|
errorColor: string;
|
|
76
81
|
/** 信息色 */
|
|
77
82
|
infoColor: string;
|
|
83
|
+
/** 圆角(风格可选;core 挂 --admin-core-radius + --el-border-radius-base) */
|
|
84
|
+
radius?: string;
|
|
85
|
+
/** 边框色(风格可选;core 挂 --admin-core-border-color + --el-border-color) */
|
|
86
|
+
borderColor?: string;
|
|
87
|
+
/** 阴影(风格可选;core 挂 --admin-core-shadow + --el-box-shadow) */
|
|
88
|
+
shadow?: string;
|
|
89
|
+
/** 边框宽(风格可选;core 挂 --admin-core-border-width + --el-border-width) */
|
|
90
|
+
borderWidth?: string;
|
|
91
|
+
/** 强调色(风格可选;core 仅挂 --admin-core-accent,EP 无对应) */
|
|
92
|
+
accent?: string;
|
|
93
|
+
/** 辉光(风格可选;core 仅挂 --admin-core-glow,EP 无对应) */
|
|
94
|
+
glow?: string;
|
|
95
|
+
/** 模糊(风格可选;core 仅挂 --admin-core-blur,EP 无对应) */
|
|
96
|
+
blur?: string;
|
|
97
|
+
/** 聚焦环(风格可选;core 仅挂 --admin-core-focus-ring,EP 无对应) */
|
|
98
|
+
focusRing?: string;
|
|
99
|
+
/** 表面色(风格可选;core 仅挂 --admin-core-surface,EP 无对应) */
|
|
100
|
+
surface?: string;
|
|
78
101
|
}
|
|
79
102
|
/**
|
|
80
103
|
* `store/app.ts` 实际消费的 app config 子集结构。
|
|
@@ -111,6 +134,23 @@ export interface AppConfig {
|
|
|
111
134
|
/** 页面主体 padding - 默认值(px) */
|
|
112
135
|
shimPadding: number;
|
|
113
136
|
};
|
|
137
|
+
/**
|
|
138
|
+
* 应用布局-视口边框配置(整个 app-shell 相对浏览器视口四边内缩,套"边框"留白观感)。
|
|
139
|
+
*
|
|
140
|
+
* Header/Sidebar 的 fixed 锚点由 `0` 改贴四边 padding 值;AppBody 在原扣 header 高 /
|
|
141
|
+
* sidebar 宽基础上经 calc 再叠加对应 viewport 边距。app 端可整体不传(核内默认四边 0
|
|
142
|
+
* = 不套框,现状不变);布局插件经 `bridge.update("APP_LAYOUT_VIEWPORT_CONFIG", ...)` 设值。
|
|
143
|
+
*/
|
|
144
|
+
APP_LAYOUT_VIEWPORT_CONFIG: {
|
|
145
|
+
/** 视口上内边距(px) */
|
|
146
|
+
paddingTop: number;
|
|
147
|
+
/** 视口右内边距(px) */
|
|
148
|
+
paddingRight: number;
|
|
149
|
+
/** 视口下内边距(px) */
|
|
150
|
+
paddingBottom: number;
|
|
151
|
+
/** 视口左内边距(px) */
|
|
152
|
+
paddingLeft: number;
|
|
153
|
+
};
|
|
114
154
|
/** 应用主题配置(store/app 取 dark / light,各为完整 AppThemeColor) */
|
|
115
155
|
APP_THEME_CONFIG: {
|
|
116
156
|
/** 亮色主题 */
|
|
@@ -178,6 +218,8 @@ export interface AppLayoutConfig {
|
|
|
178
218
|
breadcrumb: AppLayoutBreadcrumbConfig;
|
|
179
219
|
/** 页面主体配置 */
|
|
180
220
|
body: AppConfig["APP_LAYOUT_BODY_CONFIG"];
|
|
221
|
+
/** 视口边框配置 */
|
|
222
|
+
viewport: AppConfig["APP_LAYOUT_VIEWPORT_CONFIG"];
|
|
181
223
|
}
|
|
182
224
|
/**
|
|
183
225
|
* 应用路由配置(#2.5 期新增,per ADR-6)。
|
|
@@ -232,6 +274,8 @@ export type AppLayoutFooterConfig = AppConfig["APP_LAYOUT_FOOTER_CONFIG"];
|
|
|
232
274
|
export type AppLayoutSidebarConfig = AppConfig["APP_LAYOUT_SIDEBAR_CONFIG"];
|
|
233
275
|
/** 应用布局-页面主体配置 type 别名 */
|
|
234
276
|
export type AppLayoutBodyConfig = AppConfig["APP_LAYOUT_BODY_CONFIG"];
|
|
277
|
+
/** 应用布局-视口边框配置 type 别名 */
|
|
278
|
+
export type AppLayoutViewportConfig = AppConfig["APP_LAYOUT_VIEWPORT_CONFIG"];
|
|
235
279
|
/** 应用主题配置 type 别名 */
|
|
236
280
|
export type AppThemeConfig = AppConfig["APP_THEME_CONFIG"];
|
|
237
281
|
/** 应用路由元信息默认配置 type 别名 */
|
|
@@ -311,6 +355,11 @@ export interface AdminBridgeInitOptions<UserInfo = unknown> {
|
|
|
311
355
|
APP_LAYOUT_BREADCRUMB_CONFIG: AppLayoutBreadcrumbConfig;
|
|
312
356
|
/** 应用布局-页面主体配置 */
|
|
313
357
|
APP_LAYOUT_BODY_CONFIG: AppLayoutBodyConfig;
|
|
358
|
+
/**
|
|
359
|
+
* 应用布局-视口边框配置(可选;app 整体不传时核内默认四边 0 = 不套框,现状不变)。
|
|
360
|
+
* 传部分字段时与默认四边 0 浅合并(见 createAdminBridge 内 DEFAULT 合并)。
|
|
361
|
+
*/
|
|
362
|
+
APP_LAYOUT_VIEWPORT_CONFIG?: Partial<AppLayoutViewportConfig>;
|
|
314
363
|
/** 应用路由元信息默认配置(bridge 内部 generateRouteMetaRawTree 派生) */
|
|
315
364
|
APP_ROUTER_META_DEFAULT_CONFIG: AppRouterMetaDefaultConfig;
|
|
316
365
|
/** 应用路由配置(#2.5 期新增字段) */
|
|
@@ -363,23 +412,25 @@ export interface AdminBridge<UserInfo = unknown, LoginParams = unknown> {
|
|
|
363
412
|
/** 刷新 token api(createUserStore refreshTokenFn 内调;#C 期签名最简化:core 直传 refreshToken string,业务 wrap 内自打包业务 shape;未注册被调 reject 原生 Error) */
|
|
364
413
|
refreshTokenApi: (refreshToken: string) => Promise<string>;
|
|
365
414
|
/** 应用基础信息(per #2.5 期 REQ-1 直接挂载形态) */
|
|
366
|
-
readonly APP_BASE_INFO: AppBaseInfo
|
|
415
|
+
readonly APP_BASE_INFO: DeepReadonly<AppBaseInfo>;
|
|
367
416
|
/** 应用环境信息(per #2.5 期 REQ-1) */
|
|
368
417
|
readonly APP_ENV_INFO: AppEnvInfo;
|
|
369
418
|
/** 应用缓存配置(per #2.5 期 REQ-1) */
|
|
370
419
|
readonly APP_CACHE_CONFIG: AppCacheConfig;
|
|
371
420
|
/** 应用布局-header 配置(per #2.5 期 REQ-1) */
|
|
372
|
-
readonly APP_LAYOUT_HEADER_CONFIG: AppLayoutHeaderConfig
|
|
421
|
+
readonly APP_LAYOUT_HEADER_CONFIG: DeepReadonly<AppLayoutHeaderConfig>;
|
|
373
422
|
/** 应用布局-footer 配置(per #2.5 期 REQ-1) */
|
|
374
|
-
readonly APP_LAYOUT_FOOTER_CONFIG: AppLayoutFooterConfig
|
|
423
|
+
readonly APP_LAYOUT_FOOTER_CONFIG: DeepReadonly<AppLayoutFooterConfig>;
|
|
375
424
|
/** 应用布局-sidebar 配置(per #2.5 期 REQ-1) */
|
|
376
|
-
readonly APP_LAYOUT_SIDEBAR_CONFIG: AppLayoutSidebarConfig
|
|
425
|
+
readonly APP_LAYOUT_SIDEBAR_CONFIG: DeepReadonly<AppLayoutSidebarConfig>;
|
|
377
426
|
/** 应用布局-面包屑配置(per #2.5 期 REQ-1) */
|
|
378
|
-
readonly APP_LAYOUT_BREADCRUMB_CONFIG: AppLayoutBreadcrumbConfig
|
|
427
|
+
readonly APP_LAYOUT_BREADCRUMB_CONFIG: DeepReadonly<AppLayoutBreadcrumbConfig>;
|
|
379
428
|
/** 应用布局-页面主体配置(per #2.5 期 REQ-1) */
|
|
380
|
-
readonly APP_LAYOUT_BODY_CONFIG: AppLayoutBodyConfig
|
|
429
|
+
readonly APP_LAYOUT_BODY_CONFIG: DeepReadonly<AppLayoutBodyConfig>;
|
|
430
|
+
/** 应用布局-视口边框配置(响应式只读视图,经 bridge.update 跟随) */
|
|
431
|
+
readonly APP_LAYOUT_VIEWPORT_CONFIG: DeepReadonly<AppLayoutViewportConfig>;
|
|
381
432
|
/** 应用布局聚合配置(per #2.5 期 ADR-3 bridge 内部聚合派生) */
|
|
382
|
-
readonly APP_LAYOUT_CONFIG: AppLayoutConfig
|
|
433
|
+
readonly APP_LAYOUT_CONFIG: DeepReadonly<AppLayoutConfig>;
|
|
383
434
|
/** 应用路由元信息默认配置(per #2.5 期 REQ-1) */
|
|
384
435
|
readonly APP_ROUTER_META_DEFAULT_CONFIG: AppRouterMetaDefaultConfig;
|
|
385
436
|
/** 应用路由配置(per #2.5 期 REQ-1) */
|
|
@@ -387,9 +438,58 @@ export interface AdminBridge<UserInfo = unknown, LoginParams = unknown> {
|
|
|
387
438
|
/** 应用路由路径配置(per #7.3 期;8 path 聚合 readonly 挂载) */
|
|
388
439
|
readonly APP_ROUTER_PATHS_CONFIG: AppRouterPathsConfig;
|
|
389
440
|
/** 应用主题配置(per #2.5 期 REQ-1) */
|
|
390
|
-
readonly APP_THEME_CONFIG: AppThemeConfig
|
|
441
|
+
readonly APP_THEME_CONFIG: DeepReadonly<AppThemeConfig>;
|
|
442
|
+
/**
|
|
443
|
+
* 主题模块(架构反转:core/bridge 主导主题切换)。
|
|
444
|
+
*
|
|
445
|
+
* `theme.{add,remove,setStyle,setDark,list,labelOf}`——风格 map 注册/注销 + 切换 + 展示名。
|
|
446
|
+
* 插件 install 经 `bridge.theme.add(name, preset)` 注册风格(preset = {config,label?});切换真相在
|
|
447
|
+
* bridge,appStore / AppTheme.vue 转发 `setStyle` / `setDark`([MUST NOT] bridge 反向监测 store)。
|
|
448
|
+
*/
|
|
449
|
+
readonly theme: AdminThemeModule;
|
|
450
|
+
/** 当前风格名(响应式只读真相源;[MUST NOT] 解构/快照取值,⚠️ 切换后定格) */
|
|
451
|
+
readonly themeStyle: DeepReadonly<Ref<string>>;
|
|
452
|
+
/** 是否暗色(响应式只读真相源;appStore.isDarkTheme 读此、挂值 composable toggle .dark 读此) */
|
|
453
|
+
readonly themeIsDark: DeepReadonly<Ref<boolean>>;
|
|
454
|
+
/**
|
|
455
|
+
* 当前生效的 JS 主题色(输出 B:JS 色值直给,与挂值 composable 的 cssvar 输出 A 对称)。
|
|
456
|
+
*
|
|
457
|
+
* = `themeIsDark ? APP_THEME_CONFIG.dark : APP_THEME_CONFIG.light`——明暗 + 风格的
|
|
458
|
+
* 选择逻辑落在 bridge 这个真相源(store **不再自选**,仅 `appStore.theme` 转发本字段)。
|
|
459
|
+
* 给「需对颜色做运算、吃不了 CSS var」的消费方直读真实色值
|
|
460
|
+
* (MenuTree → ElMenu hover 派生 TinyColor parse / 任意 JS 内联样式)。
|
|
461
|
+
* 纯 CSS 消费方走挂值 composable 写的 `--admin-core-*` cascade(输出 A)。
|
|
462
|
+
* [MUST NOT] 解构/快照(⚠️ 切换风格/明暗后定格)。
|
|
463
|
+
*/
|
|
464
|
+
readonly themeColors: DeepReadonly<Ref<AppThemeColor>>;
|
|
391
465
|
/** 用户信息字段访问器集(业务注入;createUserStore 经 bridge.userInfoAccess.<字段>.get/set 读写,第一宪法 core 零字段耦合) */
|
|
392
466
|
readonly userInfoAccess: UserInfoAccess<UserInfo>;
|
|
467
|
+
/**
|
|
468
|
+
* 更新本期 7 个响应式配置字段(插件系统一期,REQ-1)。
|
|
469
|
+
*
|
|
470
|
+
* 两参单字段 + **一级浅合并**(`Object.assign` 把 partial 第一层属性覆盖到对应
|
|
471
|
+
* reactive 子配置,未传字段保留)。`theme` 的 `light`/`dark` 作为第一层属性整体
|
|
472
|
+
* 替换(`update("APP_THEME_CONFIG", {light: newLight})` 整体替换 `light`、保留
|
|
473
|
+
* `dark`)。[MUST NOT] 期望深合并——非 lodash merge / structuredClone 语义。
|
|
474
|
+
* update 后对应 `bridge.APP_XXX` readonly 视图自动跟随。
|
|
475
|
+
*/
|
|
476
|
+
update: <K extends UpdatableConfigKey>(key: K, partial: Partial<UpdatableConfigMap[K]>) => void;
|
|
477
|
+
/**
|
|
478
|
+
* 安装 admin bridge 插件。
|
|
479
|
+
*
|
|
480
|
+
* 插件状态按 bridge 实例隔离;同一插件引用或同名插件重复安装时会跳过。
|
|
481
|
+
* `app.use(bridge)` 只负责 Vue provide,完整插件扩展走本方法。
|
|
482
|
+
*/
|
|
483
|
+
use: <Options = unknown>(plugin: AdminBridgePluginLike<UserInfo, LoginParams, Options>, options?: Options) => AdminBridge<UserInfo, LoginParams>;
|
|
484
|
+
/**
|
|
485
|
+
* Vue 插件 install(插件系统一期,REQ-9)。
|
|
486
|
+
*
|
|
487
|
+
* `app.use(bridge)` 经 `app.provide(ADMIN_BRIDGE_KEY, bridge)` 全局注入整个 bridge
|
|
488
|
+
* 实例;业务子组件 `inject(ADMIN_BRIDGE_KEY)` 拿到整 bridge → 读只读响应式配置 +
|
|
489
|
+
* 调 `bridge.update`。**opt-in**:不 `app.use(bridge)` 则 inject 返回 undefined。
|
|
490
|
+
* 区别于组件级 `APP_LAYOUT_BRIDGE_KEY`(layout 域窄切片)——本通道是 app 级全局整实例。
|
|
491
|
+
*/
|
|
492
|
+
install: (app: App) => App;
|
|
393
493
|
}
|
|
394
494
|
/**
|
|
395
495
|
* 认证桥接无状态纯工厂:接收 init 参数,内部立即初始化,返回可直接使用的
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { AdminBridge } from './index';
|
|
2
|
+
import { UpdatableConfigKey, UpdatableConfigMap } from './config-hook';
|
|
3
|
+
/**
|
|
4
|
+
* 插件可访问的 bridge 视图。
|
|
5
|
+
*
|
|
6
|
+
* 屏蔽运行时编排入口、auth facade 与业务 API;需要业务动作时由插件 options 承接。
|
|
7
|
+
*/
|
|
8
|
+
export type AdminBridgePluginBridgeSlice<UserInfo = unknown, LoginParams = unknown> = Omit<AdminBridge<UserInfo, LoginParams>, "init" | "register" | "getToken" | "goToLogin" | "refreshToken" | "refreshAuth" | "loginApi" | "logoutApi" | "getUserInfoApi" | "refreshTokenApi" | "use" | "install">;
|
|
9
|
+
/**
|
|
10
|
+
* admin bridge 插件安装上下文。
|
|
11
|
+
*
|
|
12
|
+
* 插件只通过公开 bridge 实例与受控 action 工作,不访问 bridge 内部闭包状态。
|
|
13
|
+
*/
|
|
14
|
+
export interface AdminBridgePluginContext<UserInfo = unknown, LoginParams = unknown> {
|
|
15
|
+
/** 当前安装插件的 bridge 可用能力 */
|
|
16
|
+
bridge: AdminBridgePluginBridgeSlice<UserInfo, LoginParams>;
|
|
17
|
+
/** 配置更新 action 的便捷引用 */
|
|
18
|
+
update: <K extends UpdatableConfigKey>(key: K, partial: Partial<UpdatableConfigMap[K]>) => void;
|
|
19
|
+
}
|
|
20
|
+
/** admin bridge 插件安装函数。 */
|
|
21
|
+
export type AdminBridgePluginInstall<UserInfo = unknown, LoginParams = unknown, Options = unknown> = (ctx: AdminBridgePluginContext<UserInfo, LoginParams>, options?: Options) => void;
|
|
22
|
+
/** admin bridge 对象插件。 */
|
|
23
|
+
export interface AdminBridgePlugin<UserInfo = unknown, LoginParams = unknown, Options = unknown> {
|
|
24
|
+
/** 插件名;存在时用于跨对象实例的幂等安装 */
|
|
25
|
+
name?: string;
|
|
26
|
+
/** 插件安装函数 */
|
|
27
|
+
install: AdminBridgePluginInstall<UserInfo, LoginParams, Options>;
|
|
28
|
+
}
|
|
29
|
+
/** admin bridge 支持函数插件与对象插件两种形态。 */
|
|
30
|
+
export type AdminBridgePluginLike<UserInfo = unknown, LoginParams = unknown, Options = unknown> = AdminBridgePlugin<UserInfo, LoginParams, Options> | AdminBridgePluginInstall<UserInfo, LoginParams, Options>;
|
|
31
|
+
/** 创建单个 bridge 实例专属的插件安装宿主。 */
|
|
32
|
+
export declare function createBridgePluginHost<UserInfo = unknown, LoginParams = unknown>(): {
|
|
33
|
+
use: <Options = unknown>(payload: {
|
|
34
|
+
bridge: AdminBridge<UserInfo, LoginParams>;
|
|
35
|
+
update: AdminBridgePluginContext<UserInfo, LoginParams>["update"];
|
|
36
|
+
plugin: AdminBridgePluginLike<UserInfo, LoginParams, Options>;
|
|
37
|
+
options?: Options;
|
|
38
|
+
}) => AdminBridge<UserInfo, LoginParams>;
|
|
39
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { DeepReadonly, Ref } from 'vue';
|
|
2
|
+
import { AppThemeConfig, StorageLike } from './index';
|
|
3
|
+
/**
|
|
4
|
+
* 风格切换真相源在 bridge——core 之于主题 = core 之于 userInfo:core 是
|
|
5
|
+
* 「无知容器 + 切换能力暴露者」,不持有 dark 真相、不关心主题内容,谁实现谁注册
|
|
6
|
+
* (core 默认一对 / 插件扩展 core 均不关心)。
|
|
7
|
+
*
|
|
8
|
+
* 本模块从 `bridge/index.ts` 按耦合度拆出(core CLAUDE.md 规则:bridge 可独立能力
|
|
9
|
+
* [MUST NOT] 都耦合进 index.ts)。维护风格 map(name → 快照 config)+ 顶层响应式
|
|
10
|
+
* `themeStyle` / `themeIsDark`,对外 `theme.{add,remove,setStyle,setDark,list}`。
|
|
11
|
+
* setStyle 复用注入的 `update("APP_THEME_CONFIG", {light,dark})` 把当前风格 config
|
|
12
|
+
* 灌进 bridge 响应式 APP_THEME_CONFIG(故 init 后响应式 APP_THEME_CONFIG 随切换变,
|
|
13
|
+
* 不再恒等于初始值);用注入的 `storage` 持久化 `{themeStyle,themeIsDark}` 并 init 恢复。
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* 主题注册项(`bridge.theme.add` 第 2 参)——core 侧主题「preset」结构。
|
|
17
|
+
*
|
|
18
|
+
* core 不依赖 plugin,故自定义此最小注册形;plugin-theme 的 `AdminThemePreset`
|
|
19
|
+
* (含 id/label/description/config)是其结构超集,可整坨直接透传:
|
|
20
|
+
* `bridge.theme.add(preset.id, preset)`(多出的 id/description 作 excess 字段被忽略)。
|
|
21
|
+
*/
|
|
22
|
+
export interface AdminThemeEntry {
|
|
23
|
+
/**
|
|
24
|
+
* 风格色值(light/dark 两套 `AppThemeColor`)。
|
|
25
|
+
*
|
|
26
|
+
* 内部做浅快照(`{light:{...},dark:{...}}`)——与调用方对象解耦,且与 bridge
|
|
27
|
+
* 响应式 APP_THEME_CONFIG 的 proxy target 解耦(避免切走后反写注册值)。
|
|
28
|
+
*/
|
|
29
|
+
config: AppThemeConfig;
|
|
30
|
+
/** 展示名(供 `AppTheme.vue` 下拉显示,如中文「柔光悬浮」);缺省回退注册 name 自身。 */
|
|
31
|
+
label?: string;
|
|
32
|
+
}
|
|
33
|
+
/** 主题模块对外能力。 */
|
|
34
|
+
export interface AdminThemeModule {
|
|
35
|
+
/**
|
|
36
|
+
* 注册/覆盖一个风格(插件 install 经 `bridge.theme.add` 调;同名覆盖)。
|
|
37
|
+
*
|
|
38
|
+
* 第 2 参收 {@link AdminThemeEntry}(`{config,label?}`);config 内部浅快照解耦。
|
|
39
|
+
* 若新注册 name 命中持久化恢复的目标风格(init 时尚未注册),自动 `setStyle(name)`。
|
|
40
|
+
*/
|
|
41
|
+
add: (name: string, preset: AdminThemeEntry) => void;
|
|
42
|
+
/** 注销一个风格(`'default'` 不可注销;注销当前风格则回退 `'default'`)。 */
|
|
43
|
+
remove: (name: string) => void;
|
|
44
|
+
/** 切换风格(未注册回退 `'default'`):同步 APP_THEME_CONFIG + 持久化。 */
|
|
45
|
+
setStyle: (name: string) => void;
|
|
46
|
+
/** 切换暗色:写 `themeIsDark` + 持久化。 */
|
|
47
|
+
setDark: (isDark: boolean) => void;
|
|
48
|
+
/** 响应式风格名列表(只读,供 `AppTheme.vue` 下拉;`length>1` 才显示选择)。 */
|
|
49
|
+
list: DeepReadonly<Ref<string[]>>;
|
|
50
|
+
/** 取风格展示名(`add` 注册的 label;缺省回退 name 自身)。 */
|
|
51
|
+
labelOf: (name: string) => string;
|
|
52
|
+
}
|
|
53
|
+
/** 主题 hook 对外契约:模块 + 两个顶层响应式只读真相源。 */
|
|
54
|
+
export interface BridgeThemeHook {
|
|
55
|
+
/** 主题模块(add/remove/setStyle/setDark/list) */
|
|
56
|
+
theme: AdminThemeModule;
|
|
57
|
+
/** 当前风格名(响应式只读;切换真相源,appStore / AppTheme.vue 读此) */
|
|
58
|
+
themeStyle: DeepReadonly<Ref<string>>;
|
|
59
|
+
/** 是否暗色(响应式只读;切换真相源,appStore.isDarkTheme 读此、挂值 composable toggle .dark 读此) */
|
|
60
|
+
themeIsDark: DeepReadonly<Ref<boolean>>;
|
|
61
|
+
}
|
|
62
|
+
/** `createBridgeThemeHook` 入参。 */
|
|
63
|
+
export interface BridgeThemeInit {
|
|
64
|
+
/** init 默认风格 config(= bridge init 传入的 APP_THEME_CONFIG);core 自动 add 为 `'default'` */
|
|
65
|
+
initConfig: AppThemeConfig;
|
|
66
|
+
/**
|
|
67
|
+
* 注入的 config 更新器(= configHook.update 收窄到 APP_THEME_CONFIG)。
|
|
68
|
+
*
|
|
69
|
+
* setStyle 经此把当前风格 config 灌进 bridge 响应式 APP_THEME_CONFIG(一级浅合并
|
|
70
|
+
* 整体替换 light/dark)。复用既有 update 通道,[MUST NOT] 另持一份主题响应式。
|
|
71
|
+
*/
|
|
72
|
+
update: (key: "APP_THEME_CONFIG", partial: Partial<AppThemeConfig>) => void;
|
|
73
|
+
/** 注入的命名空间 storage(= bridge.getStorage());持久化 `{themeStyle,themeIsDark}` */
|
|
74
|
+
storage: StorageLike;
|
|
75
|
+
/** 持久化 key(命名空间已由 storage 加前缀);缺省 `"admin-core-theme"` */
|
|
76
|
+
storageKey?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* bridge 主题 hook 工厂。
|
|
80
|
+
*
|
|
81
|
+
* 每次 `createAdminBridge` 调用各自闭包内构造一份(零模块级单例,守实例隔离)。
|
|
82
|
+
* init:自动 `add('default', initConfig)`;读持久化恢复 `themeIsDark` 即时生效、
|
|
83
|
+
* `themeStyle` 走「desiredStyle 命中再 apply」时序(插件后注册风格亦能恢复)。
|
|
84
|
+
*/
|
|
85
|
+
export declare function createBridgeThemeHook(init: BridgeThemeInit): BridgeThemeHook;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|
|
@@ -39,4 +39,4 @@ export type AppLayoutUserStoreSlice<UserInfo = Record<string, any>> = ReturnType
|
|
|
39
39
|
* (getRoutes / generateRouteMetaRawTree)。loginApi / refreshToken 等 auth
|
|
40
40
|
* 面不通过本 slice 暴露(业务侧通过 appAdminBridge 直读)。
|
|
41
41
|
*/
|
|
42
|
-
export type AppLayoutBridgeSlice = Pick<AdminBridge, "APP_BASE_INFO" | "APP_ENV_INFO" | "APP_CACHE_CONFIG" | "APP_LAYOUT_HEADER_CONFIG" | "APP_LAYOUT_FOOTER_CONFIG" | "APP_LAYOUT_SIDEBAR_CONFIG" | "APP_LAYOUT_BREADCRUMB_CONFIG" | "APP_LAYOUT_BODY_CONFIG" | "APP_LAYOUT_CONFIG" | "APP_ROUTER_META_DEFAULT_CONFIG" | "APP_ROUTER_CONFIG" | "APP_ROUTER_PATHS_CONFIG" | "APP_THEME_CONFIG" | "getRoutes" | "generateRouteMetaRawTree">;
|
|
42
|
+
export type AppLayoutBridgeSlice = Pick<AdminBridge, "APP_BASE_INFO" | "APP_ENV_INFO" | "APP_CACHE_CONFIG" | "APP_LAYOUT_HEADER_CONFIG" | "APP_LAYOUT_FOOTER_CONFIG" | "APP_LAYOUT_SIDEBAR_CONFIG" | "APP_LAYOUT_BREADCRUMB_CONFIG" | "APP_LAYOUT_BODY_CONFIG" | "APP_LAYOUT_VIEWPORT_CONFIG" | "APP_LAYOUT_CONFIG" | "APP_ROUTER_META_DEFAULT_CONFIG" | "APP_ROUTER_CONFIG" | "APP_ROUTER_PATHS_CONFIG" | "APP_THEME_CONFIG" | "theme" | "themeStyle" | "themeIsDark" | "themeColors" | "getRoutes" | "generateRouteMetaRawTree">;
|
|
@@ -46,15 +46,15 @@ declare function __VLS_template(): {
|
|
|
46
46
|
$slots: Readonly<{
|
|
47
47
|
[name: string]: import('vue').Slot<any> | undefined;
|
|
48
48
|
}>;
|
|
49
|
-
$root: ComponentPublicInstance | null;
|
|
50
|
-
$parent: ComponentPublicInstance | null;
|
|
49
|
+
$root: import('vue').ComponentPublicInstance | null;
|
|
50
|
+
$parent: import('vue').ComponentPublicInstance | null;
|
|
51
51
|
$host: Element | null;
|
|
52
52
|
$emit: (event: string, ...args: any[]) => void;
|
|
53
53
|
$el: any;
|
|
54
54
|
$options: import('vue').ComponentOptionsBase<Readonly<import('element-plus').FormItemProps> & Readonly<{}>, {
|
|
55
|
-
size:
|
|
56
|
-
validateMessage:
|
|
57
|
-
validateState:
|
|
55
|
+
size: import('vue').ComputedRef<"" | "default" | "small" | "large">;
|
|
56
|
+
validateMessage: import('vue').Ref<string, string>;
|
|
57
|
+
validateState: import('vue').Ref<"" | "error" | "success" | "validating", "" | "error" | "success" | "validating">;
|
|
58
58
|
validate: (trigger: string, callback?: import('element-plus').FormValidateCallback) => import('element-plus').FormValidationResult;
|
|
59
59
|
clearValidate: () => void;
|
|
60
60
|
resetField: () => void;
|
|
@@ -79,7 +79,7 @@ declare function __VLS_template(): {
|
|
|
79
79
|
unmounted?: (() => void) | (() => void)[];
|
|
80
80
|
renderTracked?: ((e: import('vue').DebuggerEvent) => void) | ((e: import('vue').DebuggerEvent) => void)[];
|
|
81
81
|
renderTriggered?: ((e: import('vue').DebuggerEvent) => void) | ((e: import('vue').DebuggerEvent) => void)[];
|
|
82
|
-
errorCaptured?: ((err: unknown, instance: ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: ComponentPublicInstance | null, info: string) => boolean | void)[];
|
|
82
|
+
errorCaptured?: ((err: unknown, instance: import('vue').ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: import('vue').ComponentPublicInstance | null, info: string) => boolean | void)[];
|
|
83
83
|
};
|
|
84
84
|
$forceUpdate: () => void;
|
|
85
85
|
$nextTick: typeof import('vue').nextTick;
|
|
@@ -151,15 +151,15 @@ declare const __VLS_component: import('vue').DefineComponent<FormMainItemProps,
|
|
|
151
151
|
$slots: Readonly<{
|
|
152
152
|
[name: string]: import('vue').Slot<any> | undefined;
|
|
153
153
|
}>;
|
|
154
|
-
$root: ComponentPublicInstance | null;
|
|
155
|
-
$parent: ComponentPublicInstance | null;
|
|
154
|
+
$root: import('vue').ComponentPublicInstance | null;
|
|
155
|
+
$parent: import('vue').ComponentPublicInstance | null;
|
|
156
156
|
$host: Element | null;
|
|
157
157
|
$emit: (event: string, ...args: any[]) => void;
|
|
158
158
|
$el: any;
|
|
159
159
|
$options: import('vue').ComponentOptionsBase<Readonly<import('element-plus').FormItemProps> & Readonly<{}>, {
|
|
160
|
-
size:
|
|
161
|
-
validateMessage:
|
|
162
|
-
validateState:
|
|
160
|
+
size: import('vue').ComputedRef<"" | "default" | "small" | "large">;
|
|
161
|
+
validateMessage: import('vue').Ref<string, string>;
|
|
162
|
+
validateState: import('vue').Ref<"" | "error" | "success" | "validating", "" | "error" | "success" | "validating">;
|
|
163
163
|
validate: (trigger: string, callback?: import('element-plus').FormValidateCallback) => import('element-plus').FormValidationResult;
|
|
164
164
|
clearValidate: () => void;
|
|
165
165
|
resetField: () => void;
|
|
@@ -184,7 +184,7 @@ declare const __VLS_component: import('vue').DefineComponent<FormMainItemProps,
|
|
|
184
184
|
unmounted?: (() => void) | (() => void)[];
|
|
185
185
|
renderTracked?: ((e: import('vue').DebuggerEvent) => void) | ((e: import('vue').DebuggerEvent) => void)[];
|
|
186
186
|
renderTriggered?: ((e: import('vue').DebuggerEvent) => void) | ((e: import('vue').DebuggerEvent) => void)[];
|
|
187
|
-
errorCaptured?: ((err: unknown, instance: ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: ComponentPublicInstance | null, info: string) => boolean | void)[];
|
|
187
|
+
errorCaptured?: ((err: unknown, instance: import('vue').ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: import('vue').ComponentPublicInstance | null, info: string) => boolean | void)[];
|
|
188
188
|
};
|
|
189
189
|
$forceUpdate: () => void;
|
|
190
190
|
$nextTick: typeof import('vue').nextTick;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { FormItemConfigList } from './types';
|
|
2
|
+
import { ColProps } from 'element-plus';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
/** 所属父 item key(注册到父 FormMain exposeMap 的索引) */
|
|
5
|
+
nestKey: string;
|
|
6
|
+
/** 子表单配置列表 */
|
|
7
|
+
list: FormItemConfigList;
|
|
8
|
+
layout?: Partial<ColProps>;
|
|
9
|
+
rowGutter?: number;
|
|
10
|
+
/** 联结组件外环阴影颜色;缺省走 CSS 变量主题自适配(亮/暗),仅显式传时内联覆盖 */
|
|
11
|
+
shadowColor?: string;
|
|
12
|
+
/** 父 item 代表 span(P3 rebase 算因子用;helper 经 resolveLayoutSpan(layout) 传入) */
|
|
13
|
+
parentSpan?: number;
|
|
14
|
+
/** 是否叠本层嵌套布局 rebase(缺省 true;false = 逆向逃生口,layout 原样直透) */
|
|
15
|
+
rebase?: boolean;
|
|
16
|
+
};
|
|
17
|
+
type __VLS_PublicProps = {
|
|
18
|
+
modelValue?: Record<string, any>;
|
|
19
|
+
} & __VLS_Props;
|
|
20
|
+
declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
21
|
+
"update:modelValue": (value: Record<string, any>) => any;
|
|
22
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
23
|
+
"onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
|
|
24
|
+
}>, {
|
|
25
|
+
rebase: boolean;
|
|
26
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
27
|
+
childRef: {
|
|
28
|
+
validate: () => Promise<void>;
|
|
29
|
+
resetFields: () => void;
|
|
30
|
+
clearValidate: (key?: string) => void;
|
|
31
|
+
generate: () => Record<string, any>;
|
|
32
|
+
parse: (stringifyData: import('./types').ExcludeNeverProperties<import('./types').ExtractFormStringifyRawFromObject<Record<string, any>, Record<string, any>>>) => Record<string, any>;
|
|
33
|
+
stringify: () => import('./types').ExcludeNeverProperties<import('./types').ExtractFormStringifyRawFromObject<Record<string, any>, Record<string, any>>>;
|
|
34
|
+
} | null;
|
|
35
|
+
}, any>;
|
|
36
|
+
export default _default;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { VNodeChild } from 'vue';
|
|
2
|
+
import { ColProps } from 'element-plus';
|
|
3
|
+
import { FormItemConfigList } from './types';
|
|
4
|
+
import { ActionBtnConfirmConfig } from '../display';
|
|
5
|
+
declare const _default: <T extends Record<string, any>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
6
|
+
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
7
|
+
readonly "onUpdate:modelValue"?: ((value: T[]) => any) | undefined;
|
|
8
|
+
} & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>, "onUpdate:modelValue"> & ({
|
|
9
|
+
modelValue?: T[];
|
|
10
|
+
} & {
|
|
11
|
+
/** 所属父 item key(注册到父 FormMain exposeMap 的索引) */
|
|
12
|
+
nestKey: string;
|
|
13
|
+
/** 每行子表单配置列表 */
|
|
14
|
+
list: FormItemConfigList;
|
|
15
|
+
/** 行稳定标识字段(指向 T 内稳定 id);缺省走内部自增 rowId */
|
|
16
|
+
rowKey?: string;
|
|
17
|
+
/** 新增行工厂;缺省 generateFormData(list) 产子默认对象 */
|
|
18
|
+
itemFactory?: () => T;
|
|
19
|
+
/** 最少行数(删到 min 禁删;硬约束走父 item rules 长度校验) */
|
|
20
|
+
min?: number;
|
|
21
|
+
/** 最多行数(达上限禁新增;硬约束走父 item rules 长度校验) */
|
|
22
|
+
max?: number;
|
|
23
|
+
layout?: Partial<ColProps>;
|
|
24
|
+
rowGutter?: number;
|
|
25
|
+
addText?: string;
|
|
26
|
+
removeText?: string;
|
|
27
|
+
/** 顶部自定义渲染(render-fn prop,替代 template slot;label 由父 FormItem 渲染) */
|
|
28
|
+
headerRender?: (scope: {
|
|
29
|
+
count: number;
|
|
30
|
+
max: number;
|
|
31
|
+
}) => VNodeChild;
|
|
32
|
+
/** 底部自定义渲染;缺省 = 内置「新增」按钮 */
|
|
33
|
+
footerRender?: (scope: {
|
|
34
|
+
count: number;
|
|
35
|
+
max: number;
|
|
36
|
+
canAdd: boolean;
|
|
37
|
+
add: () => void;
|
|
38
|
+
}) => VNodeChild;
|
|
39
|
+
/** 联结组件外环 + 每行分割阴影颜色 */
|
|
40
|
+
shadowColor?: string;
|
|
41
|
+
/** 父 item 代表 span(P3 rebase 算因子用;helper 经 resolveLayoutSpan(layout) 传入) */
|
|
42
|
+
parentSpan?: number;
|
|
43
|
+
/** 是否叠本层嵌套布局 rebase(缺省 true;false = 逆向逃生口,layout 原样直透) */
|
|
44
|
+
rebase?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* 行删除二次确认(破坏性操作防误删):
|
|
47
|
+
* - `true`(默认)→ 默认 popconfirm「确认删除该项?」(danger)
|
|
48
|
+
* - `false` → 不弹确认,直删(回旧行为)
|
|
49
|
+
* - 对象 → 自定义 ActionBtnConfirmConfig
|
|
50
|
+
*/
|
|
51
|
+
removeConfirm?: boolean | ActionBtnConfirmConfig;
|
|
52
|
+
}) & Partial<{}>> & import('vue').PublicProps;
|
|
53
|
+
expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
|
|
54
|
+
attrs: any;
|
|
55
|
+
slots: {};
|
|
56
|
+
emit: (evt: "update:modelValue", value: T[]) => void;
|
|
57
|
+
}>) => import('vue').VNode & {
|
|
58
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
59
|
+
};
|
|
60
|
+
export default _default;
|
|
61
|
+
type __VLS_PrettifyLocal<T> = {
|
|
62
|
+
[K in keyof T]: T[K];
|
|
63
|
+
} & {};
|