@deppon/create-deppon-app 2.2.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/LICENSE +1 -0
- package/README.md +63 -0
- package/deppon.js +640 -0
- package/package.json +51 -0
- package/template/.env +12 -0
- package/template/.env.dev-local.example +64 -0
- package/template/.env.development.example +64 -0
- package/template/.env.example +1 -0
- package/template/.env.production.example +64 -0
- package/template/.env.test.example +64 -0
- package/template/.eslintignore +2 -0
- package/template/.eslintrc.cjs +14 -0
- package/template/.prettierrc.js +3 -0
- package/template/.vscode/settings.json +8 -0
- package/template/Dockerfile +5 -0
- package/template/README.md +149 -0
- package/template/commitlint.config.js +11 -0
- package/template/gitignore +8 -0
- package/template/index.html +18 -0
- package/template/nginx.conf +70 -0
- package/template/npmrc +2 -0
- package/template/package.json +49 -0
- package/template/preview-server.js +117 -0
- package/template/public/favicon.ico +0 -0
- package/template/public/logo.png +0 -0
- package/template/src/App.vue +123 -0
- package/template/src/api/index.ts +13 -0
- package/template/src/api/prefercenter.ts +23 -0
- package/template/src/api/product.ts +16 -0
- package/template/src/api/user.ts +41 -0
- package/template/src/components/ExpandableMessage.vue +340 -0
- package/template/src/components/PageLayout.vue +43 -0
- package/template/src/config/dictionaryConfig.ts +24 -0
- package/template/src/directives/permission.ts +162 -0
- package/template/src/layouts/BaseLayout.vue +687 -0
- package/template/src/main.ts +27 -0
- package/template/src/router/index.ts +179 -0
- package/template/src/router/route.ts +61 -0
- package/template/src/stores/menu.ts +334 -0
- package/template/src/stores/product.ts +155 -0
- package/template/src/stores/route.ts +79 -0
- package/template/src/stores/user.ts +145 -0
- package/template/src/styles/index.ts +29 -0
- package/template/src/types/dictionary.d.ts +24 -0
- package/template/src/types/vite-env.d.ts +119 -0
- package/template/src/utils/dictionary.ts +188 -0
- package/template/src/utils/errorAnalyzer.ts +217 -0
- package/template/src/utils/messageVNode.ts +15 -0
- package/template/src/utils/request.ts +293 -0
- package/template/src/views/error/401.vue +30 -0
- package/template/src/views/error/403.vue +30 -0
- package/template/src/views/error/404.vue +30 -0
- package/template/src/views/home/index.vue +25 -0
- package/template/tsconfig.json +27 -0
- package/template/vite.config.ts +243 -0
- package/template/yarnrc +3 -0
- package/template/yarnrc.yml +7 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { defineStore } from '@deppon/deppon-pinia';
|
|
2
|
+
import { queryProductInfo } from '@/api/product';
|
|
3
|
+
|
|
4
|
+
export interface ProductInfo {
|
|
5
|
+
code: string;
|
|
6
|
+
disable: boolean;
|
|
7
|
+
name: string;
|
|
8
|
+
productType: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ProductInfoResponse {
|
|
12
|
+
PREFER_PRODUCT_INFO: ProductInfo[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ProductState {
|
|
16
|
+
productInfoList: ProductInfo[];
|
|
17
|
+
loading: boolean;
|
|
18
|
+
error: string | null;
|
|
19
|
+
fetchPromise: Promise<void> | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const PRODUCT_INFO_STORAGE_KEY = 'deppon-product-info';
|
|
23
|
+
const PRODUCT_INFO_TIMESTAMP_KEY = 'deppon-product-info-timestamp';
|
|
24
|
+
|
|
25
|
+
const readProductInfoFromCache = (): ProductInfo[] => {
|
|
26
|
+
if (typeof window === 'undefined') {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const cached = window.localStorage.getItem(PRODUCT_INFO_STORAGE_KEY);
|
|
30
|
+
if (!cached) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const parsed = JSON.parse(cached) as ProductInfoResponse;
|
|
35
|
+
return parsed.PREFER_PRODUCT_INFO || [];
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.warn('[product-store] 无法解析缓存的产品信息', error);
|
|
38
|
+
window.localStorage.removeItem(PRODUCT_INFO_STORAGE_KEY);
|
|
39
|
+
window.localStorage.removeItem(PRODUCT_INFO_TIMESTAMP_KEY);
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const persistProductInfo = (data: ProductInfoResponse | null) => {
|
|
45
|
+
if (typeof window === 'undefined') {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (data && data.PREFER_PRODUCT_INFO) {
|
|
49
|
+
window.localStorage.setItem(PRODUCT_INFO_STORAGE_KEY, JSON.stringify(data));
|
|
50
|
+
window.localStorage.setItem(PRODUCT_INFO_TIMESTAMP_KEY, Date.now().toString());
|
|
51
|
+
} else {
|
|
52
|
+
window.localStorage.removeItem(PRODUCT_INFO_STORAGE_KEY);
|
|
53
|
+
window.localStorage.removeItem(PRODUCT_INFO_TIMESTAMP_KEY);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const isCacheValid = (): boolean => {
|
|
58
|
+
if (typeof window === 'undefined') {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
const timestamp = window.localStorage.getItem(PRODUCT_INFO_TIMESTAMP_KEY);
|
|
62
|
+
if (!timestamp) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
const oneDayInMs = 24 * 60 * 60 * 1000; // 24小时的毫秒数
|
|
66
|
+
const now = Date.now();
|
|
67
|
+
return (now - parseInt(timestamp, 10)) < oneDayInMs;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const useProductStore = defineStore('product', {
|
|
71
|
+
state: (): ProductState => ({
|
|
72
|
+
productInfoList: readProductInfoFromCache(),
|
|
73
|
+
loading: false,
|
|
74
|
+
error: null,
|
|
75
|
+
fetchPromise: null,
|
|
76
|
+
}),
|
|
77
|
+
getters: {
|
|
78
|
+
// 获取所有启用的产品信息
|
|
79
|
+
enabledProductList: (state) => state.productInfoList.filter(item => !item.disable),
|
|
80
|
+
// 根据产品类型筛选
|
|
81
|
+
getProductsByType: (state) => (productType: string) => {
|
|
82
|
+
return state.productInfoList.filter(item => item.productType === productType && !item.disable);
|
|
83
|
+
},
|
|
84
|
+
// 根据 code 查找产品
|
|
85
|
+
getProductByCode: (state) => (code: string) => {
|
|
86
|
+
return state.productInfoList.find(item => item.code === code);
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
actions: {
|
|
90
|
+
async fetchProductInfo() {
|
|
91
|
+
// 如果正在加载,等待正在进行的请求完成
|
|
92
|
+
if (this.loading && this.fetchPromise) {
|
|
93
|
+
await this.fetchPromise;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 先检查localStorage缓存是否有效
|
|
98
|
+
const cacheValid = isCacheValid();
|
|
99
|
+
|
|
100
|
+
// 如果内存中没有数据,尝试从localStorage加载
|
|
101
|
+
if (this.productInfoList.length === 0) {
|
|
102
|
+
const cachedData = readProductInfoFromCache();
|
|
103
|
+
if (cachedData.length > 0) {
|
|
104
|
+
this.productInfoList = cachedData;
|
|
105
|
+
// 如果缓存有效,不发起请求
|
|
106
|
+
if (cacheValid) {
|
|
107
|
+
console.log('[product-store] 从缓存加载产品信息,跳过请求');
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
// 如果内存中有数据,检查缓存是否有效
|
|
113
|
+
if (cacheValid) {
|
|
114
|
+
console.log('[product-store] 使用缓存的产品信息,跳过请求');
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
this.loading = true;
|
|
120
|
+
this.error = null;
|
|
121
|
+
|
|
122
|
+
// 创建 Promise 并保存,以便其他调用可以等待
|
|
123
|
+
this.fetchPromise = (async () => {
|
|
124
|
+
try {
|
|
125
|
+
const response = await queryProductInfo('PRODUCT_INFO_TIERED');
|
|
126
|
+
if (response && response.data) {
|
|
127
|
+
const productData = response.data as ProductInfoResponse;
|
|
128
|
+
this.productInfoList = productData.PREFER_PRODUCT_INFO || [];
|
|
129
|
+
persistProductInfo(productData);
|
|
130
|
+
}
|
|
131
|
+
} catch (error: any) {
|
|
132
|
+
console.error('[product-store] 获取产品信息失败', error);
|
|
133
|
+
this.error = error?.message || '获取产品信息失败';
|
|
134
|
+
// 如果请求失败,使用缓存的数据
|
|
135
|
+
if (this.productInfoList.length === 0) {
|
|
136
|
+
this.productInfoList = readProductInfoFromCache();
|
|
137
|
+
}
|
|
138
|
+
} finally {
|
|
139
|
+
this.loading = false;
|
|
140
|
+
this.fetchPromise = null;
|
|
141
|
+
}
|
|
142
|
+
})();
|
|
143
|
+
|
|
144
|
+
await this.fetchPromise;
|
|
145
|
+
},
|
|
146
|
+
clearProductInfo() {
|
|
147
|
+
this.productInfoList = [];
|
|
148
|
+
this.error = null;
|
|
149
|
+
if (typeof window !== 'undefined') {
|
|
150
|
+
window.localStorage.removeItem(PRODUCT_INFO_STORAGE_KEY);
|
|
151
|
+
window.localStorage.removeItem(PRODUCT_INFO_TIMESTAMP_KEY);
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { defineStore } from '@deppon/deppon-pinia';
|
|
2
|
+
import type { MenuNode } from '@deppon/deppon-auth';
|
|
3
|
+
|
|
4
|
+
export interface RouteState {
|
|
5
|
+
menuTree: MenuNode[];
|
|
6
|
+
routesLoaded: boolean;
|
|
7
|
+
loading: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const MENU_TREE_STORAGE_KEY = 'deppon-menu-tree';
|
|
11
|
+
|
|
12
|
+
const readMenuTreeFromCache = (): MenuNode[] => {
|
|
13
|
+
if (typeof window === 'undefined') {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const cached = window.localStorage.getItem(MENU_TREE_STORAGE_KEY);
|
|
17
|
+
if (!cached) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(cached) as MenuNode[];
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.warn('[route-store] 无法解析缓存的菜单树', error);
|
|
24
|
+
window.localStorage.removeItem(MENU_TREE_STORAGE_KEY);
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const persistMenuTree = (menuTree: MenuNode[]) => {
|
|
30
|
+
if (typeof window === 'undefined') {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (menuTree && menuTree.length > 0) {
|
|
34
|
+
window.localStorage.setItem(MENU_TREE_STORAGE_KEY, JSON.stringify(menuTree));
|
|
35
|
+
} else {
|
|
36
|
+
window.localStorage.removeItem(MENU_TREE_STORAGE_KEY);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const useRouteStore = defineStore('route', {
|
|
41
|
+
state: (): RouteState => ({
|
|
42
|
+
menuTree: readMenuTreeFromCache(),
|
|
43
|
+
routesLoaded: false,
|
|
44
|
+
loading: false,
|
|
45
|
+
}),
|
|
46
|
+
getters: {
|
|
47
|
+
hasMenuTree: state => state.menuTree.length > 0,
|
|
48
|
+
isRoutesLoaded: state => state.routesLoaded,
|
|
49
|
+
},
|
|
50
|
+
actions: {
|
|
51
|
+
/**
|
|
52
|
+
* 设置菜单树
|
|
53
|
+
*/
|
|
54
|
+
setMenuTree(menuTree: MenuNode[]) {
|
|
55
|
+
this.menuTree = menuTree;
|
|
56
|
+
persistMenuTree(menuTree);
|
|
57
|
+
},
|
|
58
|
+
/**
|
|
59
|
+
* 标记路由已加载
|
|
60
|
+
*/
|
|
61
|
+
setRoutesLoaded(loaded: boolean) {
|
|
62
|
+
this.routesLoaded = loaded;
|
|
63
|
+
},
|
|
64
|
+
/**
|
|
65
|
+
* 设置加载状态
|
|
66
|
+
*/
|
|
67
|
+
setLoading(loading: boolean) {
|
|
68
|
+
this.loading = loading;
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* 清空菜单树
|
|
72
|
+
*/
|
|
73
|
+
clearMenuTree() {
|
|
74
|
+
this.menuTree = [];
|
|
75
|
+
this.routesLoaded = false;
|
|
76
|
+
persistMenuTree([]);
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { defineStore } from '@deppon/deppon-pinia';
|
|
2
|
+
import { findUserByCode } from '@/api/user';
|
|
3
|
+
|
|
4
|
+
export interface UserProfile {
|
|
5
|
+
userName?: string;
|
|
6
|
+
userCode?: string;
|
|
7
|
+
deptCode?: string;
|
|
8
|
+
deptName?: string;
|
|
9
|
+
/** 人群/角色编码 如 UAP_ROLE_BUSINESS_DEPT */
|
|
10
|
+
crowdCode?: string;
|
|
11
|
+
/** 人群/角色名称 如 营业部 */
|
|
12
|
+
crowdName?: string;
|
|
13
|
+
/** 同步时间 */
|
|
14
|
+
currentTime?: string;
|
|
15
|
+
/** 标准部门编码 */
|
|
16
|
+
deptStandCode?: string;
|
|
17
|
+
/** 标准部门名称 */
|
|
18
|
+
deptStandName?: string;
|
|
19
|
+
/** 岗位编码 */
|
|
20
|
+
jobCode?: string;
|
|
21
|
+
/** 岗位名称 */
|
|
22
|
+
position?: string;
|
|
23
|
+
/** 性别 1男 2女 */
|
|
24
|
+
gender?: number;
|
|
25
|
+
/** 状态 */
|
|
26
|
+
status?: number;
|
|
27
|
+
id?: number;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface AuthState {
|
|
32
|
+
profile: UserProfile | null;
|
|
33
|
+
token: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface AuthPayload {
|
|
37
|
+
profile: UserProfile | null;
|
|
38
|
+
token: string | null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const PROFILE_STORAGE_KEY = 'deppon-user-profile';
|
|
42
|
+
const TOKEN_STORAGE_KEY = 'deppon-auth-token';
|
|
43
|
+
|
|
44
|
+
const readProfileFromCache = (): UserProfile | null => {
|
|
45
|
+
if (typeof window === 'undefined') {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const cached = window.localStorage.getItem(PROFILE_STORAGE_KEY);
|
|
49
|
+
if (!cached) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
return JSON.parse(cached) as UserProfile;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.warn('[deppon-auth] 无法解析缓存的用户信息', error);
|
|
56
|
+
window.localStorage.removeItem(PROFILE_STORAGE_KEY);
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const readTokenFromCache = (): string => {
|
|
62
|
+
if (typeof window === 'undefined') {
|
|
63
|
+
return '';
|
|
64
|
+
}
|
|
65
|
+
return window.localStorage.getItem(TOKEN_STORAGE_KEY) ?? '';
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const persistProfile = (profile: UserProfile | null) => {
|
|
69
|
+
if (typeof window === 'undefined') {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (profile) {
|
|
73
|
+
window.localStorage.setItem(PROFILE_STORAGE_KEY, JSON.stringify(profile));
|
|
74
|
+
} else {
|
|
75
|
+
window.localStorage.removeItem(PROFILE_STORAGE_KEY);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const persistToken = (token: string | null) => {
|
|
80
|
+
if (typeof window === 'undefined') {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (token) {
|
|
84
|
+
window.localStorage.setItem(TOKEN_STORAGE_KEY, token);
|
|
85
|
+
} else {
|
|
86
|
+
window.localStorage.removeItem(TOKEN_STORAGE_KEY);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const useUserStore = defineStore('user', {
|
|
91
|
+
state: (): AuthState => ({
|
|
92
|
+
profile: readProfileFromCache(),
|
|
93
|
+
token: readTokenFromCache(),
|
|
94
|
+
}),
|
|
95
|
+
getters: {
|
|
96
|
+
displayName: state =>
|
|
97
|
+
[state.profile?.userName, state.profile?.deptName].filter(Boolean).join('-') || '未登录',
|
|
98
|
+
isLoggedIn: state => Boolean(state.token),
|
|
99
|
+
},
|
|
100
|
+
actions: {
|
|
101
|
+
setAuth(payload: AuthPayload) {
|
|
102
|
+
this.profile = payload.profile;
|
|
103
|
+
this.token = payload.token ?? '';
|
|
104
|
+
persistProfile(payload.profile);
|
|
105
|
+
persistToken(payload.token);
|
|
106
|
+
},
|
|
107
|
+
clearAuth() {
|
|
108
|
+
this.setAuth({ profile: null, token: null });
|
|
109
|
+
},
|
|
110
|
+
/**
|
|
111
|
+
* 根据当前 profile.userCode(empCode)请求 UAP 用户信息并更新 profile
|
|
112
|
+
*/
|
|
113
|
+
async fetchUserInfoByCode() {
|
|
114
|
+
const empCode = this.profile?.userCode;
|
|
115
|
+
if (!empCode) return;
|
|
116
|
+
try {
|
|
117
|
+
const res = await findUserByCode(empCode);
|
|
118
|
+
if (res?.status === 'SUCCESS' && res?.body) {
|
|
119
|
+
const body = res.body;
|
|
120
|
+
const prev = this.profile ?? {};
|
|
121
|
+
this.profile = {
|
|
122
|
+
...prev,
|
|
123
|
+
userCode: body.empCode ?? prev.userCode,
|
|
124
|
+
userName: body.empName ?? prev.userName,
|
|
125
|
+
deptCode: body.deptCode ?? prev.deptCode,
|
|
126
|
+
deptName: body.deptName ?? prev.deptName,
|
|
127
|
+
crowdCode: body.crowdCode ?? prev.crowdCode,
|
|
128
|
+
crowdName: body.crowdName ?? prev.crowdName,
|
|
129
|
+
currentTime: body.currentTime ?? prev.currentTime,
|
|
130
|
+
deptStandCode: body.deptStandCode ?? prev.deptStandCode,
|
|
131
|
+
deptStandName: body.deptStandName ?? prev.deptStandName,
|
|
132
|
+
jobCode: body.jobCode ?? prev.jobCode,
|
|
133
|
+
position: body.position ?? prev.position,
|
|
134
|
+
gender: body.gender ?? prev.gender,
|
|
135
|
+
status: body.status ?? prev.status,
|
|
136
|
+
id: body.id ?? prev.id,
|
|
137
|
+
} as UserProfile;
|
|
138
|
+
persistProfile(this.profile);
|
|
139
|
+
}
|
|
140
|
+
} catch (e) {
|
|
141
|
+
console.warn('[user] findUserByCode 失败', e);
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// ==================== 样式统一导入 ====================
|
|
2
|
+
// 此文件用于统一导入所有组件样式,确保构建时样式被正确打包
|
|
3
|
+
|
|
4
|
+
// Element Plus 样式(deppon-ui 基于 element-plus,需要先导入)
|
|
5
|
+
import 'element-plus/dist/index.css';
|
|
6
|
+
|
|
7
|
+
// deppon-template 全局样式
|
|
8
|
+
import '@deppon/deppon-template/es/styles/index.less';
|
|
9
|
+
|
|
10
|
+
// deppon-template 组件样式(按需导入)
|
|
11
|
+
// ProLayout 样式
|
|
12
|
+
import '@deppon/deppon-template/es/pro-layout/ProLayout.vue.less';
|
|
13
|
+
|
|
14
|
+
// ProTable 样式(包含子组件样式)
|
|
15
|
+
import '@deppon/deppon-template/es/pro-table/ProTable.vue.less';
|
|
16
|
+
import '@deppon/deppon-template/es/pro-table/ProTableColumn.vue.less';
|
|
17
|
+
import '@deppon/deppon-template/es/pro-table/ProTableActionSlotWrapper.vue.less';
|
|
18
|
+
|
|
19
|
+
// ProForm 样式
|
|
20
|
+
import '@deppon/deppon-template/es/pro-form/ProForm.vue.less';
|
|
21
|
+
|
|
22
|
+
// ProDialog 样式
|
|
23
|
+
import '@deppon/deppon-template/es/pro-dialog/ProDialog.vue.less';
|
|
24
|
+
|
|
25
|
+
// ProField 样式(包含子组件样式)
|
|
26
|
+
import '@deppon/deppon-template/es/pro-field/ProField.vue.less';
|
|
27
|
+
import '@deppon/deppon-template/es/pro-field/components/Select/FieldSelect.vue.less';
|
|
28
|
+
import '@deppon/deppon-template/es/pro-field/components/Text/FieldText.vue.less';
|
|
29
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 字典相关类型定义
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 字典项接口
|
|
7
|
+
*/
|
|
8
|
+
export interface DictionaryItem {
|
|
9
|
+
/** 字典编码/值 */
|
|
10
|
+
code: string;
|
|
11
|
+
/** 字典名称/标签 */
|
|
12
|
+
label: string;
|
|
13
|
+
/** 是否禁用 */
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
/** 排序 */
|
|
16
|
+
sort?: number;
|
|
17
|
+
/** 其他扩展字段 */
|
|
18
|
+
[key: string]: any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 字典配置类型
|
|
23
|
+
*/
|
|
24
|
+
export type DictionaryConfig = Record<string, DictionaryItem[]>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
|
+
|
|
3
|
+
declare module '*.vue' {
|
|
4
|
+
import type { DefineComponent } from 'vue';
|
|
5
|
+
const component: DefineComponent<Record<string, any>, Record<string, any>, any>;
|
|
6
|
+
export default component;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare module '*.json' {
|
|
10
|
+
const value: { version: string; name: string };
|
|
11
|
+
export default value;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare module '*.png' {
|
|
15
|
+
const src: string;
|
|
16
|
+
export default src;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare module '*.jpg' {
|
|
20
|
+
const src: string;
|
|
21
|
+
export default src;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare module '*.jpeg' {
|
|
25
|
+
const src: string;
|
|
26
|
+
export default src;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare module '*.gif' {
|
|
30
|
+
const src: string;
|
|
31
|
+
export default src;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare module '*.svg' {
|
|
35
|
+
const src: string;
|
|
36
|
+
export default src;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface ImportMetaEnv {
|
|
40
|
+
readonly BASE_API?: string;
|
|
41
|
+
readonly VITE_BASE_API?: string;
|
|
42
|
+
readonly VITE_LOGIN_URL?: string;
|
|
43
|
+
readonly VITE_PORT?: string;
|
|
44
|
+
readonly VITE_HOST?: string;
|
|
45
|
+
readonly VITE_ALLOWED_HOSTS?: string;
|
|
46
|
+
readonly DP_PORT?: string;
|
|
47
|
+
readonly DP_HOST?: string;
|
|
48
|
+
readonly DP_ALLOWED_HOSTS?: string;
|
|
49
|
+
readonly DP_PUBLIC_PATH?: string;
|
|
50
|
+
readonly DP_ENABLE_LOGIN_CHECK?: string;
|
|
51
|
+
readonly DP_LOGIN_URL?: string;
|
|
52
|
+
readonly DP_API_URL?: string;
|
|
53
|
+
readonly DP_USE_LAYOUT?: string; // 是否使用 Layout 容器,默认 true(测试环境),false 表示 iframe 模式(生产环境)
|
|
54
|
+
readonly DP_USE_LOCAL_ROUTES?: string; // 是否使用本地路由(开发环境),默认 false
|
|
55
|
+
|
|
56
|
+
// 多系统 API 地址配置
|
|
57
|
+
readonly DP_API_HOST?: string; // 主业务 API 地址
|
|
58
|
+
readonly DP_UAP_API_HOST?: string; // UAP API 地址
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface ImportMeta {
|
|
62
|
+
readonly env: ImportMetaEnv;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
declare module 'nprogress' {
|
|
66
|
+
interface NProgress {
|
|
67
|
+
start(): void;
|
|
68
|
+
done(): void;
|
|
69
|
+
set(n: number): NProgress;
|
|
70
|
+
inc(amount?: number): NProgress;
|
|
71
|
+
remove(): void;
|
|
72
|
+
isStarted(): boolean;
|
|
73
|
+
configure(options: Partial<NProgressOptions>): NProgress;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
interface NProgressOptions {
|
|
77
|
+
minimum: number;
|
|
78
|
+
template: string;
|
|
79
|
+
easing: string;
|
|
80
|
+
speed: number;
|
|
81
|
+
trickle: boolean;
|
|
82
|
+
trickleSpeed: number;
|
|
83
|
+
showSpinner: boolean;
|
|
84
|
+
barSelector: string;
|
|
85
|
+
spinnerSelector: string;
|
|
86
|
+
parent: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const nprogress: NProgress;
|
|
90
|
+
export default nprogress;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 扩展 @deppon/deppon-ui/icons-vue 模块的类型声明
|
|
94
|
+
declare module '@deppon/deppon-ui/icons-vue' {
|
|
95
|
+
import type { Component } from 'vue';
|
|
96
|
+
export const ArrowDown: Component;
|
|
97
|
+
export const HomeFilled: Component;
|
|
98
|
+
export const Document: Component;
|
|
99
|
+
// 可以根据需要添加更多图标导出
|
|
100
|
+
// 例如:export const IconName: Component;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 扩展 @deppon/deppon-template 模块的类型声明
|
|
104
|
+
declare module '@deppon/deppon-template' {
|
|
105
|
+
import type { Component } from 'vue';
|
|
106
|
+
|
|
107
|
+
export const ProDialog: Component;
|
|
108
|
+
export const ProForm: Component;
|
|
109
|
+
export const ProTable: Component;
|
|
110
|
+
export const ProLayout: Component & {
|
|
111
|
+
__slots?: {
|
|
112
|
+
'header-right': () => any;
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
export const ProField: Component;
|
|
116
|
+
export const ProFieldText: Component;
|
|
117
|
+
export const ProFieldSelect: Component;
|
|
118
|
+
export const ProFieldDatePicker: Component;
|
|
119
|
+
}
|