@done-coding/admin-core 0.1.3-alpha.0 → 0.1.4-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/es/bridge/index.mjs +75 -0
- package/es/hooks/activated.mjs +36 -28
- package/es/index.mjs +106 -102
- package/es/store/user.mjs +91 -0
- package/package.json +3 -3
- package/types/bridge/index.d.ts +261 -0
- package/types/hooks/activated.d.ts +9 -5
- package/types/index.d.ts +2 -0
- package/types/store/index.d.ts +1 -0
- package/types/store/user.d.ts +62 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
function w() {
|
|
2
|
+
let l, h, c, T, I, k = !1, t, i, o, f, g, u, s, A;
|
|
3
|
+
const n = (e) => `admin bridge: ${e} 未注册`, r = () => {
|
|
4
|
+
if (!k) throw new Error("admin bridge: 未 init");
|
|
5
|
+
}, a = {
|
|
6
|
+
init(e) {
|
|
7
|
+
return l = e.appConfig, h = e.storage, c = e.routes, T = e.userInfoAccess, I = e.getUserInfoInitFn, k = !0, a;
|
|
8
|
+
},
|
|
9
|
+
register(e) {
|
|
10
|
+
r(), e.getToken && (t = e.getToken), e.goToLogin && (i = e.goToLogin), e.refreshToken && (o = e.refreshToken), e.refreshAuth && (f = e.refreshAuth), e.loginApi && (g = e.loginApi), e.logoutApi && (u = e.logoutApi), e.getUserInfoApi && (s = e.getUserInfoApi), e.refreshTokenApi && (A = e.refreshTokenApi);
|
|
11
|
+
},
|
|
12
|
+
// pre-init 同步 throw;post-init 未注册同步 throw;已注册返回 undefined 是合法业务态不 throw
|
|
13
|
+
// v3 终锁 Δ8b:零参 facade(BR-1 ③ 终裁——core 对 UserInfo 不透明 + 拦截器无 info 源)
|
|
14
|
+
getToken() {
|
|
15
|
+
if (r(), !t) throw new Error(n("getToken"));
|
|
16
|
+
return t();
|
|
17
|
+
},
|
|
18
|
+
// pre-init 同步 throw;post-init 同步对
|
|
19
|
+
goToLogin() {
|
|
20
|
+
if (r(), !i) throw new Error(n("goToLogin"));
|
|
21
|
+
i();
|
|
22
|
+
},
|
|
23
|
+
// 异步对:init-gate 优先于「异步对返 reject」——pre-init 一律同步 throw;
|
|
24
|
+
// post-init 未注册才返回 rejected Promise(既有降级语义保留)。
|
|
25
|
+
refreshToken() {
|
|
26
|
+
return r(), o ? o().then(() => {
|
|
27
|
+
}) : Promise.reject(new Error(n("refreshToken")));
|
|
28
|
+
},
|
|
29
|
+
// 异步对:同上
|
|
30
|
+
refreshAuth() {
|
|
31
|
+
return r(), f ? f().then(() => {
|
|
32
|
+
}) : Promise.reject(new Error(n("refreshAuth")));
|
|
33
|
+
},
|
|
34
|
+
// pre-init 同步 throw;post-init 返回 init 注册引用
|
|
35
|
+
getAppConfig() {
|
|
36
|
+
return r(), l;
|
|
37
|
+
},
|
|
38
|
+
// pre-init 同步 throw;post-init 返回 init 注册引用
|
|
39
|
+
getStorage() {
|
|
40
|
+
return r(), h;
|
|
41
|
+
},
|
|
42
|
+
// pre-init 同步 throw;post-init 返回 init 注册引用
|
|
43
|
+
getRoutes() {
|
|
44
|
+
return r(), c;
|
|
45
|
+
},
|
|
46
|
+
// pre-init 同步 throw;post-init 返回 init 注册引用(v3 终锁 Δ0d,镜像 getRoutes 范式)
|
|
47
|
+
getUserInfoAccess() {
|
|
48
|
+
return r(), T;
|
|
49
|
+
},
|
|
50
|
+
// pre-init 同步 throw;post-init 返回 init 注册引用(v3 终锁 Δ0d,镜像 getRoutes 范式)
|
|
51
|
+
getUserInfoInitFn() {
|
|
52
|
+
return r(), I;
|
|
53
|
+
},
|
|
54
|
+
// 异步对:pre-init 同步 throw;post-init 未注册返回 rejected 原生 Error(#4a-2 per-method 降级)
|
|
55
|
+
loginApi(e) {
|
|
56
|
+
return r(), g ? g(e) : Promise.reject(new Error(n("loginApi")));
|
|
57
|
+
},
|
|
58
|
+
// 异步对:同上
|
|
59
|
+
logoutApi() {
|
|
60
|
+
return r(), u ? u() : Promise.reject(new Error(n("logoutApi")));
|
|
61
|
+
},
|
|
62
|
+
// 异步对:同上
|
|
63
|
+
getUserInfoApi() {
|
|
64
|
+
return r(), s ? s() : Promise.reject(new Error(n("getUserInfoApi")));
|
|
65
|
+
},
|
|
66
|
+
// 异步对:同上
|
|
67
|
+
refreshTokenApi(e) {
|
|
68
|
+
return r(), A ? A(e) : Promise.reject(new Error(n("refreshTokenApi")));
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
return a;
|
|
72
|
+
}
|
|
73
|
+
export {
|
|
74
|
+
w as createAdminBridge
|
|
75
|
+
};
|
package/es/hooks/activated.mjs
CHANGED
|
@@ -1,40 +1,48 @@
|
|
|
1
|
-
import { watch as
|
|
2
|
-
const
|
|
3
|
-
const
|
|
1
|
+
import { watch as o, ref as n, computed as v, readonly as r, onMounted as u, onActivated as A, onDeactivated as m, onBeforeUnmount as f } from "vue";
|
|
2
|
+
const s = (e) => {
|
|
3
|
+
const t = n({
|
|
4
4
|
isActivated: !1,
|
|
5
5
|
triggerType: "mounted"
|
|
6
|
-
}), i =
|
|
7
|
-
|
|
6
|
+
}), i = v(() => t.value.isActivated), a = v(() => r(t.value)), d = (c) => {
|
|
7
|
+
t.value = c;
|
|
8
8
|
};
|
|
9
|
-
return
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
return u(() => {
|
|
10
|
+
d({ isActivated: !0, triggerType: "mounted" }), A(() => {
|
|
11
|
+
d({ isActivated: !0, triggerType: "activated" });
|
|
12
12
|
});
|
|
13
|
-
}),
|
|
14
|
-
|
|
15
|
-
}),
|
|
16
|
-
|
|
17
|
-
}),
|
|
13
|
+
}), m(() => {
|
|
14
|
+
d({ isActivated: !1, triggerType: "deactivated" });
|
|
15
|
+
}), f(() => {
|
|
16
|
+
d({ isActivated: !1, triggerType: "unmounted" });
|
|
17
|
+
}), o(
|
|
18
|
+
t,
|
|
19
|
+
(c) => {
|
|
20
|
+
e == null || e(c);
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
immediate: !0
|
|
24
|
+
}
|
|
25
|
+
), {
|
|
18
26
|
isActivated: i,
|
|
19
|
-
activatedInfo:
|
|
27
|
+
activatedInfo: a
|
|
20
28
|
};
|
|
21
|
-
},
|
|
22
|
-
const { activatedInfo:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
(
|
|
26
|
-
|
|
29
|
+
}, l = (e) => {
|
|
30
|
+
const { activatedInfo: t } = s();
|
|
31
|
+
o(
|
|
32
|
+
t,
|
|
33
|
+
(i) => {
|
|
34
|
+
i.isActivated && e(i);
|
|
27
35
|
},
|
|
28
36
|
{
|
|
29
37
|
immediate: !0
|
|
30
38
|
}
|
|
31
39
|
);
|
|
32
|
-
},
|
|
33
|
-
const { activatedInfo:
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
}, p = (e, t) => {
|
|
41
|
+
const { activatedInfo: i } = s();
|
|
42
|
+
o(
|
|
43
|
+
i,
|
|
36
44
|
(a) => {
|
|
37
|
-
a.isActivated ? e(a) :
|
|
45
|
+
a.isActivated ? e(a) : t(a);
|
|
38
46
|
},
|
|
39
47
|
{
|
|
40
48
|
immediate: !0
|
|
@@ -42,7 +50,7 @@ const v = () => {
|
|
|
42
50
|
);
|
|
43
51
|
};
|
|
44
52
|
export {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
s as useActivated,
|
|
54
|
+
p as useActivatedEvent,
|
|
55
|
+
l as useActivatedExec
|
|
48
56
|
};
|
package/es/index.mjs
CHANGED
|
@@ -5,120 +5,124 @@ import { miscInstall as a } from "./components/misc/index.mjs";
|
|
|
5
5
|
import { modalInstall as m } from "./components/modal/index.mjs";
|
|
6
6
|
import { tableInstall as f } from "./components/table/index.mjs";
|
|
7
7
|
import { listPageInstall as s } from "./components/list-page/index.mjs";
|
|
8
|
-
import {
|
|
9
|
-
import { default as
|
|
10
|
-
import { default as C } from "./components/misc/
|
|
11
|
-
import { default as F } from "./components/
|
|
12
|
-
import { default as R } from "./components/
|
|
13
|
-
import { default as O } from "./components/form/
|
|
14
|
-
import { default as D } from "./components/form/
|
|
15
|
-
import { default as h } from "./components/form/
|
|
16
|
-
import { default as b } from "./components/form/
|
|
17
|
-
import { default as v } from "./components/
|
|
18
|
-
import { default as
|
|
19
|
-
import { default as
|
|
20
|
-
import { default as W } from "./components/
|
|
21
|
-
import { default as k } from "./components/
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import { default as Oe } from "./components/form/
|
|
31
|
-
import { default as De } from "./components/
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import { default as He } from "./components/
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
8
|
+
import { createAdminBridge as g } from "./bridge/index.mjs";
|
|
9
|
+
import { default as A } from "./components/misc/ActionButton.vue.mjs";
|
|
10
|
+
import { default as C } from "./components/misc/ActionButtonDanger.vue.mjs";
|
|
11
|
+
import { default as F } from "./components/misc/ActionButtonWarn.vue.mjs";
|
|
12
|
+
import { default as R } from "./components/modal/DetailModal.vue.mjs";
|
|
13
|
+
import { default as O } from "./components/form/FormMain.vue.mjs";
|
|
14
|
+
import { default as D } from "./components/form/FormRadioGroup.vue.mjs";
|
|
15
|
+
import { default as h } from "./components/form/FormSelect.vue.mjs";
|
|
16
|
+
import { default as b } from "./components/form/FormTree.vue.mjs";
|
|
17
|
+
import { default as v } from "./components/form/FormVerifyCode.vue.mjs";
|
|
18
|
+
import { default as U } from "./components/display/HeightProvider.vue.mjs";
|
|
19
|
+
import { default as w } from "./components/menu/MenuItemSub.vue.mjs";
|
|
20
|
+
import { default as W } from "./components/menu/MenuTree.vue.mjs";
|
|
21
|
+
import { default as k } from "./components/misc/TriggerAutoImport.vue.mjs";
|
|
22
|
+
import { default as X } from "./components/display/WatchSize.vue.mjs";
|
|
23
|
+
import { APP_API_LIST_MODEL_KEY_CONFIG as Q } from "./config/list-model.mjs";
|
|
24
|
+
import { default as q } from "./components/misc/AutoRefresh.vue.mjs";
|
|
25
|
+
import { BODY_CONTENT_VIEWPORT_HEIGHT as Z, FULLSCREEN_HEIGHT_CHANNEL as $ } from "./inject/key.mjs";
|
|
26
|
+
import { default as te } from "./components/modal/ConfirmModal.vue.mjs";
|
|
27
|
+
import { EXPORT_MAX_LIMIT as re, OPERATE_COLUMN_PROP as ae, exportCSV as me, pickExportColumns as fe } from "./utils/export.mjs";
|
|
28
|
+
import { FORM_CONFIG_SELECT_ALL_VALUE as le, getConfirmPasswordRule as ue, passwordRule as ie, setFormComponentType as pe } from "./helpers/form.mjs";
|
|
29
|
+
import { FORM_ITEM_CHANGE_LOADING as xe, generateFormData as de, getBlurSubmit as ce, getChangeSubmit as Ee, getDatePickerShortcuts as Ie, getEnterSubmit as ge, getPlaceholder as _e, getVModelSugar as Ae, parseFormData as Te, resolveFormLayout as Ce, setInputComponent as Me, setSelectComponent as Fe, stringifyFormData as Le, swiftFormItemConfig as Re } from "./components/form/utils.mjs";
|
|
30
|
+
import { default as Oe } from "./components/form/FormSearch.vue.mjs";
|
|
31
|
+
import { default as De } from "./components/form/FormVerifyImage.vue.mjs";
|
|
32
|
+
import { default as he } from "./components/list-page/ListPage.vue.mjs";
|
|
33
|
+
import { ROUTE_MODULE_LEVEL as be, TabsMainReplaceQueryKey as Ge } from "./config/route.mjs";
|
|
34
|
+
import { default as He } from "./components/table/TableMain.vue.mjs";
|
|
35
|
+
import { default as Ve } from "./components/display/TabsMain.vue.mjs";
|
|
36
|
+
import { countAll as Be, createListApi as We, fetchListAll as Ke } from "./helpers/list-helper.mjs";
|
|
37
|
+
import { createGenerateRouteMetaRawTree as ze } from "./helpers/route.mjs";
|
|
38
|
+
import { createStorageWithNamespace as Ye } from "./helpers/storage.mjs";
|
|
39
|
+
import { createUseState as je } from "./helpers/state.mjs";
|
|
40
|
+
import { createUserStore as Je } from "./store/user.mjs";
|
|
41
|
+
import { flatRouteMetaResolveRaw as $e, getRoutePermissionKey as et } from "./utils/router.mjs";
|
|
42
|
+
import { getId as ot } from "./utils/id.mjs";
|
|
43
|
+
import { timeCountDown as at } from "./utils/time.mjs";
|
|
44
|
+
import { useActivated as ft, useActivatedEvent as st, useActivatedExec as lt } from "./hooks/activated.mjs";
|
|
45
|
+
import { useFeelSize as it } from "./hooks/feel-size.mjs";
|
|
46
|
+
import { useMenusDataDispatch as nt } from "./hooks/menus-dispatch.mjs";
|
|
47
|
+
import { useTimeout as dt } from "./hooks/timeout.mjs";
|
|
46
48
|
const c = {
|
|
47
49
|
install(e) {
|
|
48
50
|
e.use(t), e.use(o), e.use(r), e.use(a), e.use(m), e.use(f), e.use(s);
|
|
49
51
|
}
|
|
50
52
|
};
|
|
51
53
|
export {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Ye as
|
|
54
|
+
Q as APP_API_LIST_MODEL_KEY_CONFIG,
|
|
55
|
+
A as ActionButton,
|
|
56
|
+
C as ActionButtonDanger,
|
|
57
|
+
F as ActionButtonWarn,
|
|
58
|
+
q as AutoRefresh,
|
|
59
|
+
Z as BODY_CONTENT_VIEWPORT_HEIGHT,
|
|
60
|
+
te as ConfirmModal,
|
|
61
|
+
R as DetailModal,
|
|
62
|
+
re as EXPORT_MAX_LIMIT,
|
|
63
|
+
le as FORM_CONFIG_SELECT_ALL_VALUE,
|
|
64
|
+
xe as FORM_ITEM_CHANGE_LOADING,
|
|
65
|
+
$ as FULLSCREEN_HEIGHT_CHANNEL,
|
|
66
|
+
O as FormMain,
|
|
67
|
+
D as FormRadioGroup,
|
|
68
|
+
Oe as FormSearch,
|
|
69
|
+
h as FormSelect,
|
|
70
|
+
b as FormTree,
|
|
71
|
+
v as FormVerifyCode,
|
|
72
|
+
De as FormVerifyImage,
|
|
73
|
+
U as HeightProvider,
|
|
74
|
+
he as ListPage,
|
|
75
|
+
w as MenuItemSub,
|
|
76
|
+
W as MenuTree,
|
|
77
|
+
ae as OPERATE_COLUMN_PROP,
|
|
78
|
+
be as ROUTE_MODULE_LEVEL,
|
|
79
|
+
He as TableMain,
|
|
80
|
+
Ve as TabsMain,
|
|
81
|
+
Ge as TabsMainReplaceQueryKey,
|
|
82
|
+
k as TriggerAutoImport,
|
|
83
|
+
X as WatchSize,
|
|
84
|
+
Be as countAll,
|
|
85
|
+
g as createAdminBridge,
|
|
86
|
+
ze as createGenerateRouteMetaRawTree,
|
|
87
|
+
We as createListApi,
|
|
88
|
+
Ye as createStorageWithNamespace,
|
|
89
|
+
je as createUseState,
|
|
90
|
+
Je as createUserStore,
|
|
87
91
|
r as displayInstall,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
me as exportCSV,
|
|
93
|
+
Ke as fetchListAll,
|
|
94
|
+
$e as flatRouteMetaResolveRaw,
|
|
91
95
|
t as formInstall,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
96
|
+
de as generateFormData,
|
|
97
|
+
ce as getBlurSubmit,
|
|
98
|
+
Ee as getChangeSubmit,
|
|
99
|
+
ue as getConfirmPasswordRule,
|
|
100
|
+
Ie as getDatePickerShortcuts,
|
|
101
|
+
ge as getEnterSubmit,
|
|
102
|
+
ot as getId,
|
|
103
|
+
_e as getPlaceholder,
|
|
104
|
+
et as getRoutePermissionKey,
|
|
105
|
+
Ae as getVModelSugar,
|
|
102
106
|
c as installComponents,
|
|
103
107
|
s as listPageInstall,
|
|
104
108
|
o as menuInstall,
|
|
105
109
|
a as miscInstall,
|
|
106
110
|
m as modalInstall,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
Te as parseFormData,
|
|
112
|
+
ie as passwordRule,
|
|
113
|
+
fe as pickExportColumns,
|
|
114
|
+
Ce as resolveFormLayout,
|
|
115
|
+
pe as setFormComponentType,
|
|
116
|
+
Me as setInputComponent,
|
|
117
|
+
Fe as setSelectComponent,
|
|
118
|
+
Le as stringifyFormData,
|
|
119
|
+
Re as swiftFormItemConfig,
|
|
116
120
|
f as tableInstall,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
at as timeCountDown,
|
|
122
|
+
ft as useActivated,
|
|
123
|
+
st as useActivatedEvent,
|
|
124
|
+
lt as useActivatedExec,
|
|
125
|
+
it as useFeelSize,
|
|
126
|
+
nt as useMenusDataDispatch,
|
|
127
|
+
dt as useTimeout
|
|
124
128
|
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { defineStore as L } from "pinia";
|
|
2
|
+
import { computed as s, watch as A } from "vue";
|
|
3
|
+
import R from "lodash/get";
|
|
4
|
+
import M from "lodash/set";
|
|
5
|
+
import O from "lodash/cloneDeep";
|
|
6
|
+
import { createUseState as H } from "../helpers/state.mjs";
|
|
7
|
+
import { createGenerateRouteMetaRawTree as K } from "../helpers/route.mjs";
|
|
8
|
+
import { flatRouteMetaResolveRaw as b } from "../utils/router.mjs";
|
|
9
|
+
function Q(S) {
|
|
10
|
+
const { bridge: o } = S;
|
|
11
|
+
return L("USER", () => {
|
|
12
|
+
const T = o.getUserInfoInitFn(), l = o.getUserInfoAccess(), p = (e) => typeof e == "string" ? {
|
|
13
|
+
get: (t) => R(t, e),
|
|
14
|
+
set: (t, f) => {
|
|
15
|
+
const d = O(t);
|
|
16
|
+
return M(d, e, f), d;
|
|
17
|
+
}
|
|
18
|
+
} : { get: e.get, set: e.set }, c = p(l.token), g = p(l.refreshToken), k = (e) => R(e, "permission"), P = o.getAppConfig().APP_CACHE_CONFIG.namespace, n = H(P)(
|
|
19
|
+
T(),
|
|
20
|
+
{
|
|
21
|
+
moduleKey: "USER_STORE",
|
|
22
|
+
debug: !1,
|
|
23
|
+
cache: !0
|
|
24
|
+
}
|
|
25
|
+
), r = s(() => n.state), a = s(() => c.get(r.value)), u = s(() => !!a.value), v = s(() => g.get(r.value)), h = s(() => k(r.value) || []), I = K(
|
|
26
|
+
o.getAppConfig().APP_ROUTER_META_DEFAULT_CONFIG
|
|
27
|
+
), y = s(
|
|
28
|
+
() => I(o.getRoutes(), {
|
|
29
|
+
// 配置权限且有权限 或 (未配置权限无子路由(即末端子路由) 或 子路由有权限)
|
|
30
|
+
filterFn: (e, t, f) => e.checkPermission ? h.value.includes(e.permissionKey) : !f || t,
|
|
31
|
+
sortFn: (e, t) => e.menuSort - t.menuSort
|
|
32
|
+
})
|
|
33
|
+
), U = s(() => b(y.value)), _ = s(() => U.value.map((e) => e.path)), m = () => {
|
|
34
|
+
n.resetState();
|
|
35
|
+
}, F = async () => {
|
|
36
|
+
try {
|
|
37
|
+
u.value && await o.logoutApi();
|
|
38
|
+
} catch (e) {
|
|
39
|
+
console.error("退出登录失败", e);
|
|
40
|
+
}
|
|
41
|
+
m();
|
|
42
|
+
}, w = async (e) => {
|
|
43
|
+
m();
|
|
44
|
+
const { data: t } = await o.loginApi(e);
|
|
45
|
+
n.updateState(t);
|
|
46
|
+
}, i = async () => {
|
|
47
|
+
const { data: e } = await o.getUserInfoApi(), t = g.set(
|
|
48
|
+
c.set(e, a.value),
|
|
49
|
+
v.value
|
|
50
|
+
);
|
|
51
|
+
return n.updateState(t), e;
|
|
52
|
+
}, E = async () => {
|
|
53
|
+
const { data: e } = await o.refreshTokenApi({
|
|
54
|
+
Authorization: v.value
|
|
55
|
+
});
|
|
56
|
+
n.updateState(
|
|
57
|
+
c.set(r.value, e.token)
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
o.register({
|
|
61
|
+
getToken: () => a.value,
|
|
62
|
+
refreshToken: E,
|
|
63
|
+
refreshAuth: i
|
|
64
|
+
});
|
|
65
|
+
const C = (e) => _.value.includes(e), G = (e) => h.value.includes(e);
|
|
66
|
+
return A(
|
|
67
|
+
u,
|
|
68
|
+
(e, t) => {
|
|
69
|
+
e && (t ?? i());
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
immediate: !0
|
|
73
|
+
}
|
|
74
|
+
), A(a, (e, t) => {
|
|
75
|
+
e && t && i();
|
|
76
|
+
}), {
|
|
77
|
+
userInfo: r,
|
|
78
|
+
token: a,
|
|
79
|
+
isLogin: u,
|
|
80
|
+
login: w,
|
|
81
|
+
logout: F,
|
|
82
|
+
noApiLogout: m,
|
|
83
|
+
getInfo: i,
|
|
84
|
+
havePermissionByPath: C,
|
|
85
|
+
havePermissionByKey: G
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
export {
|
|
90
|
+
Q as createUserStore
|
|
91
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@done-coding/admin-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4-alpha.0",
|
|
4
4
|
"description": "后台管理核心",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "lib/index.cjs",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"repository": {
|
|
35
35
|
"type": "git",
|
|
36
|
-
"url": "https://
|
|
36
|
+
"url": "https://github.com/done-coding/done-coding-admin.git",
|
|
37
37
|
"directory": "packages/core"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
@@ -77,5 +77,5 @@
|
|
|
77
77
|
"node": ">=18.0.0",
|
|
78
78
|
"pnpm": ">=9.0.0"
|
|
79
79
|
},
|
|
80
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "e53455556dc0b6be614016fc8db37a028ec48986"
|
|
81
81
|
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { RouteRecordRaw } from 'vue-router';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 认证桥接无状态纯工厂。
|
|
5
|
+
*
|
|
6
|
+
* core 模块级零状态——每次调用 `createAdminBridge()` 在函数作用域内新建一组
|
|
7
|
+
* 闭包变量,返回实例方法闭包持有这组引用。core [MUST NOT] 持已实例化单例
|
|
8
|
+
* (避免 dist/src 双 module instance 分裂,规避机制见 design §2.3,
|
|
9
|
+
* 结构上不持单例,[MUST NOT] 用 Symbol.for / globalThis 兜底)。
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* register 入参类型,全字段 optional + 「有值才更新」增量合并。
|
|
13
|
+
*
|
|
14
|
+
* #4e 增 4 个增量可选业务 api(loginApi/logoutApi/getUserInfoApi/refreshTokenApi),
|
|
15
|
+
* 由 `createUserStore` 薄壳侧 register 注入;getToken/refreshToken/refreshAuth 由
|
|
16
|
+
* `createUserStore` core 工厂 setup 内自 register(裁决 2/3)。
|
|
17
|
+
*/
|
|
18
|
+
export interface AdminBridgeRegisterOptions<UserInfo = unknown, LoginParams = unknown> {
|
|
19
|
+
/** 取 token(v3 终锁 BR-1 ③ 终裁:零参 facade——core 对 UserInfo 不透明 + 拦截器无 info 源,泛型 `<UserInfo>` 纯透传不沾 getToken 签名) */
|
|
20
|
+
getToken?: () => string | undefined;
|
|
21
|
+
/** 跳转登录 */
|
|
22
|
+
goToLogin?: () => void;
|
|
23
|
+
/** 刷新 token */
|
|
24
|
+
refreshToken?: () => Promise<unknown>;
|
|
25
|
+
/** 刷新鉴权(重新拉取用户信息) */
|
|
26
|
+
refreshAuth?: () => Promise<unknown>;
|
|
27
|
+
/** 登录 api(对应 app accountLogin),增量可选 */
|
|
28
|
+
loginApi?: (params: LoginParams) => Promise<{
|
|
29
|
+
data: UserInfo;
|
|
30
|
+
}>;
|
|
31
|
+
/** 退出登录 api(对应 app accountLogout),增量可选 */
|
|
32
|
+
logoutApi?: () => Promise<unknown>;
|
|
33
|
+
/** 取用户信息 api(对应 app getLoginAccountInfo,含 {user_info} wrapper 连壳,见 design D2),增量可选 */
|
|
34
|
+
getUserInfoApi?: () => Promise<{
|
|
35
|
+
data: UserInfo;
|
|
36
|
+
}>;
|
|
37
|
+
/** 刷新 token api(对应 app refreshAccountToken),增量可选 */
|
|
38
|
+
refreshTokenApi?: (headers: {
|
|
39
|
+
Authorization: string;
|
|
40
|
+
}) => Promise<{
|
|
41
|
+
data: {
|
|
42
|
+
token: string;
|
|
43
|
+
};
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* pinia persist storage 适配器最小接口。
|
|
48
|
+
*
|
|
49
|
+
* 仅约束 `store/app.ts` persist 适配器实际依赖的三方法,是浏览器 `Storage`
|
|
50
|
+
* 的结构子集——`createStorageWithNamespace()` 返回的命名空间 Storage 可直接赋值兼容。
|
|
51
|
+
*/
|
|
52
|
+
export interface StorageLike {
|
|
53
|
+
/** 读取键值,未命中返回 null */
|
|
54
|
+
getItem: (key: string) => string | null;
|
|
55
|
+
/** 写入键值 */
|
|
56
|
+
setItem: (key: string, value: string) => void;
|
|
57
|
+
/** 删除键值 */
|
|
58
|
+
removeItem: (key: string) => void;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 应用主题颜色类型。
|
|
62
|
+
*
|
|
63
|
+
* 镜像 app 端 `@/config` `AppThemeColor` 全字段——store/app 的 `theme`
|
|
64
|
+
* computed 透出后由 app-layout 消费点访问 `primaryColor` 等全字段,故 [MUST]
|
|
65
|
+
* 完整镜像,[MUST NOT] 收窄到 store/app 体内直接读的子集(否则消费点 TS2339)。
|
|
66
|
+
*/
|
|
67
|
+
export interface AppThemeColor {
|
|
68
|
+
/** 背景色 */
|
|
69
|
+
bodyColor: string;
|
|
70
|
+
/** 基础色 */
|
|
71
|
+
baseColor: string;
|
|
72
|
+
/** 主色调 */
|
|
73
|
+
primaryColor: string;
|
|
74
|
+
/** 成功色 */
|
|
75
|
+
successColor: string;
|
|
76
|
+
/** 警告色 */
|
|
77
|
+
warningColor: string;
|
|
78
|
+
/** 危险色 */
|
|
79
|
+
dangerColor: string;
|
|
80
|
+
/** 错误色 */
|
|
81
|
+
errorColor: string;
|
|
82
|
+
/** 信息色 */
|
|
83
|
+
infoColor: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* `store/app.ts` 实际消费的 app config 子集结构。
|
|
87
|
+
*
|
|
88
|
+
* 字段名与层级镜像 app 端 `@/config` 原结构([MUST NOT] 重命名);覆盖
|
|
89
|
+
* store/app 现消费字段(含 `theme` 透出后消费点所需全字段),[MUST NOT] 扩面
|
|
90
|
+
* 到全量 app config。core 不能 import app,故在此显式定义等价 interface。
|
|
91
|
+
*/
|
|
92
|
+
export interface AppConfig {
|
|
93
|
+
/** 应用基础信息(store/app 仅取 name) */
|
|
94
|
+
APP_BASE_INFO: {
|
|
95
|
+
/** 应用名称 */
|
|
96
|
+
name: string;
|
|
97
|
+
};
|
|
98
|
+
/** 应用布局-header 配置(store/app 仅取 height) */
|
|
99
|
+
APP_LAYOUT_HEADER_CONFIG: {
|
|
100
|
+
/** header 高度(px) */
|
|
101
|
+
height: number;
|
|
102
|
+
};
|
|
103
|
+
/** 应用布局-footer 配置(store/app 仅取 height) */
|
|
104
|
+
APP_LAYOUT_FOOTER_CONFIG: {
|
|
105
|
+
/** footer 高度(px) */
|
|
106
|
+
height: number;
|
|
107
|
+
};
|
|
108
|
+
/** 应用布局-sidebar 配置(store/app 取 collapseWidth / width) */
|
|
109
|
+
APP_LAYOUT_SIDEBAR_CONFIG: {
|
|
110
|
+
/** [展开的]宽度(px) */
|
|
111
|
+
width: number;
|
|
112
|
+
/** 折叠起来的宽度(px) */
|
|
113
|
+
collapseWidth: number;
|
|
114
|
+
};
|
|
115
|
+
/** 应用布局-页面主体配置(store/app 仅取 shimPadding) */
|
|
116
|
+
APP_LAYOUT_BODY_CONFIG: {
|
|
117
|
+
/** 页面主体 padding - 默认值(px) */
|
|
118
|
+
shimPadding: number;
|
|
119
|
+
};
|
|
120
|
+
/** 应用主题配置(store/app 取 dark / light,各为完整 AppThemeColor) */
|
|
121
|
+
APP_THEME_CONFIG: {
|
|
122
|
+
/** 亮色主题 */
|
|
123
|
+
light: AppThemeColor;
|
|
124
|
+
/** 暗色主题 */
|
|
125
|
+
dark: AppThemeColor;
|
|
126
|
+
};
|
|
127
|
+
/** 应用路由元信息默认配置(store/app 取 show* 四项;createUserStore 经此取 menuShow/needLogin 默认) */
|
|
128
|
+
APP_ROUTER_META_DEFAULT_CONFIG: {
|
|
129
|
+
/** 各路由[未配置情况下]默认是否展示 header */
|
|
130
|
+
showHeader: boolean;
|
|
131
|
+
/** 各路由[未配置情况下]默认是否展示 footer */
|
|
132
|
+
showFooter: boolean;
|
|
133
|
+
/** 各路由[未配置情况下]默认是否展示 sidebar */
|
|
134
|
+
showSidebar: boolean;
|
|
135
|
+
/** 默认是否展示 breadcrumb */
|
|
136
|
+
showBreadcrumb: boolean;
|
|
137
|
+
/** 各路由[未配置情况下]默认是否展示在菜单 */
|
|
138
|
+
menuShow: boolean;
|
|
139
|
+
/** 各路由[未配置情况下]默认是否需要登录 */
|
|
140
|
+
needLogin: boolean;
|
|
141
|
+
};
|
|
142
|
+
/** 应用缓存配置(#4e additive 第 8 项;createUserStore 经 namespace 实例化 useState) */
|
|
143
|
+
APP_CACHE_CONFIG: {
|
|
144
|
+
/** 缓存命名空间 */
|
|
145
|
+
namespace: string;
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* UserInfo 单字段取写访问器(v3 终锁 Δ0a)。
|
|
150
|
+
*
|
|
151
|
+
* 两档形态(解析优先级 `typeof === "string"`):
|
|
152
|
+
* - **string 点路径串**(如 `"token"` / `"auth.t"`):core 内经 `lodash/get` 读、
|
|
153
|
+
* `lodash/cloneDeep` then `lodash/set` 写(先 clone 产新对象再 set,不可变,
|
|
154
|
+
* 1:1 镜像现行 spread 语义;见 design D2-bis)。`UserInfo` 对 core 完全不透明。
|
|
155
|
+
* - **显式方法档** `{ get, set }`:app 自定取写逻辑(嵌套字段 / 自定义合并),
|
|
156
|
+
* `set` [MUST] 产新对象(app 自负不可变,core 不包装、无 lodash 介入)。
|
|
157
|
+
*
|
|
158
|
+
* permission [MUST NOT] 入本访问器——core route-permission-tree 经固定约定路径
|
|
159
|
+
* `"permission"` 读(design D-a 记账,本期维持现状)。
|
|
160
|
+
*/
|
|
161
|
+
export type UserInfoFieldAccess<UserInfo = unknown> = string | {
|
|
162
|
+
/** 从 userInfo 读取该字段字符串值(未命中返回 undefined) */
|
|
163
|
+
get: (info: UserInfo) => string | undefined;
|
|
164
|
+
/** 写入该字段并返回新 userInfo([MUST] 产新对象不 mutate 入参) */
|
|
165
|
+
set: (info: UserInfo, v: string | undefined) => UserInfo;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* UserInfo 的 token / refreshToken 双字段访问器集(v3 终锁 Δ0a)。
|
|
169
|
+
*
|
|
170
|
+
* 经 `bridge.init({ userInfoAccess })` 注入 → createUserStore 经
|
|
171
|
+
* `bridge.getUserInfoAccess()` 取,使 core 对 UserInfo token/refreshToken
|
|
172
|
+
* 字段名零硬编(用户终锁 1/6)。permission **不入此集**(design D-a)。
|
|
173
|
+
*/
|
|
174
|
+
export interface UserInfoAccess<UserInfo = unknown> {
|
|
175
|
+
/** token 字段访问器(string 点路径串 / 显式 `{get,set}`) */
|
|
176
|
+
token: UserInfoFieldAccess<UserInfo>;
|
|
177
|
+
/** refreshToken 字段访问器(string 点路径串 / 显式 `{get,set}`) */
|
|
178
|
+
refreshToken: UserInfoFieldAccess<UserInfo>;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* `init` 入参类型,全入参均必传(类型层 required,非 optional)。
|
|
182
|
+
*
|
|
183
|
+
* `appConfig` 与 `storage` 均为 env-driven、不依赖 core、app pre-Vue 即可备好;
|
|
184
|
+
* `routes`(#4e additive)为 app 嵌套路由树(带 children),createUserStore 经此算权限树;
|
|
185
|
+
* `userInfoAccess` / `getUserInfoInitFn`(v3 终锁 Δ0b)为 createUserStore token/refreshToken
|
|
186
|
+
* 取写 + 用户信息空保底注入面(core 对 UserInfo 不透明,业务 shape 不下沉,规则 8)。
|
|
187
|
+
*/
|
|
188
|
+
export interface AdminBridgeInitOptions<UserInfo = unknown> {
|
|
189
|
+
/** store/app + createUserStore 消费的 app config 子集(必传) */
|
|
190
|
+
appConfig: AppConfig;
|
|
191
|
+
/** pinia persist storage 适配器(必传) */
|
|
192
|
+
storage: StorageLike;
|
|
193
|
+
/** app 嵌套路由树(必传,#4e additive;createUserStore 权限树依赖 children 嵌套,[MUST NOT] 传扁平化数据) */
|
|
194
|
+
routes: RouteRecordRaw[];
|
|
195
|
+
/** UserInfo token/refreshToken 取写访问器(v3 终锁 Δ0b;createUserStore 经此取写,core 不透明 UserInfo,permission 不入) */
|
|
196
|
+
userInfoAccess: UserInfoAccess<UserInfo>;
|
|
197
|
+
/** 用户信息空保底工厂(v3 终锁 Δ0b;恒返非空业务字段默认值对象,createUserStore useState 经此取初值,core 不锁业务 shape) */
|
|
198
|
+
getUserInfoInitFn: () => UserInfo;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* 认证桥接实例类型。
|
|
202
|
+
*
|
|
203
|
+
* 调用侧 4 auth 方法签名与原 app `@/config` facade 完全一致;新增
|
|
204
|
+
* `init` 启动期一次性注入 + `getAppConfig` / `getStorage` / `getRoutes` post-init 取注册引用。
|
|
205
|
+
*/
|
|
206
|
+
export interface AdminBridge<UserInfo = unknown, LoginParams = unknown> {
|
|
207
|
+
/**
|
|
208
|
+
* 启动期一次性注入 appConfig / storage / routes / userInfoAccess / getUserInfoInitFn
|
|
209
|
+
* (重复调用运行时幂等覆盖,[MUST NOT] throw/warn;v3 终锁 Δ0c:类型层返回
|
|
210
|
+
* `Omit<AdminBridge,"init">` 防重复 init 误用 + 支持链式,语句式 `bridge.init({...})`
|
|
211
|
+
* 调用继续合法不强制消费返回值)。
|
|
212
|
+
*/
|
|
213
|
+
init: (options: AdminBridgeInitOptions<UserInfo>) => Omit<AdminBridge<UserInfo, LoginParams>, "init">;
|
|
214
|
+
/** 注册 auth fn + 业务 api(增量合并,多次调用就近增量,后注册覆盖前注册) */
|
|
215
|
+
register: (options: AdminBridgeRegisterOptions<UserInfo, LoginParams>) => void;
|
|
216
|
+
/** 取 token(v3 终锁 BR-1 ③ 终裁零参;现有无参调用 `bridge.getToken()` 继续合法,泛型 `<UserInfo>` 纯透传不沾本签名) */
|
|
217
|
+
getToken: () => string | undefined;
|
|
218
|
+
/** 跳转登录 */
|
|
219
|
+
goToLogin: () => void;
|
|
220
|
+
/** 刷新 token */
|
|
221
|
+
refreshToken: () => Promise<void>;
|
|
222
|
+
/** 刷新鉴权 */
|
|
223
|
+
refreshAuth: () => Promise<void>;
|
|
224
|
+
/** post-init 返回 `init` 注册的 appConfig 引用;pre-init 同步 throw */
|
|
225
|
+
getAppConfig: () => AppConfig;
|
|
226
|
+
/** post-init 返回 `init` 注册的 storage 引用;pre-init 同步 throw */
|
|
227
|
+
getStorage: () => StorageLike;
|
|
228
|
+
/** post-init 返回 `init` 注册的 routes 引用;pre-init 同步 throw */
|
|
229
|
+
getRoutes: () => RouteRecordRaw[];
|
|
230
|
+
/** post-init 返回 `init` 注册的 userInfoAccess 引用;pre-init 同步 throw(v3 终锁 Δ0d,镜像 getRoutes 范式) */
|
|
231
|
+
getUserInfoAccess: () => UserInfoAccess<UserInfo>;
|
|
232
|
+
/** post-init 返回 `init` 注册的 getUserInfoInitFn 引用;pre-init 同步 throw(v3 终锁 Δ0d,镜像 getRoutes 范式) */
|
|
233
|
+
getUserInfoInitFn: () => () => UserInfo;
|
|
234
|
+
/** 登录 api(createUserStore login 内调;未注册被调同步 throw 原生 Error 前 reject——异步对 reject 原生 Error) */
|
|
235
|
+
loginApi: (params: LoginParams) => Promise<{
|
|
236
|
+
data: UserInfo;
|
|
237
|
+
}>;
|
|
238
|
+
/** 退出登录 api(createUserStore logout 内调;未注册被调 reject 原生 Error) */
|
|
239
|
+
logoutApi: () => Promise<unknown>;
|
|
240
|
+
/** 取用户信息 api(createUserStore getInfo 内调;连壳 {user_info} 见 design D2;未注册被调 reject 原生 Error) */
|
|
241
|
+
getUserInfoApi: () => Promise<{
|
|
242
|
+
data: UserInfo;
|
|
243
|
+
}>;
|
|
244
|
+
/** 刷新 token api(createUserStore refreshTokenFn 内调;未注册被调 reject 原生 Error) */
|
|
245
|
+
refreshTokenApi: (headers: {
|
|
246
|
+
Authorization: string;
|
|
247
|
+
}) => Promise<{
|
|
248
|
+
data: {
|
|
249
|
+
token: string;
|
|
250
|
+
};
|
|
251
|
+
}>;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* 认证桥接无状态纯工厂:每次调用返回一个独立的 `AdminBridge` 实例,
|
|
255
|
+
* 实例状态(appConfig / storage / routes / fn 引用 + initialized 闸)仅存在于
|
|
256
|
+
* 本次调用的闭包内,工厂自身零状态。
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* const appAdminBridge = createAdminBridge<LoginAccountInfo, AccountLoginParams>();
|
|
260
|
+
*/
|
|
261
|
+
export declare function createAdminBridge<UserInfo = unknown, LoginParams = unknown>(): AdminBridge<UserInfo, LoginParams>;
|
|
@@ -4,14 +4,18 @@ export interface ActivatedInfo {
|
|
|
4
4
|
triggerType: "mounted" | "activated" | "deactivated" | "unmounted";
|
|
5
5
|
}
|
|
6
6
|
/** 是否激活 */
|
|
7
|
-
export declare const useActivated: () => {
|
|
7
|
+
export declare const useActivated: (watchFn?: (info: ActivatedInfo) => void) => {
|
|
8
8
|
isActivated: globalThis.ComputedRef<boolean>;
|
|
9
9
|
activatedInfo: globalThis.ComputedRef<{
|
|
10
|
-
isActivated: boolean;
|
|
11
|
-
triggerType: "mounted" | "activated" | "deactivated" | "unmounted";
|
|
10
|
+
readonly isActivated: boolean;
|
|
11
|
+
readonly triggerType: "mounted" | "activated" | "deactivated" | "unmounted";
|
|
12
12
|
}>;
|
|
13
13
|
};
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated 请使用 useActivated 替代
|
|
16
|
+
* 激活时执行时间 */
|
|
15
17
|
export declare const useActivatedExec: (callback: (info: ActivatedInfo) => void) => void;
|
|
16
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* @deprecated 请使用 useActivated 替代
|
|
20
|
+
* 激活时监听事件 */
|
|
17
21
|
export declare const useActivatedEvent: (bind: (info: ActivatedInfo) => void, unbind: (info: ActivatedInfo) => void) => void;
|
package/types/index.d.ts
CHANGED
|
@@ -20,5 +20,7 @@ export * from './types';
|
|
|
20
20
|
export * from './config';
|
|
21
21
|
export * from './inject';
|
|
22
22
|
export * from './helpers';
|
|
23
|
+
export * from './bridge';
|
|
24
|
+
export * from './store';
|
|
23
25
|
export { formInstall, menuInstall, displayInstall, miscInstall, modalInstall, tableInstall, listPageInstall, };
|
|
24
26
|
export declare const installComponents: Plugin;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './user';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ComputedRef } from 'vue';
|
|
2
|
+
import { AdminBridge } from '../bridge';
|
|
3
|
+
import { RoutePermission } from '../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* createUserStore 工厂依赖(v3 终锁 Δ1:deps 收敛单字段 `{ bridge }`)。
|
|
7
|
+
*
|
|
8
|
+
* 业务类型 shape 经泛型 `<UserInfo, LoginParams>` 注入(core 不锁 shape,规则 8);
|
|
9
|
+
* 运行时配置 + 注入面全部经 `bridge`——`getAppConfig` / `getRoutes` / 4 业务 api /
|
|
10
|
+
* `getUserInfoInitFn()`(用户信息空保底工厂,替代 0fd94cc `userInfoInit` deps 字段)/
|
|
11
|
+
* `getUserInfoAccess()`(token/refreshToken 取写访问器,core 对 UserInfo 不透明)。
|
|
12
|
+
* permission 不入访问器——core route-permission-tree 经固定约定路径 `"permission"`
|
|
13
|
+
* 读(用户终锁 4,design D-a 记账)。
|
|
14
|
+
*/
|
|
15
|
+
export interface CreateUserStoreDeps<UserInfo, LoginParams = unknown> {
|
|
16
|
+
/** app 侧 admin bridge 单例(注入而非 core 持单例,守规则 8;userInfoInit/userInfoAccess 经 bridge.init 注入,本工厂经 bridge.getUserInfoInitFn()/getUserInfoAccess() 读) */
|
|
17
|
+
bridge: AdminBridge<UserInfo, LoginParams>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 用户 store 泛型工厂下沉 core。
|
|
21
|
+
*
|
|
22
|
+
* 返回 `defineStore("USER", setup)` 结果(store id 保持 `"USER"`;core 工厂
|
|
23
|
+
* 无状态,store 实例由 app 侧 pinia 管理,规则 8)。setup 内 1:1 镜像原
|
|
24
|
+
* `packages/app/src/store/user.ts` 全部运行时行为(actions / computed / watch /
|
|
25
|
+
* return / 路由权限计算),[MUST NOT] 重构 / 精简 / 调整顺序。
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* export const useUserStore = createUserStore<LoginAccountInfo, AccountLoginParams>({
|
|
29
|
+
* bridge: appAdminBridge,
|
|
30
|
+
* });
|
|
31
|
+
*/
|
|
32
|
+
export declare function createUserStore<UserInfo, LoginParams = unknown>(deps: CreateUserStoreDeps<UserInfo, LoginParams>): import('pinia').StoreDefinition<"USER", Pick<{
|
|
33
|
+
userInfo: ComputedRef<UserInfo>;
|
|
34
|
+
token: ComputedRef<string | undefined>;
|
|
35
|
+
isLogin: ComputedRef<boolean>;
|
|
36
|
+
login: (params: LoginParams) => Promise<void>;
|
|
37
|
+
logout: () => Promise<void>;
|
|
38
|
+
noApiLogout: () => void;
|
|
39
|
+
getInfo: () => Promise<UserInfo>;
|
|
40
|
+
havePermissionByPath: (path: string) => boolean;
|
|
41
|
+
havePermissionByKey: (key?: RoutePermission["key"]) => boolean;
|
|
42
|
+
}, never>, Pick<{
|
|
43
|
+
userInfo: ComputedRef<UserInfo>;
|
|
44
|
+
token: ComputedRef<string | undefined>;
|
|
45
|
+
isLogin: ComputedRef<boolean>;
|
|
46
|
+
login: (params: LoginParams) => Promise<void>;
|
|
47
|
+
logout: () => Promise<void>;
|
|
48
|
+
noApiLogout: () => void;
|
|
49
|
+
getInfo: () => Promise<UserInfo>;
|
|
50
|
+
havePermissionByPath: (path: string) => boolean;
|
|
51
|
+
havePermissionByKey: (key?: RoutePermission["key"]) => boolean;
|
|
52
|
+
}, "userInfo" | "token" | "isLogin">, Pick<{
|
|
53
|
+
userInfo: ComputedRef<UserInfo>;
|
|
54
|
+
token: ComputedRef<string | undefined>;
|
|
55
|
+
isLogin: ComputedRef<boolean>;
|
|
56
|
+
login: (params: LoginParams) => Promise<void>;
|
|
57
|
+
logout: () => Promise<void>;
|
|
58
|
+
noApiLogout: () => void;
|
|
59
|
+
getInfo: () => Promise<UserInfo>;
|
|
60
|
+
havePermissionByPath: (path: string) => boolean;
|
|
61
|
+
havePermissionByKey: (key?: RoutePermission["key"]) => boolean;
|
|
62
|
+
}, "login" | "logout" | "noApiLogout" | "getInfo" | "havePermissionByPath" | "havePermissionByKey">>;
|