yxuse 3.0.19 → 3.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,572 +1,572 @@
1
- # yxuse
2
-
3
- ## 更新日志
4
-
5
- - 2024 4-01 (Vue2.x--> 2.0.11 Vue3.x--->3.0.18)
6
-
7
- - 悬浮球新增语言切换的入口
8
- - 新增翻译的模块 translate
9
-
10
- ```js
11
- export interface YxuseOptions {
12
- ...之前的配置
13
- /** 系统标识,isRenderLang为true时必传 */
14
- systemKey?: string;
15
- }
16
- translate 模块方法说明
17
-
18
- /**
19
- * @description:初始化语言包
20
- * @param {*} lang 语言包标识
21
- * @param {*} systemKey 系统标识
22
- */
23
- initTranslate
24
- /**
25
- * @description:语言切换
26
- * @param {*} lang 语言包标识
27
- */
28
- changeLang
29
-
30
- /**
31
- * @description:获取当前语言
32
- */
33
- getLang
34
-
35
- ```
36
-
37
- - 2024 3-18 (Vue2.x--> 2.0.3 Vue3.x--->3.0.10)
38
-
39
- - theme
40
-
41
- - 主题初始化 install 方法新增配置,主要有当前开发的环境,在开发环境下无 token 会进行弹窗提示,进行自动登录,生产环境登录失效自动跳转至 loginUrl 地址(已内置)
42
-
43
- ```js
44
- export interface YxuseOptions {
45
- /** 是否渲染悬浮球*/
46
- isRenderToolbar?: boolean;
47
- /** 是否加载工单*/
48
- isRenderIssue?: boolean;
49
- /** 是否加载语言切换*/
50
- isRenderLang?: boolean;
51
- /** 登录页地址,非运管系统项目使用*/
52
- loginUrl?: string;
53
- /** 自定义登录api,非运管系统项目使用*/
54
- loginApiUrl?: string;
55
- /** 翻译Api地址,非运管系统项目使用*/
56
- translateApiUrl?: string;
57
- /** 主题列表接口,非运管系统项目使用*/
58
- themeApiUrl: string;
59
- /** 首页地址,非运管系统项目使用*/
60
- homeUrl?: string;
61
- /** 系统默认语言*/
62
- lang?: string;
63
- /** 当前环境*/
64
- environment: "development" | "production";
65
- }
66
- ```
67
-
68
- - 新增判断当前色值是否在当前主题中的方法 findColorByTheme(key: string, color: string)
69
-
70
- - auth
71
-
72
- - 新增获取系统配置的方法 getSystemConfig(key: string)
73
-
74
- - utils
75
- - 新增判断该色值是否是深色的方法 isDarkColor(color: string)
76
-
77
- ## 起步
78
-
79
- ```javascript
80
- 低版本适配为1.0.100
81
- //npm
82
- npm install yxuse@latest
83
- //pnpm
84
- pnpm install yxuse@latest
85
-
86
- //最新淘宝镜像地址为 https://registry.npmmirror.com
87
-
88
- //速度慢或者版本更新不及时 请使用npm源镜像下载
89
- // npm set registry https://registry.npmjs.org
90
- // //或
91
- // pnpm set registry https://registry.npmjs.org
92
-
93
- npm publish
94
- ```
95
-
96
- ## 权限相关
97
-
98
- ```javascript
99
- import { auth } from "yxuse/api";
100
- ```
101
-
102
- - 数据权限
103
-
104
- - 在综合管理-用户管理中操作栏编辑数据权限,给对应账户添加对应的星和站即可。管理员账户无需配置,默认有所有的星和站
105
-
106
- - 系统权限
107
-
108
- - 系统权限
109
-
110
- - 此层级的权限决定在运管系统入口处是否显示。目前有综合管理(integrated-management)、轨道控制系统(orbit)、任务计划(traceplan)、遥控分系统(telecommand)、遥测分系统(telemetry)、站控分系统(station-control)。
111
- - 配置步骤:
112
- 1. 在综合管理系统-权限配置模块新增分系统
113
- 2. 在综合管理-用户管理中操作栏(系统权限)给对应用户分配系统权限
114
-
115
- - 分系统菜单权限
116
-
117
- - 此层级的权限决定在各分系统的菜单栏是否显示。
118
- - 配置步骤:
119
- 1. 在综合管理系统-权限配置模块中各分系统下添加分系统路由
120
- 2. 表单配置说明:路由名称(左侧菜单名称),路由标识(分系统名称.前端路由名称),路由类型选择页面,前端路由(前端页面路由),接口路由(可以不填)
121
- 3. 在综合管理-用户管理中操作栏(系统权限)给对应用户分配当前系统权限
122
-
123
- - 分系统按钮权限
124
-
125
- - 此层级的权限决定在各分系统中某按钮的是否显示
126
-
127
- - 配置步骤:
128
-
129
- 1. 在综合管理系统-权限配置模块中各分系统下添加分系统路由
130
-
131
- 2. 表单配置说明:路由名称(左侧菜单名称),路由标识(前端页面路由名称.按钮含义),路由类型选择按钮类型,前端路由(前端页面路由名称.按钮含义),接口路由(可以不填)
132
-
133
- - yxuse 内置方法
134
-
135
- ```javascript
136
- /**
137
- * @description:获取token
138
- */
139
- getToken;
140
-
141
- /**
142
- * @description:移除token
143
- */
144
- removeToken;
145
-
146
- /**
147
- * 获取当前用户的权限(通用权限)
148
- * @param systemName 系统名称
149
- * @description 综合管理分系统->integrated
150
- * @description 站控分系统->station
151
- * @description 综合管理->integrated
152
- * @description 轨道分系统->orbit
153
- * @description 任务计划分系统->traceplan
154
- * @description 遥控分系统->telecommand
155
- * @description 遥测分系统->telemetry
156
- * @returns 当前分系统的用户菜单列表 userMenuList
157
- * @returns 当前分系统的用户按钮列表 userBtnList
158
- */
159
- getUserPermissions;
160
-
161
- /**
162
- *
163
- * @param userMenuList 用户路由数据
164
- * @param viewModules 页面文件
165
- * @param viewConfig 页面配置项
166
- * @returns UserRouter 用户动态路由
167
- * @description 综合管理分系统->integrated
168
- * @description 站控分系统->station
169
- * 此方法适用于Vue3+Vite项目
170
- */
171
- getUserRouter;
172
- ```
173
-
174
- - 代码参考
175
-
176
- - Vue3.0+Vite+Ts+pinia
177
-
178
- ```javascript
179
- //Vue3.0+Vite+Ts+pinia
180
- // router/index.ts
181
- router.beforeEach(async (to, from, next) => {
182
- const globalStore = GlobalStore();
183
- NProgress.start();
184
- // await getBaseConfig();
185
- //权限校验
186
- // 2.动态设置标题
187
- const title = import.meta.env.VITE_GLOB_APP_TITLE;
188
- document.title = to.meta.title ? `${to.meta.title} - ${title}` : title;
189
- // 3.判断是访问登陆页,有 Token 就在当前页面,没有 Token 重置路由并放行到登陆页
190
- const URL = [LOGIN_URL];
191
- if (URL.includes(to.path.toLocaleLowerCase())) {
192
- if (globalStore.token) return next(from.fullPath);
193
- return next();
194
- }
195
- // 4.判断访问页面是否在路由白名单地址中,如果存在直接放行
196
- if (ROUTER_WHITE_LIST.includes(to.path)) return next();
197
- // 5.判断是否有 Token,没有重定向到 login
198
-
199
- if (!globalStore.token) return next({ path: LOGIN_URL, replace: true });
200
-
201
- // 6.如果没有菜单列表,或者系统列表,就重新请求菜单列表并添加动态路由
202
- const authStore = AuthStore();
203
- authStore.setRouteName(to.name as string);
204
-
205
- if (!authStore.authMenuList.length) {
206
- //监测是当前用户是否有权限
207
- const isEmptyPower = await initDynamicRouter(to.path);
208
- if (!isEmptyPower) return next({ ...to, replace: true });
209
- }
210
- next();
211
- });
212
- //router/modules/dynamicRouter.ts
213
- export const initDynamicRouter = async path => {
214
- const authStore = AuthStore();
215
- const globalStore = GlobalStore();
216
- const configStore = ConfigStore();
217
- const baseConfig = configStore.baseConfigMapGet;
218
- if (Object.keys(baseConfig).length === 0) {
219
- await configStore.getBaseConfig();
220
- }
221
- try {
222
- // 1.获取菜单列表 && 按钮权限(可合并到一个接口获取,根据后端不同可自行改造)
223
- await authStore.getUserRouteListApi();
224
- //2.判断当前用户有没有系统权限
225
- if (!authStore.authMenuListGet.length) {
226
- //用户无权限且当前路由不在系统入口页面 默认跳转至系统入口
227
- if (path !== SYSTEM_ENTRY) {
228
- router.replace(SYSTEM_ENTRY);
229
- } else {
230
- ElNotification({
231
- title: "无权限访问",
232
- message: "当前账号无任何系统权限,请联系系统管理员!",
233
- type: "warning",
234
- duration: 3000
235
- });
236
- }
237
- return true;
238
- }
239
- // 3.添加动态路由
240
- //页面文件
241
- const modules = import.meta.glob("@/views/**/*.vue");
242
- //页面配置项
243
- const viewConfig = import.meta.glob("@/views/**/config.ts", {
244
- import: "viewConfig",
245
- eager: true
246
- });
247
- const userRouterList = auth.getUserRouter(authStore.authMenuList, modules, viewConfig);
248
- console.log(authStore.authMenuList);
249
-
250
- userRouterList.forEach(route => {
251
- router.addRoute("layout", route);
252
- });
253
- authStore.setLayoutMenuList(userRouterList);
254
- return false;
255
- } catch (error) {
256
- // 💢 当按钮 || 菜单请求出错时,重定向到登陆页
257
- // globalStore.setToken("");
258
- // router.replace(LOGIN_URL);
259
- return Promise.reject(error);
260
- }
261
- };
262
-
263
- ```
264
-
265
- - Vue2+Vuex+Webpack+Vue
266
-
267
- ```javascript
268
- //router/index.js
269
- router.beforeEach(async (to, from, next) => {
270
- NProgress.start();
271
- document.title = to.query.name ? `${to.query.name + "-"}` : "" + `${to.meta.title ?? ""}`;
272
- // 1.判断是访问登陆页,有 Token 就在当前页面,没有 Token 重置路由并放行到登陆页
273
- const URL = [LOGIN_ROUTER];
274
- const token = auth.getToken();
275
- if (URL.includes(to.path.toLocaleLowerCase())) {
276
- if (token) return next(from.fullPath);
277
- return next();
278
- }
279
- //2.判断是否有无token,没有重定向到 login
280
- if (!token) return next({ path: LOGIN_ROUTER, replace: true });
281
- //3.判断用户是否有菜单列表
282
- if (!store.getters.authMenuListGet.length) {
283
- //监测是当前用户是否有权限,并同步菜单
284
- const isEmptyPower = await initDynamicRouter(to.path);
285
- if (!isEmptyPower) return next({ ...to, replace: true });
286
- } else {
287
- //动态设置菜单
288
- setNavList(to.path, permission);
289
- }
290
- return next();
291
- });
292
- //router/dynamicRouter.js
293
- let userStationRouter = [];
294
- /**
295
- * 初始化动态路由
296
- */
297
- export const initDynamicRouter = async path => {
298
- try {
299
- // 1.获取菜单列表 && 按钮权限(可合并到一个接口获取,根据后端不同可自行改造)
300
- // await store.dispatch('getUserRouteListApi');
301
- // console.log(store.getters.authMenuListGet);
302
- const authMenuList = await fetchUserRouteList();
303
- //2.判断当前用户有没有系统权限
304
- if (!authMenuList.length) {
305
- handleNoPermission();
306
- return true;
307
- }
308
- // 3.添加动态路由,生成菜单栏
309
- userStationRouter = generateUserStationRouter(authMenuList);
310
- addRoutesToRouter(userStationRouter);
311
- addRoutesToRouter(permission);
312
- setNavList(path, permission);
313
- return false;
314
- } catch (error) {
315
- // 💢 当按钮 || 菜单请求出错时,重定向到登陆页
316
- // globalStore.setToken("");
317
- // router.replace(LOGIN_URL);
318
- handleRequestError(error);
319
- return Promise.reject(error);
320
- }
321
- };
322
- //错误处理
323
- function handleRequestError(error) {
324
- auth.removeToken();
325
- }
326
- //无权限处理
327
- function handleNoPermission() {
328
- Notification({
329
- title: "无权限访问",
330
- message: "当前账号无任何系统权限,请联系系统管理员!",
331
- type: "warning",
332
- duration: 3000
333
- });
334
- }
335
- //动态用户菜单
336
- async function fetchUserRouteList() {
337
- await store.dispatch("getUserRouteListApi");
338
- return store.getters.authMenuListGet.map(item => item.routeView);
339
- }
340
- //过滤路由
341
- function generateUserStationRouter(authMenuList) {
342
- return stationRouter
343
- .map(item => {
344
- if (item.children.length === 1 && authMenuList.includes(item.path)) {
345
- return item;
346
- } else if (item.children.length > 1) {
347
- item.children = item.children.filter(child => authMenuList.includes(child.path));
348
- return item.children.length ? item : null;
349
- }
350
- return null;
351
- })
352
- .filter(item => item !== null);
353
- }
354
- //动态添加路由
355
- function addRoutesToRouter(routes) {
356
- for (let route of routes) {
357
- router.addRoute(route);
358
- }
359
- }
360
- ```
361
-
362
- - 404 页面配置
363
-
364
- - Vue2+VueRouter3.x
365
-
366
- ```javascript
367
- //静态路由下添加
368
- {
369
- path: '*',
370
- component: () => import('@/components/ErrorPage/404.vue'),
371
- },
372
- ```
373
-
374
- - Vue3+VueRouter4.x
375
-
376
- ```javascript
377
- //静态路由下添加
378
- {
379
- path: "/:pathMatch(.*)*",
380
- component: () => import("@/components/ErrorMessage/404.vue")
381
- }
382
- ```
383
-
384
- - 按钮级别权限处理(自定义指令)
385
-
386
- ```javascript
387
- import store from "@/store";
388
- const auth = {
389
- inserted(el, binding) {
390
- controlShowByUserPower(el, binding);
391
- }
392
- };
393
- function controlShowByUserPower(el, binding) {
394
- const value = binding.value;
395
- const authButtonList = store.getters.authButtonListGet;
396
- return !authButtonList.includes(value) ? el.parentNode.removeChild(el) : "";
397
- }
398
- export default auth;
399
- //如何使用,“stationController.addStation标识需要与按钮权限标识匹配”
400
- <div v-auth="'stationController.addStation'"> </div>;
401
- ```
402
-
403
- ## 主题
404
-
405
- - 使用方式
406
-
407
- ```javascript
408
- //在项目入口文件 main.js/main.ts中,在webpack5/vite项目中请使用以下方式按需导入
409
- import { install } from "yxuse/theme";
410
- install();
411
- //在webpack4或其他低版本语法
412
- import yxuse from "yxuse";
413
- const { install } = yxuse.theme;
414
- install();
415
- ```
416
-
417
- - 内置方法
418
-
419
- ```javascript
420
- /**
421
- * @description:注册主题下的css变量
422
- */
423
- install;
424
- /**
425
- * @description:修改主题
426
- * @param themeName 主题名称
427
- */
428
- changeTheme;
429
- /**
430
- * @description:获取当前主题
431
- */
432
- getCurTheme;
433
- /**
434
- * @description:获取当前主题下的系统配置
435
- * @param systemName 系统名称
436
- */
437
- getSystemThemeConfig;
438
-
439
- /**
440
- * @description:获取当前主题下的某个组/模块配置颜色
441
- * @param groupName 名称
442
- */
443
- getGroupColor;
444
-
445
- /**
446
- * @description:注册当前系统私有css变量
447
- * @param systemName 系统名称
448
- */
449
- installSystemTheme;
450
- ```
451
-
452
- - css 变量 json 配置
453
-
454
- > 下方各类组件颜色变量配置,需要大家一起丰富
455
-
456
- ```javascript
457
- green: {
458
- common: {
459
- //公用颜色
460
- color: {
461
- //主题色
462
- "main-100": "rgba(80, 165, 122, 1)",
463
- "main-50": "rgba(80, 165, 122, 0.5)",
464
- "main-25": "rgba(80, 165, 122, 0.25)",
465
- "main-15": "rgba(80, 165, 122, 0.15)",
466
- "main-5": "rgba(80, 165, 122, 0.05)",
467
-
468
- //故障色
469
- "error-100": "rgba(255, 152, 146, 1)",
470
- "error-50": "rgba(255, 152, 146, 0.5)",
471
- "error-25": "rgba(255, 152, 146, 0.25)",
472
- "error-15": "rgba(255, 152, 146, 0.15)",
473
- "error-5": "rgba(255, 152, 146, 0.05)",
474
-
475
- //预警色
476
- "warning-100": "rgba(249, 162, 33, 1)",
477
- "warning-50": "rgba(249, 162, 33, 0.5)",
478
- "warning-25": "rgba(249, 162, 33, 0.25)",
479
- "warning-15": "rgba(249, 162, 33, 0.15)",
480
- "warning-5": "rgba(249, 162, 33, 0.05)",
481
-
482
- //信息色
483
- "info-100": "rgba(133, 233, 183, 1)",
484
- "info-50": "rgba(133, 233, 183, 0.5)",
485
- "info-25": "rgba(133, 233, 183, 0.25)",
486
- "info-15": "rgba(133, 233, 183, 0.15)",
487
- "info-5": "rgba(133, 233, 183, 0.05)",
488
-
489
- //中性色
490
- "neutral-100": "rgba(85, 221, 221, 1)",
491
- "neutral-50": "rgba(85, 221, 221, 0.5)",
492
- "neutral-25": "rgba(85, 221, 221, 0.25)",
493
- "neutral-15": "rgba(85, 221, 221, 0.15)",
494
- "neutral-5": "rgba(85, 221, 221, 0.05)"
495
- },
496
- //背景色类
497
- background: {
498
- "error-gradual": "linear-gradient(90deg, #FFCECB 0%, rgba(255,235,233,0.35) 100%)",
499
- "warning-gradual": "linear-gradient(90deg, #FFE4BC 0%, rgba(255,250,233,0.35) 100%)",
500
- "success-gradual": "linear-gradient(90deg, #D5ECBE 0%, rgba(234,255,233,0.35) 100%)"
501
- },
502
- //按钮类
503
- button: {
504
- background: "rgba(103, 186, 145, 0.10)",
505
- "border-color": "rgba(80, 165, 122, 1)",
506
- "text-color": "rgba(80, 165, 122, 1)",
507
- "active-background-color": "rgba(80, 165, 122, 1)",
508
- "active-border-color": "rgba(154, 209, 162, 1)",
509
- "active-text-color": "#fff"
510
- },
511
- checkbox: {
512
- background: "rgba(216, 233, 219, 1)",
513
- "icon-color": "rgba(80, 165, 122, 0)",
514
- "border-color": "rgba(154, 209, 162, 1)",
515
- "checked-background": "rgba(216, 233, 219, 1)",
516
- "checked-icon-color": "rgba(80, 165, 122, 1)",
517
- "checked-border-color": "rgba(154, 209, 162, 1)"
518
- },
519
- //input
520
- input: {
521
- background: "rgba(237, 246, 239, 1)",
522
- "border-color": "rgba(80, 165, 122, 1)",
523
- color: "rgba(29, 75, 52, 1)",
524
- "placeholder-color": "rgba(80, 165, 122, 1)",
525
- "hover-background": "rgba(237, 246, 239, 0.30)",
526
- "hover-border-color": "rgba(80, 165, 122, 1)",
527
- "hover-color": "rgba(80, 165, 122, 1)",
528
- "active-background": "rgba(237, 246, 239, 0.30)",
529
- "active-border-color": "rgba(80, 165, 122, 1)",
530
- "active-color": "rgba(80, 165, 122, 1)",
531
- "disabled-background": "rgba(237, 246, 239, 1)",
532
- "disabled-border-color": "rgba(237, 246, 239, 1)",
533
- "disabled-color": "rgba(83, 83, 83, 1)"
534
- },
535
- // select
536
- select: {
537
- "dropdown-background": "rgba(237, 246, 239, 1)",
538
- "dropdown-border-color": "rgba(80, 165, 122, 1)",
539
- "dropdown-item-color": "rgba(80, 165, 122, 1)",
540
- "dropdown-item-hover-background": "rgba(178, 220, 198, 1)",
541
- "dropdown-item-hover-color": "rgba(29, 75, 52, 1)",
542
- "dropdown-item-selected-background": "rgba(178, 220, 198, 1)",
543
- "dropdown-item-selected-color": "rgba(29, 75, 52, 1)"
544
- },
545
- //文字颜色
546
- text: {
547
- main: "#50A57A",
548
- deep: "#1D4B34",
549
- light: "rgba(80, 165, 122, 0.50)",
550
- paler: "#637B6B",
551
- warning: "#F8B85A"
552
- },
553
- tree:{},
554
- //布局类
555
- layout: {},
556
- //表格类
557
- table: {},
558
- //曲线类
559
- chart: {},
560
- //提示类
561
- message: {}
562
- },
563
-
564
- //各系统个性化配置
565
- cloud: {},//运管系统
566
- "station-control-center": {}, //站控
567
- "traceplan-client":{} //任务计划
568
- ...
569
- },
570
-
571
-
572
- ```
1
+ # yxuse
2
+
3
+ ## 更新日志
4
+
5
+ - 2024 4-01 (Vue2.x--> 2.0.11 Vue3.x--->3.0.18)
6
+
7
+ - 悬浮球新增语言切换的入口
8
+ - 新增翻译的模块 translate
9
+
10
+ ```js
11
+ export interface YxuseOptions {
12
+ ...之前的配置
13
+ /** 系统标识,isRenderLang为true时必传 */
14
+ systemKey?: string;
15
+ }
16
+ translate 模块方法说明
17
+
18
+ /**
19
+ * @description:初始化语言包
20
+ * @param {*} lang 语言包标识
21
+ * @param {*} systemKey 系统标识
22
+ */
23
+ initTranslate
24
+ /**
25
+ * @description:语言切换
26
+ * @param {*} lang 语言包标识
27
+ */
28
+ changeLang
29
+
30
+ /**
31
+ * @description:获取当前语言
32
+ */
33
+ getLang
34
+
35
+ ```
36
+
37
+ - 2024 3-18 (Vue2.x--> 2.0.3 Vue3.x--->3.0.10)
38
+
39
+ - theme
40
+
41
+ - 主题初始化 install 方法新增配置,主要有当前开发的环境,在开发环境下无 token 会进行弹窗提示,进行自动登录,生产环境登录失效自动跳转至 loginUrl 地址(已内置)
42
+
43
+ ```js
44
+ export interface YxuseOptions {
45
+ /** 是否渲染悬浮球*/
46
+ isRenderToolbar?: boolean;
47
+ /** 是否加载工单*/
48
+ isRenderIssue?: boolean;
49
+ /** 是否加载语言切换*/
50
+ isRenderLang?: boolean;
51
+ /** 登录页地址,非运管系统项目使用*/
52
+ loginUrl?: string;
53
+ /** 自定义登录api,非运管系统项目使用*/
54
+ loginApiUrl?: string;
55
+ /** 翻译Api地址,非运管系统项目使用*/
56
+ translateApiUrl?: string;
57
+ /** 主题列表接口,非运管系统项目使用*/
58
+ themeApiUrl: string;
59
+ /** 首页地址,非运管系统项目使用*/
60
+ homeUrl?: string;
61
+ /** 系统默认语言*/
62
+ lang?: string;
63
+ /** 当前环境*/
64
+ environment: "development" | "production";
65
+ }
66
+ ```
67
+
68
+ - 新增判断当前色值是否在当前主题中的方法 findColorByTheme(key: string, color: string)
69
+
70
+ - auth
71
+
72
+ - 新增获取系统配置的方法 getSystemConfig(key: string)
73
+
74
+ - utils
75
+ - 新增判断该色值是否是深色的方法 isDarkColor(color: string)
76
+
77
+ ## 起步
78
+
79
+ ```javascript
80
+ 低版本适配为1.0.100
81
+ //npm
82
+ npm install yxuse@latest
83
+ //pnpm
84
+ pnpm install yxuse@latest
85
+
86
+ //最新淘宝镜像地址为 https://registry.npmmirror.com
87
+
88
+ //速度慢或者版本更新不及时 请使用npm源镜像下载
89
+ // npm set registry https://registry.npmjs.org
90
+ // //或
91
+ // pnpm set registry https://registry.npmjs.org
92
+
93
+ npm publish
94
+ ```
95
+
96
+ ## 权限相关
97
+
98
+ ```javascript
99
+ import { auth } from "yxuse/api";
100
+ ```
101
+
102
+ - 数据权限
103
+
104
+ - 在综合管理-用户管理中操作栏编辑数据权限,给对应账户添加对应的星和站即可。管理员账户无需配置,默认有所有的星和站
105
+
106
+ - 系统权限
107
+
108
+ - 系统权限
109
+
110
+ - 此层级的权限决定在运管系统入口处是否显示。目前有综合管理(integrated-management)、轨道控制系统(orbit)、任务计划(traceplan)、遥控分系统(telecommand)、遥测分系统(telemetry)、站控分系统(station-control)。
111
+ - 配置步骤:
112
+ 1. 在综合管理系统-权限配置模块新增分系统
113
+ 2. 在综合管理-用户管理中操作栏(系统权限)给对应用户分配系统权限
114
+
115
+ - 分系统菜单权限
116
+
117
+ - 此层级的权限决定在各分系统的菜单栏是否显示。
118
+ - 配置步骤:
119
+ 1. 在综合管理系统-权限配置模块中各分系统下添加分系统路由
120
+ 2. 表单配置说明:路由名称(左侧菜单名称),路由标识(分系统名称.前端路由名称),路由类型选择页面,前端路由(前端页面路由),接口路由(可以不填)
121
+ 3. 在综合管理-用户管理中操作栏(系统权限)给对应用户分配当前系统权限
122
+
123
+ - 分系统按钮权限
124
+
125
+ - 此层级的权限决定在各分系统中某按钮的是否显示
126
+
127
+ - 配置步骤:
128
+
129
+ 1. 在综合管理系统-权限配置模块中各分系统下添加分系统路由
130
+
131
+ 2. 表单配置说明:路由名称(左侧菜单名称),路由标识(前端页面路由名称.按钮含义),路由类型选择按钮类型,前端路由(前端页面路由名称.按钮含义),接口路由(可以不填)
132
+
133
+ - yxuse 内置方法
134
+
135
+ ```javascript
136
+ /**
137
+ * @description:获取token
138
+ */
139
+ getToken;
140
+
141
+ /**
142
+ * @description:移除token
143
+ */
144
+ removeToken;
145
+
146
+ /**
147
+ * 获取当前用户的权限(通用权限)
148
+ * @param systemName 系统名称
149
+ * @description 综合管理分系统->integrated
150
+ * @description 站控分系统->station
151
+ * @description 综合管理->integrated
152
+ * @description 轨道分系统->orbit
153
+ * @description 任务计划分系统->traceplan
154
+ * @description 遥控分系统->telecommand
155
+ * @description 遥测分系统->telemetry
156
+ * @returns 当前分系统的用户菜单列表 userMenuList
157
+ * @returns 当前分系统的用户按钮列表 userBtnList
158
+ */
159
+ getUserPermissions;
160
+
161
+ /**
162
+ *
163
+ * @param userMenuList 用户路由数据
164
+ * @param viewModules 页面文件
165
+ * @param viewConfig 页面配置项
166
+ * @returns UserRouter 用户动态路由
167
+ * @description 综合管理分系统->integrated
168
+ * @description 站控分系统->station
169
+ * 此方法适用于Vue3+Vite项目
170
+ */
171
+ getUserRouter;
172
+ ```
173
+
174
+ - 代码参考
175
+
176
+ - Vue3.0+Vite+Ts+pinia
177
+
178
+ ```javascript
179
+ //Vue3.0+Vite+Ts+pinia
180
+ // router/index.ts
181
+ router.beforeEach(async (to, from, next) => {
182
+ const globalStore = GlobalStore();
183
+ NProgress.start();
184
+ // await getBaseConfig();
185
+ //权限校验
186
+ // 2.动态设置标题
187
+ const title = import.meta.env.VITE_GLOB_APP_TITLE;
188
+ document.title = to.meta.title ? `${to.meta.title} - ${title}` : title;
189
+ // 3.判断是访问登陆页,有 Token 就在当前页面,没有 Token 重置路由并放行到登陆页
190
+ const URL = [LOGIN_URL];
191
+ if (URL.includes(to.path.toLocaleLowerCase())) {
192
+ if (globalStore.token) return next(from.fullPath);
193
+ return next();
194
+ }
195
+ // 4.判断访问页面是否在路由白名单地址中,如果存在直接放行
196
+ if (ROUTER_WHITE_LIST.includes(to.path)) return next();
197
+ // 5.判断是否有 Token,没有重定向到 login
198
+
199
+ if (!globalStore.token) return next({ path: LOGIN_URL, replace: true });
200
+
201
+ // 6.如果没有菜单列表,或者系统列表,就重新请求菜单列表并添加动态路由
202
+ const authStore = AuthStore();
203
+ authStore.setRouteName(to.name as string);
204
+
205
+ if (!authStore.authMenuList.length) {
206
+ //监测是当前用户是否有权限
207
+ const isEmptyPower = await initDynamicRouter(to.path);
208
+ if (!isEmptyPower) return next({ ...to, replace: true });
209
+ }
210
+ next();
211
+ });
212
+ //router/modules/dynamicRouter.ts
213
+ export const initDynamicRouter = async path => {
214
+ const authStore = AuthStore();
215
+ const globalStore = GlobalStore();
216
+ const configStore = ConfigStore();
217
+ const baseConfig = configStore.baseConfigMapGet;
218
+ if (Object.keys(baseConfig).length === 0) {
219
+ await configStore.getBaseConfig();
220
+ }
221
+ try {
222
+ // 1.获取菜单列表 && 按钮权限(可合并到一个接口获取,根据后端不同可自行改造)
223
+ await authStore.getUserRouteListApi();
224
+ //2.判断当前用户有没有系统权限
225
+ if (!authStore.authMenuListGet.length) {
226
+ //用户无权限且当前路由不在系统入口页面 默认跳转至系统入口
227
+ if (path !== SYSTEM_ENTRY) {
228
+ router.replace(SYSTEM_ENTRY);
229
+ } else {
230
+ ElNotification({
231
+ title: "无权限访问",
232
+ message: "当前账号无任何系统权限,请联系系统管理员!",
233
+ type: "warning",
234
+ duration: 3000
235
+ });
236
+ }
237
+ return true;
238
+ }
239
+ // 3.添加动态路由
240
+ //页面文件
241
+ const modules = import.meta.glob("@/views/**/*.vue");
242
+ //页面配置项
243
+ const viewConfig = import.meta.glob("@/views/**/config.ts", {
244
+ import: "viewConfig",
245
+ eager: true
246
+ });
247
+ const userRouterList = auth.getUserRouter(authStore.authMenuList, modules, viewConfig);
248
+ console.log(authStore.authMenuList);
249
+
250
+ userRouterList.forEach(route => {
251
+ router.addRoute("layout", route);
252
+ });
253
+ authStore.setLayoutMenuList(userRouterList);
254
+ return false;
255
+ } catch (error) {
256
+ // 💢 当按钮 || 菜单请求出错时,重定向到登陆页
257
+ // globalStore.setToken("");
258
+ // router.replace(LOGIN_URL);
259
+ return Promise.reject(error);
260
+ }
261
+ };
262
+
263
+ ```
264
+
265
+ - Vue2+Vuex+Webpack+Vue
266
+
267
+ ```javascript
268
+ //router/index.js
269
+ router.beforeEach(async (to, from, next) => {
270
+ NProgress.start();
271
+ document.title = to.query.name ? `${to.query.name + "-"}` : "" + `${to.meta.title ?? ""}`;
272
+ // 1.判断是访问登陆页,有 Token 就在当前页面,没有 Token 重置路由并放行到登陆页
273
+ const URL = [LOGIN_ROUTER];
274
+ const token = auth.getToken();
275
+ if (URL.includes(to.path.toLocaleLowerCase())) {
276
+ if (token) return next(from.fullPath);
277
+ return next();
278
+ }
279
+ //2.判断是否有无token,没有重定向到 login
280
+ if (!token) return next({ path: LOGIN_ROUTER, replace: true });
281
+ //3.判断用户是否有菜单列表
282
+ if (!store.getters.authMenuListGet.length) {
283
+ //监测是当前用户是否有权限,并同步菜单
284
+ const isEmptyPower = await initDynamicRouter(to.path);
285
+ if (!isEmptyPower) return next({ ...to, replace: true });
286
+ } else {
287
+ //动态设置菜单
288
+ setNavList(to.path, permission);
289
+ }
290
+ return next();
291
+ });
292
+ //router/dynamicRouter.js
293
+ let userStationRouter = [];
294
+ /**
295
+ * 初始化动态路由
296
+ */
297
+ export const initDynamicRouter = async path => {
298
+ try {
299
+ // 1.获取菜单列表 && 按钮权限(可合并到一个接口获取,根据后端不同可自行改造)
300
+ // await store.dispatch('getUserRouteListApi');
301
+ // console.log(store.getters.authMenuListGet);
302
+ const authMenuList = await fetchUserRouteList();
303
+ //2.判断当前用户有没有系统权限
304
+ if (!authMenuList.length) {
305
+ handleNoPermission();
306
+ return true;
307
+ }
308
+ // 3.添加动态路由,生成菜单栏
309
+ userStationRouter = generateUserStationRouter(authMenuList);
310
+ addRoutesToRouter(userStationRouter);
311
+ addRoutesToRouter(permission);
312
+ setNavList(path, permission);
313
+ return false;
314
+ } catch (error) {
315
+ // 💢 当按钮 || 菜单请求出错时,重定向到登陆页
316
+ // globalStore.setToken("");
317
+ // router.replace(LOGIN_URL);
318
+ handleRequestError(error);
319
+ return Promise.reject(error);
320
+ }
321
+ };
322
+ //错误处理
323
+ function handleRequestError(error) {
324
+ auth.removeToken();
325
+ }
326
+ //无权限处理
327
+ function handleNoPermission() {
328
+ Notification({
329
+ title: "无权限访问",
330
+ message: "当前账号无任何系统权限,请联系系统管理员!",
331
+ type: "warning",
332
+ duration: 3000
333
+ });
334
+ }
335
+ //动态用户菜单
336
+ async function fetchUserRouteList() {
337
+ await store.dispatch("getUserRouteListApi");
338
+ return store.getters.authMenuListGet.map(item => item.routeView);
339
+ }
340
+ //过滤路由
341
+ function generateUserStationRouter(authMenuList) {
342
+ return stationRouter
343
+ .map(item => {
344
+ if (item.children.length === 1 && authMenuList.includes(item.path)) {
345
+ return item;
346
+ } else if (item.children.length > 1) {
347
+ item.children = item.children.filter(child => authMenuList.includes(child.path));
348
+ return item.children.length ? item : null;
349
+ }
350
+ return null;
351
+ })
352
+ .filter(item => item !== null);
353
+ }
354
+ //动态添加路由
355
+ function addRoutesToRouter(routes) {
356
+ for (let route of routes) {
357
+ router.addRoute(route);
358
+ }
359
+ }
360
+ ```
361
+
362
+ - 404 页面配置
363
+
364
+ - Vue2+VueRouter3.x
365
+
366
+ ```javascript
367
+ //静态路由下添加
368
+ {
369
+ path: '*',
370
+ component: () => import('@/components/ErrorPage/404.vue'),
371
+ },
372
+ ```
373
+
374
+ - Vue3+VueRouter4.x
375
+
376
+ ```javascript
377
+ //静态路由下添加
378
+ {
379
+ path: "/:pathMatch(.*)*",
380
+ component: () => import("@/components/ErrorMessage/404.vue")
381
+ }
382
+ ```
383
+
384
+ - 按钮级别权限处理(自定义指令)
385
+
386
+ ```javascript
387
+ import store from "@/store";
388
+ const auth = {
389
+ inserted(el, binding) {
390
+ controlShowByUserPower(el, binding);
391
+ }
392
+ };
393
+ function controlShowByUserPower(el, binding) {
394
+ const value = binding.value;
395
+ const authButtonList = store.getters.authButtonListGet;
396
+ return !authButtonList.includes(value) ? el.parentNode.removeChild(el) : "";
397
+ }
398
+ export default auth;
399
+ //如何使用,“stationController.addStation标识需要与按钮权限标识匹配”
400
+ <div v-auth="'stationController.addStation'"> </div>;
401
+ ```
402
+
403
+ ## 主题
404
+
405
+ - 使用方式
406
+
407
+ ```javascript
408
+ //在项目入口文件 main.js/main.ts中,在webpack5/vite项目中请使用以下方式按需导入
409
+ import { install } from "yxuse/theme";
410
+ install();
411
+ //在webpack4或其他低版本语法
412
+ import yxuse from "yxuse";
413
+ const { install } = yxuse.theme;
414
+ install();
415
+ ```
416
+
417
+ - 内置方法
418
+
419
+ ```javascript
420
+ /**
421
+ * @description:注册主题下的css变量
422
+ */
423
+ install;
424
+ /**
425
+ * @description:修改主题
426
+ * @param themeName 主题名称
427
+ */
428
+ changeTheme;
429
+ /**
430
+ * @description:获取当前主题
431
+ */
432
+ getCurTheme;
433
+ /**
434
+ * @description:获取当前主题下的系统配置
435
+ * @param systemName 系统名称
436
+ */
437
+ getSystemThemeConfig;
438
+
439
+ /**
440
+ * @description:获取当前主题下的某个组/模块配置颜色
441
+ * @param groupName 名称
442
+ */
443
+ getGroupColor;
444
+
445
+ /**
446
+ * @description:注册当前系统私有css变量
447
+ * @param systemName 系统名称
448
+ */
449
+ installSystemTheme;
450
+ ```
451
+
452
+ - css 变量 json 配置
453
+
454
+ > 下方各类组件颜色变量配置,需要大家一起丰富
455
+
456
+ ```javascript
457
+ green: {
458
+ common: {
459
+ //公用颜色
460
+ color: {
461
+ //主题色
462
+ "main-100": "rgba(80, 165, 122, 1)",
463
+ "main-50": "rgba(80, 165, 122, 0.5)",
464
+ "main-25": "rgba(80, 165, 122, 0.25)",
465
+ "main-15": "rgba(80, 165, 122, 0.15)",
466
+ "main-5": "rgba(80, 165, 122, 0.05)",
467
+
468
+ //故障色
469
+ "error-100": "rgba(255, 152, 146, 1)",
470
+ "error-50": "rgba(255, 152, 146, 0.5)",
471
+ "error-25": "rgba(255, 152, 146, 0.25)",
472
+ "error-15": "rgba(255, 152, 146, 0.15)",
473
+ "error-5": "rgba(255, 152, 146, 0.05)",
474
+
475
+ //预警色
476
+ "warning-100": "rgba(249, 162, 33, 1)",
477
+ "warning-50": "rgba(249, 162, 33, 0.5)",
478
+ "warning-25": "rgba(249, 162, 33, 0.25)",
479
+ "warning-15": "rgba(249, 162, 33, 0.15)",
480
+ "warning-5": "rgba(249, 162, 33, 0.05)",
481
+
482
+ //信息色
483
+ "info-100": "rgba(133, 233, 183, 1)",
484
+ "info-50": "rgba(133, 233, 183, 0.5)",
485
+ "info-25": "rgba(133, 233, 183, 0.25)",
486
+ "info-15": "rgba(133, 233, 183, 0.15)",
487
+ "info-5": "rgba(133, 233, 183, 0.05)",
488
+
489
+ //中性色
490
+ "neutral-100": "rgba(85, 221, 221, 1)",
491
+ "neutral-50": "rgba(85, 221, 221, 0.5)",
492
+ "neutral-25": "rgba(85, 221, 221, 0.25)",
493
+ "neutral-15": "rgba(85, 221, 221, 0.15)",
494
+ "neutral-5": "rgba(85, 221, 221, 0.05)"
495
+ },
496
+ //背景色类
497
+ background: {
498
+ "error-gradual": "linear-gradient(90deg, #FFCECB 0%, rgba(255,235,233,0.35) 100%)",
499
+ "warning-gradual": "linear-gradient(90deg, #FFE4BC 0%, rgba(255,250,233,0.35) 100%)",
500
+ "success-gradual": "linear-gradient(90deg, #D5ECBE 0%, rgba(234,255,233,0.35) 100%)"
501
+ },
502
+ //按钮类
503
+ button: {
504
+ background: "rgba(103, 186, 145, 0.10)",
505
+ "border-color": "rgba(80, 165, 122, 1)",
506
+ "text-color": "rgba(80, 165, 122, 1)",
507
+ "active-background-color": "rgba(80, 165, 122, 1)",
508
+ "active-border-color": "rgba(154, 209, 162, 1)",
509
+ "active-text-color": "#fff"
510
+ },
511
+ checkbox: {
512
+ background: "rgba(216, 233, 219, 1)",
513
+ "icon-color": "rgba(80, 165, 122, 0)",
514
+ "border-color": "rgba(154, 209, 162, 1)",
515
+ "checked-background": "rgba(216, 233, 219, 1)",
516
+ "checked-icon-color": "rgba(80, 165, 122, 1)",
517
+ "checked-border-color": "rgba(154, 209, 162, 1)"
518
+ },
519
+ //input
520
+ input: {
521
+ background: "rgba(237, 246, 239, 1)",
522
+ "border-color": "rgba(80, 165, 122, 1)",
523
+ color: "rgba(29, 75, 52, 1)",
524
+ "placeholder-color": "rgba(80, 165, 122, 1)",
525
+ "hover-background": "rgba(237, 246, 239, 0.30)",
526
+ "hover-border-color": "rgba(80, 165, 122, 1)",
527
+ "hover-color": "rgba(80, 165, 122, 1)",
528
+ "active-background": "rgba(237, 246, 239, 0.30)",
529
+ "active-border-color": "rgba(80, 165, 122, 1)",
530
+ "active-color": "rgba(80, 165, 122, 1)",
531
+ "disabled-background": "rgba(237, 246, 239, 1)",
532
+ "disabled-border-color": "rgba(237, 246, 239, 1)",
533
+ "disabled-color": "rgba(83, 83, 83, 1)"
534
+ },
535
+ // select
536
+ select: {
537
+ "dropdown-background": "rgba(237, 246, 239, 1)",
538
+ "dropdown-border-color": "rgba(80, 165, 122, 1)",
539
+ "dropdown-item-color": "rgba(80, 165, 122, 1)",
540
+ "dropdown-item-hover-background": "rgba(178, 220, 198, 1)",
541
+ "dropdown-item-hover-color": "rgba(29, 75, 52, 1)",
542
+ "dropdown-item-selected-background": "rgba(178, 220, 198, 1)",
543
+ "dropdown-item-selected-color": "rgba(29, 75, 52, 1)"
544
+ },
545
+ //文字颜色
546
+ text: {
547
+ main: "#50A57A",
548
+ deep: "#1D4B34",
549
+ light: "rgba(80, 165, 122, 0.50)",
550
+ paler: "#637B6B",
551
+ warning: "#F8B85A"
552
+ },
553
+ tree:{},
554
+ //布局类
555
+ layout: {},
556
+ //表格类
557
+ table: {},
558
+ //曲线类
559
+ chart: {},
560
+ //提示类
561
+ message: {}
562
+ },
563
+
564
+ //各系统个性化配置
565
+ cloud: {},//运管系统
566
+ "station-control-center": {}, //站控
567
+ "traceplan-client":{} //任务计划
568
+ ...
569
+ },
570
+
571
+
572
+ ```