af-mobile-client-vue3 1.3.30 → 1.3.32
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/.claude/settings.local.json +10 -0
- package/.cursorrules +60 -60
- package/.editorconfig +9 -9
- package/.env +10 -10
- package/.env.development +1 -1
- package/.env.production +1 -1
- package/.node-version +1 -1
- package/.vscode/extensions.json +12 -12
- package/.vscode/settings.json +68 -66
- package/CLAUDE.md +218 -189
- package/README.md +182 -182
- package/af-example-mobile-vue-web.iml +9 -9
- package/build/vite/index.ts +98 -98
- package/build/vite/optimize.ts +34 -34
- package/build/vite/vconsole.ts +47 -47
- package/commitlint.config.ts +32 -32
- package/compress.js +36 -36
- package/eslint.config.ts +31 -30
- package/index.html +23 -23
- package/mock/data.ts +20 -20
- package/mock/index.ts +7 -7
- package/mock/modules/prose.mock.ts +13 -13
- package/mock/modules/user.mock.ts +95 -152
- package/mock/util.ts +19 -19
- package/netlify.toml +12 -12
- package/package.json +135 -114
- package/postcss.config.ts +27 -27
- package/public/favicon.svg +4 -4
- package/public/safari-pinned-tab.svg +4 -4
- package/scripts/verifyCommit.js +19 -19
- package/src/App.vue +79 -79
- package/src/api/auth/index.ts +77 -0
- package/src/api/auth/types.ts +200 -0
- package/src/api/mock/index.ts +30 -30
- package/src/api/user/index.ts +40 -40
- package/src/assets/img/user/login/background-shadow-1.svg +20 -20
- package/src/assets/img/user/login/logo-background.svg +20 -20
- package/src/bootstrap.ts +26 -26
- package/src/components/core/BeautifulLoading/index.vue +52 -52
- package/src/components/core/ImageUploader/index.vue +251 -251
- package/src/components/core/NavBar/index.vue +53 -53
- package/src/components/core/Tabbar/index.vue +32 -32
- package/src/components/core/Uploader/index.vue +124 -124
- package/src/components/core/XGridDropOption/index.vue +154 -154
- package/src/components/core/XMultiSelect/index.vue +183 -183
- package/src/components/core/XSelect/index.vue +149 -149
- package/src/components/data/CardContainer/CardContainer.vue +118 -118
- package/src/components/data/CardContainer/CardHeader.vue +99 -99
- package/src/components/data/InfoDisplay/index.vue +132 -132
- package/src/components/data/UserDetail/api.ts +24 -24
- package/src/components/data/UserDetail/index.vue +620 -620
- package/src/components/data/UserDetail/recordEntries.ts +159 -159
- package/src/components/data/UserDetail/types.ts +26 -26
- package/src/components/data/XBadge/index.vue +82 -82
- package/src/components/data/XCellDetail/index.vue +105 -105
- package/src/components/data/XCellList/XCellList.md +432 -432
- package/src/components/data/XCellList/index.vue +1436 -1436
- package/src/components/data/XCellListFilter/QrScanner/index.vue +207 -207
- package/src/components/data/XCellListFilter/QrScanner/startScanAnimation.ts +53 -53
- package/src/components/data/XCellListFilter/VpnRecognition/index.vue +119 -119
- package/src/components/data/XCellListFilter/index.vue +705 -705
- package/src/components/data/XForm/index.vue +659 -659
- package/src/components/data/XFormGroup/doc/DeviceForm.vue +122 -122
- package/src/components/data/XFormGroup/doc/FormGroupDemo.vue +56 -56
- package/src/components/data/XFormGroup/doc/README.md +286 -286
- package/src/components/data/XFormGroup/doc/UserForm.vue +102 -102
- package/src/components/data/XFormGroup/index.vue +240 -240
- package/src/components/data/XFormItem/index.vue +1310 -1310
- package/src/components/data/XOlMap/README.md +227 -227
- package/src/components/data/XOlMap/XLocationPicker/index.vue +226 -226
- package/src/components/data/XOlMap/index.vue +1490 -1490
- package/src/components/data/XOlMap/types.ts +149 -149
- package/src/components/data/XOlMap/utils/{wgs84ToGcj02.js → wgs84ToGcj02.ts} +171 -154
- package/src/components/data/XReportForm/DateTimeSecondsPicker.vue +208 -208
- package/src/components/data/XReportForm/XReportFormJsonRender.vue +220 -220
- package/src/components/data/XReportForm/index.vue +1393 -1393
- package/src/components/data/XReportGrid/XAddReport/XAddReport.vue +198 -198
- package/src/components/data/XReportGrid/XAddReport/index.js +3 -3
- package/src/components/data/XReportGrid/XAddReport/index.md +53 -53
- package/src/components/data/XReportGrid/XAddReport/index.ts +10 -10
- package/src/components/data/XReportGrid/XReport.vue +960 -960
- package/src/components/data/XReportGrid/XReportDemo.vue +33 -33
- package/src/components/data/XReportGrid/XReportDesign.vue +597 -597
- package/src/components/data/XReportGrid/XReportDrawer/XReportDrawer.vue +148 -148
- package/src/components/data/XReportGrid/XReportDrawer/index.js +3 -3
- package/src/components/data/XReportGrid/XReportDrawer/index.ts +10 -10
- package/src/components/data/XReportGrid/XReportJsonRender.vue +399 -399
- package/src/components/data/XReportGrid/XReportTrGroup.vue +592 -592
- package/src/components/data/XReportGrid/index.md +46 -46
- package/src/components/data/XReportGrid/print.js +184 -184
- package/src/components/data/XSignature/index.vue +284 -284
- package/src/components/data/XTag/index.vue +10 -10
- package/src/components/layout/NormalDataLayout/index.vue +69 -69
- package/src/components/layout/TabBarLayout/index.vue +40 -40
- package/src/composables/dark.ts +5 -5
- package/src/config/routes.ts +9 -9
- package/src/constants/index.ts +2 -2
- package/src/enums/requestEnum.ts +25 -25
- package/src/expression/ExpressionRunner.ts +28 -28
- package/src/expression/TestExpression.ts +510 -510
- package/src/expression/core/Delegate.ts +116 -116
- package/src/expression/core/Expression.ts +1359 -1359
- package/src/expression/core/Program.ts +985 -985
- package/src/expression/core/Token.ts +29 -29
- package/src/expression/enums/ExpressionType.ts +81 -81
- package/src/expression/enums/TokenType.ts +11 -11
- package/src/expression/exception/BreakWayException.ts +2 -2
- package/src/expression/exception/ContinueWayException.ts +2 -2
- package/src/expression/exception/ExpressionException.ts +29 -29
- package/src/expression/exception/ReturnWayException.ts +14 -14
- package/src/expression/exception/ServiceException.ts +22 -22
- package/src/expression/instances/JSONArray.ts +52 -52
- package/src/expression/instances/JSONObject.ts +118 -118
- package/src/expression/instances/LogicConsole.ts +31 -31
- package/src/font-style/font.css +4 -4
- package/src/hooks/useBoolean.ts +26 -26
- package/src/hooks/useCommon.ts +9 -9
- package/src/hooks/useLoading.ts +16 -16
- package/src/hooks/useLogin.ts +97 -97
- package/src/icons/svg/check-in.svg +32 -32
- package/src/icons/svg/dark.svg +4 -4
- package/src/icons/svg/github.svg +4 -4
- package/src/icons/svg/light.svg +4 -4
- package/src/icons/svg/link.svg +4 -4
- package/src/icons/svgo.yml +22 -22
- package/src/index.ts +4 -0
- package/src/layout/GridView/index.vue +16 -16
- package/src/layout/PageLayout.vue +9 -9
- package/src/layout/SingleLayout.vue +9 -9
- package/src/locales/en-US.json +128 -128
- package/src/locales/zh-CN.json +128 -128
- package/src/logic/LogicRunner.ts +67 -67
- package/src/logic/TestLogic.ts +13 -13
- package/src/logic/plugins/common/DateTools.ts +35 -35
- package/src/logic/plugins/common/VueTools.ts +30 -30
- package/src/logic/plugins/index.ts +7 -7
- package/src/main.ts +44 -44
- package/src/plugins/AppData.ts +38 -38
- package/src/plugins/GetLoginInfoService.ts +10 -10
- package/src/plugins/collectIcons.ts +10 -10
- package/src/plugins/index.ts +11 -11
- package/src/router/README.md +8 -8
- package/src/router/external-routes.ts +60 -0
- package/src/router/guards.ts +131 -59
- package/src/router/index.ts +35 -35
- package/src/router/invoiceRoutes.ts +33 -33
- package/src/router/routes.ts +426 -347
- package/src/services/api/Login.ts +6 -6
- package/src/services/api/common.ts +109 -109
- package/src/services/api/index.ts +7 -7
- package/src/services/api/manage.ts +8 -8
- package/src/services/api/search.ts +16 -16
- package/src/services/api/user.ts +17 -17
- package/src/services/restTools.ts +56 -56
- package/src/services/v3Api.ts +147 -147
- package/src/stores/index.ts +13 -13
- package/src/stores/modules/counter.ts +19 -19
- package/src/stores/modules/homeApp.ts +55 -55
- package/src/stores/modules/routeCache.ts +22 -23
- package/src/stores/modules/setting.ts +87 -87
- package/src/stores/modules/user.ts +326 -235
- package/src/stores/mutation-type.ts +12 -7
- package/src/styles/app.less +36 -36
- package/src/styles/login.less +109 -109
- package/src/styles/var.less +25 -25
- package/src/types/auth.ts +85 -0
- package/src/types/env.d.ts +16 -16
- package/src/types/platform.ts +194 -0
- package/src/types/settings.ts +1 -1
- package/src/types/vue-router.d.ts +13 -9
- package/src/utils/Storage.ts +124 -124
- package/src/utils/authority-utils.ts +84 -84
- package/src/utils/common.ts +41 -41
- package/src/utils/crypto.ts +39 -39
- package/src/utils/dataUtil.ts +42 -42
- package/src/utils/dictUtil.ts +52 -52
- package/src/utils/http/index.ts +201 -199
- package/src/utils/i18n.ts +72 -72
- package/src/utils/indexedDB.ts +195 -195
- package/src/utils/inline-px-to-vw.ts +28 -28
- package/src/utils/mobileUtil.ts +33 -34
- package/src/utils/platform-auth.ts +134 -0
- package/src/utils/progress.ts +19 -19
- package/src/utils/routerUtil.ts +271 -271
- package/src/utils/runEvalFunction.ts +13 -13
- package/src/utils/secureStorage.ts +70 -71
- package/src/utils/set-page-title.ts +5 -5
- package/src/utils/validate.ts +6 -6
- package/src/views/chat/index.vue +153 -153
- package/src/views/common/Forbidden.vue +97 -0
- package/src/views/common/LoadError.vue +63 -63
- package/src/views/common/NotFound.vue +67 -67
- package/src/views/component/EvaluateRecordView/index.vue +40 -40
- package/src/views/component/IconifyView/index.vue +504 -504
- package/src/views/component/UserDetailView/UserDetailPage.vue +77 -77
- package/src/views/component/UserDetailView/index.vue +234 -234
- package/src/views/component/XCellDetailView/index.vue +217 -217
- package/src/views/component/XCellListView/index.vue +108 -129
- package/src/views/component/XFormAppraiseView/index.vue +174 -174
- package/src/views/component/XFormGroupView/index.vue +78 -82
- package/src/views/component/XFormView/index.vue +27 -27
- package/src/views/component/XOlMapView/XLocationPicker/index.vue +118 -118
- package/src/views/component/XOlMapView/index.vue +434 -434
- package/src/views/component/XOlMapView/testData.ts +64 -64
- package/src/views/component/XReportFormIframeView/index.vue +47 -47
- package/src/views/component/XReportFormView/index.vue +13 -13
- package/src/views/component/XReportGridView/index.vue +17 -17
- package/src/views/component/XRequestView/index.vue +234 -234
- package/src/views/component/XSignatureView/index.vue +50 -50
- package/src/views/component/index.vue +181 -181
- package/src/views/component/menu.vue +117 -117
- package/src/views/component/notice.vue +46 -46
- package/src/views/component/topNav.vue +36 -36
- package/src/views/external/index.vue +152 -0
- package/src/views/invoiceShow/index.vue +61 -61
- package/src/views/loading/AuthLoading.vue +345 -0
- package/src/views/user/login/ForgetPasswordForm.vue +94 -94
- package/src/views/user/login/LoginForm.vue +350 -347
- package/src/views/user/login/LoginTitle.vue +76 -76
- package/src/views/user/login/LoginWave.vue +109 -109
- package/src/views/user/login/index.vue +22 -22
- package/src/views/user/my/comm/ModifyPassword.vue +346 -346
- package/src/views/user/my/index.vue +507 -507
- package/src/views/user/register/index.vue +952 -952
- package/src/views/userRecords/AbnormalAlarmRecords.vue +21 -21
- package/src/views/userRecords/CardReplacementRecords.vue +21 -21
- package/src/views/userRecords/ChangeRecords.vue +19 -19
- package/src/views/userRecords/CommandViewRecords.vue +20 -20
- package/src/views/userRecords/GasCompensationRecords.vue +20 -20
- package/src/views/userRecords/InstrumentCollectionRecords.vue +21 -21
- package/src/views/userRecords/MeterRecords.vue +20 -20
- package/src/views/userRecords/OperateRecords.vue +51 -51
- package/src/views/userRecords/OtherChargeRecords.vue +19 -19
- package/src/views/userRecords/PaymentRecords.vue +28 -28
- package/src/views/userRecords/PriceAdjustmentRecords.vue +19 -19
- package/src/views/userRecords/ReplacementRecords.vue +19 -19
- package/src/views/userRecords/SafetyRecords.vue +19 -19
- package/src/views/userRecords/TransactionRecords.vue +21 -21
- package/src/views/userRecords/TransferRecords.vue +19 -19
- package/src/views/userRecords/operateRecordDetail/index.vue +316 -316
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AddUserDetail.vue +124 -124
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AdvanceDeliveryDetail.vue +88 -88
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AutoAccountsCancelDetail.vue +205 -205
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AutoAccountsDetail.vue +192 -192
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/BankDkDetail.vue +192 -192
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/BankPayDetail.vue +192 -192
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/BlacklistDetail.vue +153 -153
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CancellationDetail.vue +101 -101
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CardMeterCenterCancelDetail.vue +127 -127
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CardMeterCenterDetail.vue +153 -153
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CardOverUserDetail.vue +153 -153
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ChangeMeterCancelDetail.vue +166 -166
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ChangeMeterDetail.vue +205 -205
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/DisableManageDetail.vue +127 -127
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/EnableManageDetail.vue +114 -114
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/FaZheChangeDetail.vue +124 -124
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/FeeDeductionDetail.vue +153 -153
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/GasPriceChangeDetail.vue +126 -126
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/InputtorChangeDetail.vue +126 -126
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/IotMeterCenterCancelDetail.vue +114 -114
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/IotMeterCenterDetail.vue +127 -127
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/IotOpenDetail.vue +88 -88
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/MachineCardDetail.vue +101 -101
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/MachineMeterCenterCancelDetail.vue +218 -218
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/MachineMeterCenterDetail.vue +153 -153
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OffGasAddGasDetail.vue +140 -140
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OtherChargeCancelDetail.vue +127 -127
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OtherChargeDetail.vue +114 -114
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OverUserChangeDetail.vue +127 -127
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ReBillDetail.vue +127 -127
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/RefundDetail.vue +114 -114
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ReplaceCardManageCancelDetail.vue +127 -127
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ReplaceCardManageDetail.vue +114 -114
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/SaleCardGasDetail.vue +140 -140
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/TransferManageCancelDetail.vue +152 -152
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/TransferManageDetail.vue +178 -178
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/UserChangeDetail.vue +123 -123
- package/src/views/userRecords/operateRecordDetail/operateRecordDetails/WechatPayDetail.vue +192 -192
- package/src/views/userRecords/types.ts +66 -66
- package/tsconfig.json +39 -39
- package/uno.config.ts +82 -82
- package/vite.config.ts +119 -118
- package/src/router/types.ts +0 -7
- package/src/utils/wechatUtil.ts +0 -9
package/src/utils/Storage.ts
CHANGED
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
// 默认缓存期限为7天
|
|
2
|
-
const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 创建本地缓存对象
|
|
6
|
-
*/
|
|
7
|
-
export function createStorage({ prefixKey = '', storage = localStorage } = {}) {
|
|
8
|
-
/**
|
|
9
|
-
* 本地缓存类
|
|
10
|
-
* @class Storage
|
|
11
|
-
*/
|
|
12
|
-
const Storage = class {
|
|
13
|
-
private storage = storage
|
|
14
|
-
private prefixKey?: string = prefixKey
|
|
15
|
-
|
|
16
|
-
private getKey(key: string) {
|
|
17
|
-
return `${this.prefixKey}${key}`.toUpperCase()
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @description 设置缓存
|
|
22
|
-
* @param {string} key 缓存键
|
|
23
|
-
* @param {*} value 缓存值
|
|
24
|
-
* @param expire
|
|
25
|
-
*/
|
|
26
|
-
set(key: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
|
27
|
-
const stringData = JSON.stringify({
|
|
28
|
-
value,
|
|
29
|
-
expire: expire !== null ? new Date().getTime() + expire * 1000 : null,
|
|
30
|
-
})
|
|
31
|
-
this.storage.setItem(this.getKey(key), stringData)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* 读取缓存
|
|
36
|
-
* @param {string} key 缓存键
|
|
37
|
-
* @param {*=} def 默认值
|
|
38
|
-
*/
|
|
39
|
-
get(key: string, def: any = null) {
|
|
40
|
-
const item = this.storage.getItem(this.getKey(key))
|
|
41
|
-
if (item) {
|
|
42
|
-
try {
|
|
43
|
-
const data = JSON.parse(item)
|
|
44
|
-
const { value, expire } = data
|
|
45
|
-
// 在有效期内直接返回
|
|
46
|
-
if (expire === null || expire >= Date.now())
|
|
47
|
-
return value
|
|
48
|
-
|
|
49
|
-
this.remove(key)
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
return def
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return def
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* 从缓存删除某项
|
|
60
|
-
* @param {string} key
|
|
61
|
-
*/
|
|
62
|
-
remove(key: string) {
|
|
63
|
-
this.storage.removeItem(this.getKey(key))
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* 清空所有缓存
|
|
68
|
-
* @memberOf Cache
|
|
69
|
-
*/
|
|
70
|
-
clear(): void {
|
|
71
|
-
this.storage.clear()
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* 设置cookie
|
|
76
|
-
* @param {string} name cookie 名称
|
|
77
|
-
* @param {*} value cookie 值
|
|
78
|
-
* @param {number=} expire 过期时间
|
|
79
|
-
* 如果过期时间为设置,默认关闭浏览器自动删除
|
|
80
|
-
* @example
|
|
81
|
-
*/
|
|
82
|
-
setCookie(name: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
|
83
|
-
document.cookie = `${this.getKey(name)}=${value}; Max-Age=${expire}`
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 根据名字获取cookie值
|
|
88
|
-
* @param name
|
|
89
|
-
*/
|
|
90
|
-
getCookie(name: string): string {
|
|
91
|
-
const cookieArr = document.cookie.split('; ')
|
|
92
|
-
for (let i = 0, length = cookieArr.length; i < length; i++) {
|
|
93
|
-
const kv = cookieArr[i].split('=')
|
|
94
|
-
if (kv[0] === this.getKey(name))
|
|
95
|
-
return kv[1]
|
|
96
|
-
}
|
|
97
|
-
return ''
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* 根据名字删除指定的cookie
|
|
102
|
-
* @param {string} key
|
|
103
|
-
*/
|
|
104
|
-
removeCookie(key: string) {
|
|
105
|
-
this.setCookie(key, 1, -1)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* 清空cookie,使所有cookie失效
|
|
110
|
-
*/
|
|
111
|
-
clearCookie(): void {
|
|
112
|
-
const keys = document.cookie.match(/[^ =;]+(?==)/g)
|
|
113
|
-
if (keys) {
|
|
114
|
-
for (let i = keys.length; i--;)
|
|
115
|
-
document.cookie = `${keys[i]}=0;expire=${new Date(0).toUTCString()}`
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return new Storage()
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export const storage = createStorage()
|
|
123
|
-
|
|
124
|
-
export default Storage
|
|
1
|
+
// 默认缓存期限为7天
|
|
2
|
+
const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 创建本地缓存对象
|
|
6
|
+
*/
|
|
7
|
+
export function createStorage({ prefixKey = '', storage = localStorage } = {}) {
|
|
8
|
+
/**
|
|
9
|
+
* 本地缓存类
|
|
10
|
+
* @class Storage
|
|
11
|
+
*/
|
|
12
|
+
const Storage = class {
|
|
13
|
+
private storage = storage
|
|
14
|
+
private prefixKey?: string = prefixKey
|
|
15
|
+
|
|
16
|
+
private getKey(key: string) {
|
|
17
|
+
return `${this.prefixKey}${key}`.toUpperCase()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @description 设置缓存
|
|
22
|
+
* @param {string} key 缓存键
|
|
23
|
+
* @param {*} value 缓存值
|
|
24
|
+
* @param expire
|
|
25
|
+
*/
|
|
26
|
+
set(key: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
|
27
|
+
const stringData = JSON.stringify({
|
|
28
|
+
value,
|
|
29
|
+
expire: expire !== null ? new Date().getTime() + expire * 1000 : null,
|
|
30
|
+
})
|
|
31
|
+
this.storage.setItem(this.getKey(key), stringData)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 读取缓存
|
|
36
|
+
* @param {string} key 缓存键
|
|
37
|
+
* @param {*=} def 默认值
|
|
38
|
+
*/
|
|
39
|
+
get(key: string, def: any = null) {
|
|
40
|
+
const item = this.storage.getItem(this.getKey(key))
|
|
41
|
+
if (item) {
|
|
42
|
+
try {
|
|
43
|
+
const data = JSON.parse(item)
|
|
44
|
+
const { value, expire } = data
|
|
45
|
+
// 在有效期内直接返回
|
|
46
|
+
if (expire === null || expire >= Date.now())
|
|
47
|
+
return value
|
|
48
|
+
|
|
49
|
+
this.remove(key)
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return def
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return def
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 从缓存删除某项
|
|
60
|
+
* @param {string} key
|
|
61
|
+
*/
|
|
62
|
+
remove(key: string) {
|
|
63
|
+
this.storage.removeItem(this.getKey(key))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 清空所有缓存
|
|
68
|
+
* @memberOf Cache
|
|
69
|
+
*/
|
|
70
|
+
clear(): void {
|
|
71
|
+
this.storage.clear()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 设置cookie
|
|
76
|
+
* @param {string} name cookie 名称
|
|
77
|
+
* @param {*} value cookie 值
|
|
78
|
+
* @param {number=} expire 过期时间
|
|
79
|
+
* 如果过期时间为设置,默认关闭浏览器自动删除
|
|
80
|
+
* @example
|
|
81
|
+
*/
|
|
82
|
+
setCookie(name: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
|
83
|
+
document.cookie = `${this.getKey(name)}=${value}; Max-Age=${expire}`
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 根据名字获取cookie值
|
|
88
|
+
* @param name
|
|
89
|
+
*/
|
|
90
|
+
getCookie(name: string): string {
|
|
91
|
+
const cookieArr = document.cookie.split('; ')
|
|
92
|
+
for (let i = 0, length = cookieArr.length; i < length; i++) {
|
|
93
|
+
const kv = cookieArr[i].split('=')
|
|
94
|
+
if (kv[0] === this.getKey(name))
|
|
95
|
+
return kv[1]
|
|
96
|
+
}
|
|
97
|
+
return ''
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 根据名字删除指定的cookie
|
|
102
|
+
* @param {string} key
|
|
103
|
+
*/
|
|
104
|
+
removeCookie(key: string) {
|
|
105
|
+
this.setCookie(key, 1, -1)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 清空cookie,使所有cookie失效
|
|
110
|
+
*/
|
|
111
|
+
clearCookie(): void {
|
|
112
|
+
const keys = document.cookie.match(/[^ =;]+(?==)/g)
|
|
113
|
+
if (keys) {
|
|
114
|
+
for (let i = keys.length; i--;)
|
|
115
|
+
document.cookie = `${keys[i]}=0;expire=${new Date(0).toUTCString()}`
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return new Storage()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const storage = createStorage()
|
|
123
|
+
|
|
124
|
+
export default Storage
|
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 判断是否有路由的权限
|
|
3
|
-
* @param authority 路由权限配置
|
|
4
|
-
* @param permissions 用户权限集合
|
|
5
|
-
*/
|
|
6
|
-
function hasPermission(authority: any, permissions: any): boolean {
|
|
7
|
-
let required: string = '*'
|
|
8
|
-
if (typeof authority === 'string')
|
|
9
|
-
required = authority
|
|
10
|
-
else if (Array.isArray(authority))
|
|
11
|
-
required = authority.toString()
|
|
12
|
-
else if (typeof authority === 'object')
|
|
13
|
-
required = authority.permission
|
|
14
|
-
|
|
15
|
-
return required === '*' || hasAnyItem(required, permissions, (r, t) => !!(r === t || r === t.id))
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* 判断是否有路由需要的角色
|
|
20
|
-
* @param authority 路由权限配置
|
|
21
|
-
* @param roles 用户角色集合
|
|
22
|
-
*/
|
|
23
|
-
function hasRole(authority, roles) {
|
|
24
|
-
let required
|
|
25
|
-
if (typeof authority === 'object')
|
|
26
|
-
required = authority.role
|
|
27
|
-
|
|
28
|
-
return authority === '*' || hasAnyItem(required, roles, (r, t) => !!(r === t || r === t.id))
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* 判断目标数组是否有所需元素
|
|
33
|
-
* @param {string | string[]}required 所需元素,数组或单个元素
|
|
34
|
-
* @param {string[] | object[]} source 目标数组
|
|
35
|
-
* @param {Function} filter 匹配条件
|
|
36
|
-
* (r: String, s: String|Object) => boolean
|
|
37
|
-
*/
|
|
38
|
-
function hasAnyItem(required, source, filter): boolean {
|
|
39
|
-
if (!required)
|
|
40
|
-
return false
|
|
41
|
-
|
|
42
|
-
const checkedList = Array.isArray(required) ? required : [required]
|
|
43
|
-
return !!source.find(s => checkedList.find(r => filter(r, s)))
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* 路由权限校验
|
|
48
|
-
* @param route 路由
|
|
49
|
-
* @param permissions 用户权限集合
|
|
50
|
-
* @param roles 用户角色集合
|
|
51
|
-
*/
|
|
52
|
-
function hasAuthority(route, permissions, roles) {
|
|
53
|
-
// TODO 此处判断可能有问题
|
|
54
|
-
if (!route.meta.pAuthorities)
|
|
55
|
-
return true
|
|
56
|
-
|
|
57
|
-
const authorities = [...route.meta.pAuthorities, route.meta.authority]
|
|
58
|
-
for (const authority of authorities) {
|
|
59
|
-
if (!hasPermission(authority, permissions) && !hasRole(authority, roles))
|
|
60
|
-
return false
|
|
61
|
-
}
|
|
62
|
-
return true
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 根据权限配置过滤菜单数据
|
|
67
|
-
* @param menuData
|
|
68
|
-
* @param permissions
|
|
69
|
-
* @param roles
|
|
70
|
-
*/
|
|
71
|
-
function filterMenu(menuData, permissions, roles) {
|
|
72
|
-
return menuData.filter((menu) => {
|
|
73
|
-
if (menu.meta && menu.meta.invisible === undefined) {
|
|
74
|
-
if (!hasAuthority(menu, permissions, roles))
|
|
75
|
-
return false
|
|
76
|
-
}
|
|
77
|
-
if (menu.children && menu.children.length > 0)
|
|
78
|
-
menu.children = filterMenu(menu.children, permissions, roles)
|
|
79
|
-
|
|
80
|
-
return true
|
|
81
|
-
})
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export { filterMenu, hasAuthority }
|
|
1
|
+
/**
|
|
2
|
+
* 判断是否有路由的权限
|
|
3
|
+
* @param authority 路由权限配置
|
|
4
|
+
* @param permissions 用户权限集合
|
|
5
|
+
*/
|
|
6
|
+
function hasPermission(authority: any, permissions: any): boolean {
|
|
7
|
+
let required: string = '*'
|
|
8
|
+
if (typeof authority === 'string')
|
|
9
|
+
required = authority
|
|
10
|
+
else if (Array.isArray(authority))
|
|
11
|
+
required = authority.toString()
|
|
12
|
+
else if (typeof authority === 'object')
|
|
13
|
+
required = authority.permission
|
|
14
|
+
|
|
15
|
+
return required === '*' || hasAnyItem(required, permissions, (r, t) => !!(r === t || r === t.id))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 判断是否有路由需要的角色
|
|
20
|
+
* @param authority 路由权限配置
|
|
21
|
+
* @param roles 用户角色集合
|
|
22
|
+
*/
|
|
23
|
+
function hasRole(authority, roles) {
|
|
24
|
+
let required
|
|
25
|
+
if (typeof authority === 'object')
|
|
26
|
+
required = authority.role
|
|
27
|
+
|
|
28
|
+
return authority === '*' || hasAnyItem(required, roles, (r, t) => !!(r === t || r === t.id))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 判断目标数组是否有所需元素
|
|
33
|
+
* @param {string | string[]}required 所需元素,数组或单个元素
|
|
34
|
+
* @param {string[] | object[]} source 目标数组
|
|
35
|
+
* @param {Function} filter 匹配条件
|
|
36
|
+
* (r: String, s: String|Object) => boolean
|
|
37
|
+
*/
|
|
38
|
+
function hasAnyItem(required, source, filter): boolean {
|
|
39
|
+
if (!required)
|
|
40
|
+
return false
|
|
41
|
+
|
|
42
|
+
const checkedList = Array.isArray(required) ? required : [required]
|
|
43
|
+
return !!source.find(s => checkedList.find(r => filter(r, s)))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 路由权限校验
|
|
48
|
+
* @param route 路由
|
|
49
|
+
* @param permissions 用户权限集合
|
|
50
|
+
* @param roles 用户角色集合
|
|
51
|
+
*/
|
|
52
|
+
function hasAuthority(route, permissions, roles) {
|
|
53
|
+
// TODO 此处判断可能有问题
|
|
54
|
+
if (!route.meta.pAuthorities)
|
|
55
|
+
return true
|
|
56
|
+
|
|
57
|
+
const authorities = [...route.meta.pAuthorities, route.meta.authority]
|
|
58
|
+
for (const authority of authorities) {
|
|
59
|
+
if (!hasPermission(authority, permissions) && !hasRole(authority, roles))
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
return true
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 根据权限配置过滤菜单数据
|
|
67
|
+
* @param menuData
|
|
68
|
+
* @param permissions
|
|
69
|
+
* @param roles
|
|
70
|
+
*/
|
|
71
|
+
function filterMenu(menuData, permissions, roles) {
|
|
72
|
+
return menuData.filter((menu) => {
|
|
73
|
+
if (menu.meta && menu.meta.invisible === undefined) {
|
|
74
|
+
if (!hasAuthority(menu, permissions, roles))
|
|
75
|
+
return false
|
|
76
|
+
}
|
|
77
|
+
if (menu.children && menu.children.length > 0)
|
|
78
|
+
menu.children = filterMenu(menu.children, permissions, roles)
|
|
79
|
+
|
|
80
|
+
return true
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { filterMenu, hasAuthority }
|
package/src/utils/common.ts
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import useUserStore from '@af-mobile-client-vue3/stores/modules/user'
|
|
2
|
-
|
|
3
|
-
export function hexToRgba(hex: string, opacity: number) {
|
|
4
|
-
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i
|
|
5
|
-
hex = hex.replace(shorthandRegex, (r, g, b) => {
|
|
6
|
-
return r + r + g + g + b + b
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
|
|
10
|
-
opacity = opacity >= 0 && opacity <= 1 ? Number(opacity) : 1
|
|
11
|
-
return result
|
|
12
|
-
? `rgba(${
|
|
13
|
-
[Number.parseInt(result[1], 16), Number.parseInt(result[2], 16), Number.parseInt(result[3], 16), opacity].join(
|
|
14
|
-
',',
|
|
15
|
-
)
|
|
16
|
-
})`
|
|
17
|
-
: hex
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// 引入本地图片
|
|
21
|
-
export function getImageUrl(url, prefix?): string {
|
|
22
|
-
return new URL(prefix ? prefix + url : url, import.meta.url).href
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// 获取路由属性
|
|
26
|
-
export function getFunction(link?: string): { children?: any[], link?: string, name?: string, parentId?: string, sort?: number } {
|
|
27
|
-
const FunctionPage = useUserStore().getUserInfo()?.functions?.filter((item) => {
|
|
28
|
-
return item.link === import.meta.env.VITE_APP_PUBLIC_PATH.replace('/', '')
|
|
29
|
-
})
|
|
30
|
-
if (FunctionPage?.length > 0) {
|
|
31
|
-
if (link) {
|
|
32
|
-
if (FunctionPage[0].children?.length > 0) {
|
|
33
|
-
return FunctionPage[0].children?.filter((_item) => {
|
|
34
|
-
return _item.link === link
|
|
35
|
-
})[0]
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return Object.assign({ children: [] }, FunctionPage[0])
|
|
39
|
-
}
|
|
40
|
-
return { children: [] }
|
|
41
|
-
}
|
|
1
|
+
import useUserStore from '@af-mobile-client-vue3/stores/modules/user'
|
|
2
|
+
|
|
3
|
+
export function hexToRgba(hex: string, opacity: number) {
|
|
4
|
+
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i
|
|
5
|
+
hex = hex.replace(shorthandRegex, (r, g, b) => {
|
|
6
|
+
return r + r + g + g + b + b
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
|
|
10
|
+
opacity = opacity >= 0 && opacity <= 1 ? Number(opacity) : 1
|
|
11
|
+
return result
|
|
12
|
+
? `rgba(${
|
|
13
|
+
[Number.parseInt(result[1], 16), Number.parseInt(result[2], 16), Number.parseInt(result[3], 16), opacity].join(
|
|
14
|
+
',',
|
|
15
|
+
)
|
|
16
|
+
})`
|
|
17
|
+
: hex
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// 引入本地图片
|
|
21
|
+
export function getImageUrl(url, prefix?): string {
|
|
22
|
+
return new URL(prefix ? prefix + url : url, import.meta.url).href
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 获取路由属性
|
|
26
|
+
export function getFunction(link?: string): { children?: any[], link?: string, name?: string, parentId?: string, sort?: number } {
|
|
27
|
+
const FunctionPage = useUserStore().getUserInfo()?.functions?.filter((item) => {
|
|
28
|
+
return item.link === import.meta.env.VITE_APP_PUBLIC_PATH.replace('/', '')
|
|
29
|
+
})
|
|
30
|
+
if (FunctionPage?.length > 0) {
|
|
31
|
+
if (link) {
|
|
32
|
+
if (FunctionPage[0].children?.length > 0) {
|
|
33
|
+
return FunctionPage[0].children?.filter((_item) => {
|
|
34
|
+
return _item.link === link
|
|
35
|
+
})[0]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return Object.assign({ children: [] }, FunctionPage[0])
|
|
39
|
+
}
|
|
40
|
+
return { children: [] }
|
|
41
|
+
}
|
package/src/utils/crypto.ts
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import AesEncryptJS from 'crypto-js'
|
|
2
|
-
|
|
3
|
-
export default {
|
|
4
|
-
/**
|
|
5
|
-
* AES加密
|
|
6
|
-
*
|
|
7
|
-
* @param word
|
|
8
|
-
* @param encryKey
|
|
9
|
-
*/
|
|
10
|
-
AESEncrypt(word: string, encryKey: string): string {
|
|
11
|
-
const key = AesEncryptJS.enc.Utf8.parse(encryKey)
|
|
12
|
-
const srcs = AesEncryptJS.enc.Utf8.parse(word)
|
|
13
|
-
const encrypted = AesEncryptJS.AES.encrypt(srcs, key, {
|
|
14
|
-
mode: AesEncryptJS.mode.ECB,
|
|
15
|
-
padding: AesEncryptJS.pad.Pkcs7,
|
|
16
|
-
})
|
|
17
|
-
return encrypted.toString()
|
|
18
|
-
},
|
|
19
|
-
/**
|
|
20
|
-
* AES解密
|
|
21
|
-
*
|
|
22
|
-
* @param word
|
|
23
|
-
* @param encryKey
|
|
24
|
-
*/
|
|
25
|
-
AESDecrypt(word: string, encryKey: string): any {
|
|
26
|
-
const key = AesEncryptJS.enc.Utf8.parse(encryKey)
|
|
27
|
-
const decrypt = AesEncryptJS.AES.decrypt(word, key, {
|
|
28
|
-
mode: AesEncryptJS.mode.ECB,
|
|
29
|
-
padding: AesEncryptJS.pad.Pkcs7,
|
|
30
|
-
})
|
|
31
|
-
const ret = AesEncryptJS.enc.Utf8.stringify(decrypt).toString()
|
|
32
|
-
try {
|
|
33
|
-
return JSON.parse(ret)
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
return ret
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
}
|
|
1
|
+
import AesEncryptJS from 'crypto-js'
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
/**
|
|
5
|
+
* AES加密
|
|
6
|
+
*
|
|
7
|
+
* @param word
|
|
8
|
+
* @param encryKey
|
|
9
|
+
*/
|
|
10
|
+
AESEncrypt(word: string, encryKey: string): string {
|
|
11
|
+
const key = AesEncryptJS.enc.Utf8.parse(encryKey)
|
|
12
|
+
const srcs = AesEncryptJS.enc.Utf8.parse(word)
|
|
13
|
+
const encrypted = AesEncryptJS.AES.encrypt(srcs, key, {
|
|
14
|
+
mode: AesEncryptJS.mode.ECB,
|
|
15
|
+
padding: AesEncryptJS.pad.Pkcs7,
|
|
16
|
+
})
|
|
17
|
+
return encrypted.toString()
|
|
18
|
+
},
|
|
19
|
+
/**
|
|
20
|
+
* AES解密
|
|
21
|
+
*
|
|
22
|
+
* @param word
|
|
23
|
+
* @param encryKey
|
|
24
|
+
*/
|
|
25
|
+
AESDecrypt(word: string, encryKey: string): any {
|
|
26
|
+
const key = AesEncryptJS.enc.Utf8.parse(encryKey)
|
|
27
|
+
const decrypt = AesEncryptJS.AES.decrypt(word, key, {
|
|
28
|
+
mode: AesEncryptJS.mode.ECB,
|
|
29
|
+
padding: AesEncryptJS.pad.Pkcs7,
|
|
30
|
+
})
|
|
31
|
+
const ret = AesEncryptJS.enc.Utf8.stringify(decrypt).toString()
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(ret)
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return ret
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
}
|
package/src/utils/dataUtil.ts
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 构造树型结构数据
|
|
3
|
-
* [label,value,children]
|
|
4
|
-
*/
|
|
5
|
-
export function handleTree(data: any, id?: string, parentId?: string, children?: string) {
|
|
6
|
-
const config = {
|
|
7
|
-
id: id || 'id',
|
|
8
|
-
parentId: parentId || 'parent_id',
|
|
9
|
-
childrenList: children || 'children',
|
|
10
|
-
}
|
|
11
|
-
const childrenListMap = {}
|
|
12
|
-
const nodeIds = {}
|
|
13
|
-
const tree = []
|
|
14
|
-
for (const d of data) {
|
|
15
|
-
const parentId = d[config.parentId]
|
|
16
|
-
if (childrenListMap[parentId] == null)
|
|
17
|
-
childrenListMap[parentId] = []
|
|
18
|
-
|
|
19
|
-
nodeIds[d[config.id]] = d
|
|
20
|
-
childrenListMap[parentId].push(d)
|
|
21
|
-
}
|
|
22
|
-
for (const d of data) {
|
|
23
|
-
const parentId = d[config.parentId]
|
|
24
|
-
if (nodeIds[parentId] == null)
|
|
25
|
-
tree.push(d)
|
|
26
|
-
}
|
|
27
|
-
for (const t of tree)
|
|
28
|
-
adaptToChildrenList(t)
|
|
29
|
-
|
|
30
|
-
function adaptToChildrenList(o) {
|
|
31
|
-
o.label = o.name
|
|
32
|
-
o.value = o.name
|
|
33
|
-
if (childrenListMap[o[config.id]] !== null)
|
|
34
|
-
o[config.childrenList] = childrenListMap[o[config.id]]
|
|
35
|
-
|
|
36
|
-
if (o[config.childrenList]) {
|
|
37
|
-
for (const c of o[config.childrenList])
|
|
38
|
-
adaptToChildrenList(c)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return tree
|
|
42
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 构造树型结构数据
|
|
3
|
+
* [label,value,children]
|
|
4
|
+
*/
|
|
5
|
+
export function handleTree(data: any, id?: string, parentId?: string, children?: string) {
|
|
6
|
+
const config = {
|
|
7
|
+
id: id || 'id',
|
|
8
|
+
parentId: parentId || 'parent_id',
|
|
9
|
+
childrenList: children || 'children',
|
|
10
|
+
}
|
|
11
|
+
const childrenListMap = {}
|
|
12
|
+
const nodeIds = {}
|
|
13
|
+
const tree = []
|
|
14
|
+
for (const d of data) {
|
|
15
|
+
const parentId = d[config.parentId]
|
|
16
|
+
if (childrenListMap[parentId] == null)
|
|
17
|
+
childrenListMap[parentId] = []
|
|
18
|
+
|
|
19
|
+
nodeIds[d[config.id]] = d
|
|
20
|
+
childrenListMap[parentId].push(d)
|
|
21
|
+
}
|
|
22
|
+
for (const d of data) {
|
|
23
|
+
const parentId = d[config.parentId]
|
|
24
|
+
if (nodeIds[parentId] == null)
|
|
25
|
+
tree.push(d)
|
|
26
|
+
}
|
|
27
|
+
for (const t of tree)
|
|
28
|
+
adaptToChildrenList(t)
|
|
29
|
+
|
|
30
|
+
function adaptToChildrenList(o) {
|
|
31
|
+
o.label = o.name
|
|
32
|
+
o.value = o.name
|
|
33
|
+
if (childrenListMap[o[config.id]] !== null)
|
|
34
|
+
o[config.childrenList] = childrenListMap[o[config.id]]
|
|
35
|
+
|
|
36
|
+
if (o[config.childrenList]) {
|
|
37
|
+
for (const c of o[config.childrenList])
|
|
38
|
+
adaptToChildrenList(c)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return tree
|
|
42
|
+
}
|