af-mobile-client-vue3 1.0.94 → 1.0.96
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/.env +6 -6
- package/.env.development +4 -4
- package/.env.envoiceShow +6 -6
- package/.env.production +6 -6
- package/.husky/commit-msg +1 -1
- package/.husky/pre-commit +1 -1
- package/.vscode/settings.json +61 -61
- package/build/vite/index.ts +91 -91
- package/eslint.config.js +9 -1
- package/mock/modules/user.mock.ts +152 -152
- package/package.json +1 -1
- package/public/favicon.svg +4 -4
- package/public/safari-pinned-tab.svg +32 -32
- package/scripts/verifyCommit.js +19 -19
- package/src/App.vue +43 -43
- package/src/api/user/index.ts +40 -40
- package/src/bootstrap.ts +18 -18
- package/src/components/core/App/MicroAppView.vue +3 -3
- package/src/components/core/NavBar/index.vue +12 -12
- package/src/components/core/SvgIcon/index.vue +1 -1
- package/src/components/core/Tabbar/index.vue +38 -38
- package/src/components/core/Uploader/index.vue +1 -1
- package/src/components/core/XGridDropOption/index.vue +151 -151
- package/src/components/core/XMultiSelect/index.vue +183 -183
- package/src/components/data/XCellDetail/index.vue +106 -106
- package/src/components/data/XCellList/XCellList.md +28 -28
- package/src/components/data/XCellList/index.vue +50 -11
- package/src/components/data/XCellListFilter/QrScanner/index.vue +1 -1
- package/src/components/data/XCellListFilter/VpnRecognition/index.vue +3 -3
- package/src/components/data/XCellListFilter/index.vue +160 -62
- package/src/components/data/XForm/index.vue +2 -2
- package/src/components/data/XFormGroup/index.vue +3 -3
- package/src/components/data/XFormItem/index.vue +25 -26
- package/src/components/data/XOlMap/demo.vue +209 -0
- package/src/components/data/XOlMap/index.vue +644 -0
- package/src/components/data/XReportForm/XReportFormJsonRender.vue +220 -220
- package/src/components/data/XReportForm/index.vue +1079 -1079
- package/src/components/data/XReportGrid/XAddReport/XAddReport.vue +4 -7
- package/src/components/data/XReportGrid/XAddReport/index.md +3 -7
- package/src/components/data/XReportGrid/XAddReport/index.ts +2 -2
- package/src/components/data/XReportGrid/XReport.vue +25 -38
- package/src/components/data/XReportGrid/XReportDesign.vue +46 -46
- package/src/components/data/XReportGrid/XReportDrawer/XReportDrawer.vue +3 -3
- package/src/components/data/XReportGrid/XReportDrawer/index.ts +2 -2
- package/src/components/data/XReportGrid/XReportJsonRender.vue +20 -7
- package/src/components/data/XReportGrid/XReportTrGroup.vue +4 -4
- package/src/components/data/XReportGrid/index.md +4 -6
- package/src/components/data/XSignature/index.vue +285 -285
- package/src/components/data/XTag/index.vue +10 -10
- package/src/components/layout/NormalDataLayout/index.vue +70 -70
- package/src/components/layout/TabBarLayout/index.vue +40 -40
- package/src/components.d.ts +53 -53
- package/src/env.d.ts +16 -16
- package/src/font-style/font.css +3 -3
- package/src/hooks/useCommon.ts +9 -9
- package/src/layout/GridView/index.vue +1 -1
- package/src/layout/PageLayout.vue +5 -5
- package/src/layout/SingleLayout.vue +3 -3
- package/src/locales/en-US.json +25 -25
- package/src/locales/zh-CN.json +25 -25
- package/src/plugins/AppData.ts +38 -38
- package/src/plugins/index.ts +1 -1
- package/src/router/guards.ts +59 -59
- package/src/router/index.ts +61 -60
- package/src/router/invoiceRoutes.ts +33 -33
- package/src/router/routes.ts +20 -14
- package/src/services/api/common.ts +109 -109
- package/src/services/api/manage.ts +8 -8
- package/src/services/restTools.ts +52 -52
- package/src/services/v3Api.ts +46 -35
- package/src/stores/modules/cachedView.ts +1 -1
- package/src/stores/modules/setting.ts +52 -52
- package/src/stores/modules/user.ts +5 -5
- package/src/stores/mutation-type.ts +7 -7
- package/src/styles/app.less +6 -1
- package/src/utils/Storage.ts +1 -1
- package/src/utils/authority-utils.ts +84 -84
- package/src/utils/crypto.ts +39 -39
- package/src/utils/http/index.ts +6 -6
- package/src/utils/i18n.ts +41 -41
- package/src/utils/indexedDB.ts +180 -180
- package/src/utils/mobileUtil.ts +26 -26
- package/src/utils/routerUtil.ts +271 -271
- package/src/utils/runEvalFunction.ts +13 -13
- package/src/utils/validate.ts +1 -1
- package/src/utils/wechatUtil.ts +9 -9
- package/src/views/chat/index.vue +1 -1
- package/src/views/common/LoadError.vue +64 -64
- package/src/views/common/NotFound.vue +68 -68
- package/src/views/component/EvaluateRecordView/index.vue +40 -40
- package/src/views/component/XCellDetailView/index.vue +217 -216
- package/src/views/component/XCellListView/index.vue +1 -1
- package/src/views/component/XFormAppraiseView/index.vue +4 -4
- package/src/views/component/XFormGroupView/index.vue +1 -1
- package/src/views/component/XFormView/index.vue +6 -7
- 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 +2 -3
- package/src/views/component/XSignatureView/index.vue +50 -50
- package/src/views/component/index.vue +4 -4
- 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/invoiceShow/index.vue +61 -62
- package/src/views/user/login/ForgetPasswordForm.vue +94 -93
- package/src/views/user/login/LoginForm.vue +8 -7
- package/src/views/user/login/LoginTitle.vue +68 -68
- package/src/views/user/login/index.vue +22 -22
- package/src/views/user/my/index.vue +230 -230
- package/src/vue-router.d.ts +9 -9
- package/tsconfig.json +43 -43
- package/uno.config.ts +1 -1
- package/vite.config.ts +123 -123
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* GET请求
|
|
6
|
-
* @param url 请求地址
|
|
7
|
-
* @param params 路径参数
|
|
8
|
-
*/
|
|
9
|
-
export function get(url: string, params?: any) {
|
|
10
|
-
return http.request<BasicResponseModel>({
|
|
11
|
-
url,
|
|
12
|
-
method: 'GET',
|
|
13
|
-
params,
|
|
14
|
-
})
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* POST请求
|
|
19
|
-
* @param url 请求地址
|
|
20
|
-
* @param data 请求参数
|
|
21
|
-
*/
|
|
22
|
-
export function post(url: string, data: any) {
|
|
23
|
-
return http.request<BasicResponseModel>({
|
|
24
|
-
url,
|
|
25
|
-
method: 'POST',
|
|
26
|
-
data,
|
|
27
|
-
})
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function postWithConfig(url: string, data: any, config: any) {
|
|
31
|
-
return http.request<BasicResponseModel>({
|
|
32
|
-
url,
|
|
33
|
-
method: 'POST',
|
|
34
|
-
data,
|
|
35
|
-
headers: { ...config },
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* DELETE请求
|
|
41
|
-
* @param url 请求地址
|
|
42
|
-
* @param data 查询参数
|
|
43
|
-
* @param config 额外的配置项(如自定义头信息等)
|
|
44
|
-
*/
|
|
45
|
-
export function del(url: string, data?: any, config?: any) {
|
|
46
|
-
return http.request<BasicResponseModel>({
|
|
47
|
-
url,
|
|
48
|
-
method: 'DELETE',
|
|
49
|
-
data,
|
|
50
|
-
...config,
|
|
51
|
-
})
|
|
52
|
-
}
|
|
1
|
+
import type { BasicResponseModel } from '@af-mobile-client-vue3/api/user'
|
|
2
|
+
import { http } from '@af-mobile-client-vue3/utils/http'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* GET请求
|
|
6
|
+
* @param url 请求地址
|
|
7
|
+
* @param params 路径参数
|
|
8
|
+
*/
|
|
9
|
+
export function get(url: string, params?: any) {
|
|
10
|
+
return http.request<BasicResponseModel>({
|
|
11
|
+
url,
|
|
12
|
+
method: 'GET',
|
|
13
|
+
params,
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* POST请求
|
|
19
|
+
* @param url 请求地址
|
|
20
|
+
* @param data 请求参数
|
|
21
|
+
*/
|
|
22
|
+
export function post(url: string, data: any) {
|
|
23
|
+
return http.request<BasicResponseModel>({
|
|
24
|
+
url,
|
|
25
|
+
method: 'POST',
|
|
26
|
+
data,
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function postWithConfig(url: string, data: any, config: any) {
|
|
31
|
+
return http.request<BasicResponseModel>({
|
|
32
|
+
url,
|
|
33
|
+
method: 'POST',
|
|
34
|
+
data,
|
|
35
|
+
headers: { ...config },
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* DELETE请求
|
|
41
|
+
* @param url 请求地址
|
|
42
|
+
* @param data 查询参数
|
|
43
|
+
* @param config 额外的配置项(如自定义头信息等)
|
|
44
|
+
*/
|
|
45
|
+
export function del(url: string, data?: any, config?: any) {
|
|
46
|
+
return http.request<BasicResponseModel>({
|
|
47
|
+
url,
|
|
48
|
+
method: 'DELETE',
|
|
49
|
+
data,
|
|
50
|
+
...config,
|
|
51
|
+
})
|
|
52
|
+
}
|
package/src/services/v3Api.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { METHOD, request } from '@af-mobile-client-vue3/utils/http/index'
|
|
2
1
|
import { runLogic } from '@af-mobile-client-vue3/services/api/common'
|
|
2
|
+
import { METHOD, request } from '@af-mobile-client-vue3/utils/http/index'
|
|
3
3
|
|
|
4
|
-
function getLeafNodes
|
|
5
|
-
|
|
4
|
+
function getLeafNodes(nodes) {
|
|
5
|
+
// console.log(nodes)
|
|
6
6
|
// 确保 nodes 是数组
|
|
7
7
|
const nodeArray = Array.isArray(nodes) ? nodes : [nodes]
|
|
8
8
|
return nodeArray.reduce((leaves, node) => {
|
|
9
9
|
if (node.children && node.children.length) {
|
|
10
10
|
// 递归处理子节点并合并结果
|
|
11
11
|
leaves.push(...getLeafNodes(node.children))
|
|
12
|
-
}
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
13
14
|
// 当前节点是叶子节点时,直接加入结果
|
|
14
15
|
leaves.push(node)
|
|
15
16
|
}
|
|
@@ -17,7 +18,7 @@ function getLeafNodes (nodes) {
|
|
|
17
18
|
}, [])
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
function getLeafNodesByCondition
|
|
21
|
+
function getLeafNodesByCondition(type, nodes, parent = null) {
|
|
21
22
|
// console.log('nodes------',nodes)
|
|
22
23
|
// 确保 nodes 是数组
|
|
23
24
|
const nodeArray = Array.isArray(nodes) ? nodes : [nodes]
|
|
@@ -44,27 +45,29 @@ function getLeafNodesByCondition (type, nodes, parent = null) {
|
|
|
44
45
|
}
|
|
45
46
|
// 递归处理子节点
|
|
46
47
|
leaves.push(...getLeafNodesByCondition(type, node.children, updatedParent))
|
|
47
|
-
}
|
|
48
|
+
}
|
|
49
|
+
else if (isValidNode) {
|
|
48
50
|
// 无子节点但符合条件时,直接加入叶子节点列表
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
}
|
|
51
|
+
if (node.resourcetype === 'organization') {
|
|
52
|
+
leaves.push({
|
|
53
|
+
...node,
|
|
54
|
+
name: parent ? `${node.name}-${parent}` : node.name,
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
else if (node.resourcetype === 'department' && !nodeArray.includes(node.name)) {
|
|
58
|
+
// console.log('数组',nodeArray.includes(node.name))
|
|
59
|
+
leaves.push({
|
|
60
|
+
...node,
|
|
61
|
+
name: parent ? `${node.name}-${parent}` : node.name,
|
|
62
|
+
})
|
|
61
63
|
}
|
|
64
|
+
}
|
|
62
65
|
return leaves
|
|
63
66
|
}, [])
|
|
64
67
|
}
|
|
65
68
|
|
|
66
|
-
function transformData
|
|
67
|
-
function transform
|
|
69
|
+
function transformData(inputData) {
|
|
70
|
+
function transform(node) {
|
|
68
71
|
return {
|
|
69
72
|
label: node.name,
|
|
70
73
|
value: node.id,
|
|
@@ -72,41 +75,48 @@ function transformData (inputData) {
|
|
|
72
75
|
f_department_id: node.f_department_id,
|
|
73
76
|
parentid: node.parentid,
|
|
74
77
|
orgid: node.orgid,
|
|
75
|
-
children: node.children ? node.children.map(transform) : []
|
|
78
|
+
children: node.children ? node.children.map(transform) : [],
|
|
76
79
|
}
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
return inputData.map(transform)
|
|
80
83
|
}
|
|
81
84
|
|
|
82
|
-
function getResData
|
|
85
|
+
function getResData(params, toCallback) {
|
|
83
86
|
const data = { userId: params.userid, roleName: params.roleName }
|
|
84
87
|
if (params.source === '获取分公司') {
|
|
85
88
|
runLogic('getOrgBySearch', data, 'af-system').then(res => toCallback(res))
|
|
86
|
-
}
|
|
89
|
+
}
|
|
90
|
+
else if (params.source === '获取部门') {
|
|
87
91
|
runLogic('getDepBySearch', data, 'af-system').then(res => toCallback(res))
|
|
88
|
-
}
|
|
92
|
+
}
|
|
93
|
+
else if (params.source === '获取人员') {
|
|
89
94
|
runLogic('getUserBySearch', data, 'af-system').then(res => toCallback(res))
|
|
90
|
-
}
|
|
95
|
+
}
|
|
96
|
+
else if (params.source === '根据角色获取人员') {
|
|
91
97
|
runLogic('getUserBySearchRole', data, 'af-system').then(res => toCallback(res))
|
|
92
|
-
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
93
100
|
return search(params).then(res => toCallback(res))
|
|
94
101
|
}
|
|
95
102
|
}
|
|
96
103
|
|
|
97
|
-
export async function searchToOption
|
|
98
|
-
function toCallback
|
|
104
|
+
export async function searchToOption(params, callback) {
|
|
105
|
+
function toCallback(res) {
|
|
99
106
|
if (res.length) {
|
|
100
107
|
if (res[0].children && res[0].children.length) {
|
|
101
108
|
if (res[0].children[0].children) {
|
|
102
109
|
callback(transformData(res[0].children[0].children))
|
|
103
|
-
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
104
112
|
callback(transformData(res[0].children))
|
|
105
113
|
}
|
|
106
|
-
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
107
116
|
callback(res[0].children)
|
|
108
117
|
}
|
|
109
|
-
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
110
120
|
callback(res)
|
|
111
121
|
}
|
|
112
122
|
}
|
|
@@ -114,12 +124,13 @@ export async function searchToOption (params, callback) {
|
|
|
114
124
|
await getResData(params, toCallback)
|
|
115
125
|
}
|
|
116
126
|
|
|
117
|
-
export async function searchToListOption
|
|
118
|
-
function toCallback
|
|
127
|
+
export async function searchToListOption(params, callback) {
|
|
128
|
+
function toCallback(res) {
|
|
119
129
|
if (params.source.includes('人员')) {
|
|
120
130
|
// console.log('ren---------',res)
|
|
121
131
|
callback(transformData(getLeafNodes(res)))
|
|
122
|
-
}
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
123
134
|
const type = params.source.includes('公司') ? 'organization' : 'department'
|
|
124
135
|
// console.log('bumenpgonngsi',res)
|
|
125
136
|
callback(transformData(getLeafNodesByCondition(type, res)))
|
|
@@ -129,7 +140,7 @@ export async function searchToListOption (params, callback) {
|
|
|
129
140
|
await getResData(params, toCallback)
|
|
130
141
|
}
|
|
131
142
|
|
|
132
|
-
export async function search
|
|
143
|
+
export async function search(params) {
|
|
133
144
|
return request('/rs/search', METHOD.POST, params, params.config)
|
|
134
145
|
}
|
|
135
146
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { toRouteType } from '@af-mobile-client-vue3/router'
|
|
1
2
|
import { defineStore } from 'pinia'
|
|
2
3
|
import { ref } from 'vue'
|
|
3
|
-
import type { toRouteType } from '@af-mobile-client-vue3/router'
|
|
4
4
|
|
|
5
5
|
const useCachedViewStore = defineStore('cached-view', () => {
|
|
6
6
|
// 缓存页面 keepAlive
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
export interface WebConfig {
|
|
8
|
-
systemName: string
|
|
9
|
-
routerName: string
|
|
10
|
-
systemDesc: string
|
|
11
|
-
homePage: string
|
|
12
|
-
defaultAvatarUrl: string
|
|
13
|
-
wechatLogin: boolean
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// 存放 webConfig 中的 setting 配置
|
|
17
|
-
export const useSettingStore = defineStore('setting', () => {
|
|
18
|
-
const setting = ref<WebConfig>(undefined)
|
|
19
|
-
const setSetting = (newSetting: WebConfig) => {
|
|
20
|
-
setting.value = newSetting
|
|
21
|
-
}
|
|
22
|
-
const getSetting = () => {
|
|
23
|
-
return setting.value
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const useStore = createStorage()
|
|
27
|
-
|
|
28
|
-
const store = useSettingStore()
|
|
29
|
-
|
|
30
|
-
const init = async () => {
|
|
31
|
-
const catchWebConfig = useStore.get(APP_WEB_CONFIG_KEY)
|
|
32
|
-
if (catchWebConfig) {
|
|
33
|
-
setSetting(catchWebConfig)
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
const res = await getConfigByNameAsync('webMobileConfig')
|
|
37
|
-
useStore.set(APP_WEB_CONFIG_KEY, res)
|
|
38
|
-
const setting: WebConfig = res.setting
|
|
39
|
-
if (setting)
|
|
40
|
-
store.setSetting(setting)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
init().then(() => {})
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
setSetting,
|
|
48
|
-
getSetting,
|
|
49
|
-
}
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
export default useSettingStore
|
|
1
|
+
import { getConfigByNameAsync } from '@af-mobile-client-vue3/services/api/common'
|
|
2
|
+
import { APP_WEB_CONFIG_KEY } from '@af-mobile-client-vue3/stores/mutation-type'
|
|
3
|
+
import { createStorage } from '@af-mobile-client-vue3/utils/Storage'
|
|
4
|
+
import { defineStore } from 'pinia'
|
|
5
|
+
import { ref } from 'vue'
|
|
6
|
+
|
|
7
|
+
export interface WebConfig {
|
|
8
|
+
systemName: string
|
|
9
|
+
routerName: string
|
|
10
|
+
systemDesc: string
|
|
11
|
+
homePage: string
|
|
12
|
+
defaultAvatarUrl: string
|
|
13
|
+
wechatLogin: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 存放 webConfig 中的 setting 配置
|
|
17
|
+
export const useSettingStore = defineStore('setting', () => {
|
|
18
|
+
const setting = ref<WebConfig>(undefined)
|
|
19
|
+
const setSetting = (newSetting: WebConfig) => {
|
|
20
|
+
setting.value = newSetting
|
|
21
|
+
}
|
|
22
|
+
const getSetting = () => {
|
|
23
|
+
return setting.value
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const useStore = createStorage()
|
|
27
|
+
|
|
28
|
+
const store = useSettingStore()
|
|
29
|
+
|
|
30
|
+
const init = async () => {
|
|
31
|
+
const catchWebConfig = useStore.get(APP_WEB_CONFIG_KEY)
|
|
32
|
+
if (catchWebConfig) {
|
|
33
|
+
setSetting(catchWebConfig)
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const res = await getConfigByNameAsync('webMobileConfig')
|
|
37
|
+
useStore.set(APP_WEB_CONFIG_KEY, res)
|
|
38
|
+
const setting: WebConfig = res.setting
|
|
39
|
+
if (setting)
|
|
40
|
+
store.setSetting(setting)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
init().then(() => {})
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
setSetting,
|
|
48
|
+
getSetting,
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
export default useSettingStore
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { defineStore } from 'pinia'
|
|
2
|
-
import { ref } from 'vue'
|
|
3
1
|
import type { RouteRecordRaw } from 'vue-router'
|
|
4
|
-
import {
|
|
2
|
+
import { doLogout, login, OALogin } from '@af-mobile-client-vue3/api/user'
|
|
3
|
+
import router from '@af-mobile-client-vue3/router/index'
|
|
5
4
|
import {
|
|
6
5
|
ACCESS_TOKEN,
|
|
7
6
|
APP_LOGIN_KEY,
|
|
@@ -10,9 +9,10 @@ import {
|
|
|
10
9
|
APP_ROUTES_KEY,
|
|
11
10
|
CURRENT_USER,
|
|
12
11
|
} from '@af-mobile-client-vue3/stores/mutation-type'
|
|
13
|
-
import { OALogin, doLogout, login } from '@af-mobile-client-vue3/api/user'
|
|
14
12
|
import crypto from '@af-mobile-client-vue3/utils/crypto'
|
|
15
|
-
import
|
|
13
|
+
import { createStorage } from '@af-mobile-client-vue3/utils/Storage'
|
|
14
|
+
import { defineStore } from 'pinia'
|
|
15
|
+
import { ref } from 'vue'
|
|
16
16
|
|
|
17
17
|
const Storage = createStorage({ storage: localStorage })
|
|
18
18
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export const CURRENT_USER = 'CURRENT-USER'
|
|
2
|
-
export const ACCESS_TOKEN = 'Authorization'
|
|
3
|
-
export const APP_LOGIN_KEY = 'admin.login'
|
|
4
|
-
export const APP_PERMISSIONS_KEY = 'admin.permissions'
|
|
5
|
-
export const APP_ROLES_KEY = 'admin.roles'
|
|
6
|
-
export const APP_ROUTES_KEY = 'admin.routes'
|
|
7
|
-
export const APP_WEB_CONFIG_KEY = 'admin.webconfig'
|
|
1
|
+
export const CURRENT_USER = 'CURRENT-USER'
|
|
2
|
+
export const ACCESS_TOKEN = 'Authorization'
|
|
3
|
+
export const APP_LOGIN_KEY = 'admin.login'
|
|
4
|
+
export const APP_PERMISSIONS_KEY = 'admin.permissions'
|
|
5
|
+
export const APP_ROLES_KEY = 'admin.roles'
|
|
6
|
+
export const APP_ROUTES_KEY = 'admin.routes'
|
|
7
|
+
export const APP_WEB_CONFIG_KEY = 'admin.webconfig'
|
package/src/styles/app.less
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
--base-interval-2: 28px;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
:root:root {
|
|
8
|
+
// 覆盖 primary 颜色
|
|
9
|
+
--van-blue: #2563EB;
|
|
10
|
+
}
|
|
11
|
+
|
|
7
12
|
#system-app {
|
|
8
13
|
min-height: 100vh;
|
|
9
14
|
position: relative;
|
|
@@ -11,7 +16,7 @@
|
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
html {
|
|
14
|
-
background: var(--van-
|
|
19
|
+
background: var(--van-gray-1);
|
|
15
20
|
color-scheme: light;
|
|
16
21
|
}
|
|
17
22
|
|
package/src/utils/Storage.ts
CHANGED
|
@@ -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 }
|