af-mobile-client-vue3 1.2.15 → 1.2.16

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/package.json CHANGED
@@ -1,113 +1,113 @@
1
- {
2
- "name": "af-mobile-client-vue3",
3
- "type": "module",
4
- "version": "1.2.15",
5
- "packageManager": "pnpm@10.12.3",
6
- "description": "Vue + Vite component lib",
7
- "engines": {
8
- "node": ">=20.19.0"
9
- },
10
- "scripts": {
11
- "dev": "cross-env MOCK_SERVER_PORT=8086 vite",
12
- "build": "vue-tsc --noEmit && vite build",
13
- "build:dev": "vue-tsc --noEmit && vite build --mode=development",
14
- "preview": "vite preview",
15
- "lint": "eslint . && vue-tsc --noEmit",
16
- "lint:fix": "eslint . --fix",
17
- "release": "bumpp --commit --push --tag",
18
- "typecheck": "vue-tsc --noEmit",
19
- "commitlint": "commitlint --edit",
20
- "prepare": "simple-git-hooks"
21
- },
22
- "dependencies": {
23
- "@vant/area-data": "^2.0.0",
24
- "crypto-js": "^4.2.0",
25
- "dayjs": "^1.11.13",
26
- "ol": "^10.5.0",
27
- "vue3-hash-calendar": "^1.1.3",
28
- "@iconify/vue": "4.3.0",
29
- "@micro-zoe/micro-app": "1.0.0-rc.24",
30
- "@unhead/vue": "2.0.11",
31
- "@vant/touch-emulator": "^1.4.0",
32
- "@vant/use": "^1.6.0",
33
- "@vueuse/core": "^13.4.0",
34
- "axios": "^1.10.0",
35
- "echarts": "^5.6.0",
36
- "lodash-es": "^4.17.21",
37
- "nprogress": "^0.2.0",
38
- "pinia": "^3.0.3",
39
- "pinia-plugin-persistedstate": "^4.3.0",
40
- "resize-detector": "^0.3.0",
41
- "vant": "^4.9.20",
42
- "vconsole": "^3.15.1",
43
- "vue": "^3.5.17",
44
- "vue-i18n": "^11.1.7",
45
- "vue-router": "^4.5.1"
46
- },
47
- "devDependencies": {
48
- "vite-plugin-compression": "^0.5.1",
49
- "@iconify/json": "2.2.318",
50
- "@types/crypto-js": "^4.2.2",
51
- "@antfu/eslint-config": "4.16.1",
52
- "@commitlint/cli": "^19.8.1",
53
- "@commitlint/config-conventional": "^19.8.1",
54
- "@commitlint/types": "^19.8.1",
55
- "@intlify/unplugin-vue-i18n": "^6.0.8",
56
- "@types/lodash-es": "^4.17.12",
57
- "@types/node": "^24.0.4",
58
- "@types/nprogress": "^0.2.3",
59
- "@unocss/eslint-config": "66.2.3",
60
- "@vitejs/plugin-legacy": "^7.0.0",
61
- "@vitejs/plugin-vue": "^6.0.0",
62
- "autoprefixer": "^10.4.21",
63
- "bumpp": "^10.2.0",
64
- "consola": "^3.4.2",
65
- "cross-env": "^7.0.3",
66
- "eslint": "^9.29.0",
67
- "eslint-plugin-format": "^1.0.1",
68
- "less": "^4.3.0",
69
- "lint-staged": "^16.1.2",
70
- "mockjs": "^1.1.0",
71
- "postcss-mobile-forever": "^5.0.0",
72
- "rollup": "^4.44.0",
73
- "simple-git-hooks": "^2.13.0",
74
- "terser": "^5.43.1",
75
- "typescript": "^5.8.3",
76
- "unocss": "66.2.3",
77
- "vite": "^7.0.0",
78
- "vite-plugin-mock-dev-server": "^1.9.1",
79
- "vite-plugin-pwa": "^1.0.0",
80
- "vite-plugin-sitemap": "^0.8.2",
81
- "vite-plugin-vconsole": "^2.1.1",
82
- "vite-plugin-vue-devtools": "^7.7.7",
83
- "vue-tsc": "^2.2.10"
84
- },
85
- "pnpm": {
86
- "allowedDeprecatedVersions": {
87
- "glob": "7.2.3",
88
- "inflight": "1.0.6",
89
- "sourcemap-codec": "1.4.8"
90
- },
91
- "peerDependencyRules": {
92
- "allowedVersions": {
93
- "typescript": "5.8.3"
94
- }
95
- },
96
- "onlyBuiltDependencies": [
97
- "core-js",
98
- "esbuild",
99
- "simple-git-hooks",
100
- "unrs-resolver"
101
- ]
102
- },
103
- "resolutions": {
104
- "vite": "^7.0.0"
105
- },
106
- "simple-git-hooks": {
107
- "pre-commit": "pnpm lint-staged",
108
- "commit-msg": "pnpm commitlint $1"
109
- },
110
- "lint-staged": {
111
- "*": "eslint --fix"
112
- }
113
- }
1
+ {
2
+ "name": "af-mobile-client-vue3",
3
+ "type": "module",
4
+ "version": "1.2.16",
5
+ "packageManager": "pnpm@10.12.3",
6
+ "description": "Vue + Vite component lib",
7
+ "engines": {
8
+ "node": ">=20.19.0"
9
+ },
10
+ "scripts": {
11
+ "dev": "cross-env MOCK_SERVER_PORT=8086 vite",
12
+ "build": "vue-tsc --noEmit && vite build",
13
+ "build:dev": "vue-tsc --noEmit && vite build --mode=development",
14
+ "preview": "vite preview",
15
+ "lint": "eslint . && vue-tsc --noEmit",
16
+ "lint:fix": "eslint . --fix",
17
+ "release": "bumpp --commit --push --tag",
18
+ "typecheck": "vue-tsc --noEmit",
19
+ "commitlint": "commitlint --edit",
20
+ "prepare": "simple-git-hooks"
21
+ },
22
+ "dependencies": {
23
+ "@vant/area-data": "^2.0.0",
24
+ "crypto-js": "^4.2.0",
25
+ "dayjs": "^1.11.13",
26
+ "ol": "^10.5.0",
27
+ "vue3-hash-calendar": "^1.1.3",
28
+ "@iconify/vue": "4.3.0",
29
+ "@micro-zoe/micro-app": "1.0.0-rc.24",
30
+ "@unhead/vue": "2.0.11",
31
+ "@vant/touch-emulator": "^1.4.0",
32
+ "@vant/use": "^1.6.0",
33
+ "@vueuse/core": "^13.4.0",
34
+ "axios": "^1.10.0",
35
+ "echarts": "^5.6.0",
36
+ "lodash-es": "^4.17.21",
37
+ "nprogress": "^0.2.0",
38
+ "pinia": "^3.0.3",
39
+ "pinia-plugin-persistedstate": "^4.3.0",
40
+ "resize-detector": "^0.3.0",
41
+ "vant": "^4.9.20",
42
+ "vconsole": "^3.15.1",
43
+ "vue": "^3.5.17",
44
+ "vue-i18n": "^11.1.7",
45
+ "vue-router": "^4.5.1"
46
+ },
47
+ "devDependencies": {
48
+ "vite-plugin-compression": "^0.5.1",
49
+ "@iconify/json": "2.2.318",
50
+ "@types/crypto-js": "^4.2.2",
51
+ "@antfu/eslint-config": "4.16.1",
52
+ "@commitlint/cli": "^19.8.1",
53
+ "@commitlint/config-conventional": "^19.8.1",
54
+ "@commitlint/types": "^19.8.1",
55
+ "@intlify/unplugin-vue-i18n": "^6.0.8",
56
+ "@types/lodash-es": "^4.17.12",
57
+ "@types/node": "^24.0.4",
58
+ "@types/nprogress": "^0.2.3",
59
+ "@unocss/eslint-config": "66.2.3",
60
+ "@vitejs/plugin-legacy": "^7.0.0",
61
+ "@vitejs/plugin-vue": "^6.0.0",
62
+ "autoprefixer": "^10.4.21",
63
+ "bumpp": "^10.2.0",
64
+ "consola": "^3.4.2",
65
+ "cross-env": "^7.0.3",
66
+ "eslint": "^9.29.0",
67
+ "eslint-plugin-format": "^1.0.1",
68
+ "less": "^4.3.0",
69
+ "lint-staged": "^16.1.2",
70
+ "mockjs": "^1.1.0",
71
+ "postcss-mobile-forever": "^5.0.0",
72
+ "rollup": "^4.44.0",
73
+ "simple-git-hooks": "^2.13.0",
74
+ "terser": "^5.43.1",
75
+ "typescript": "^5.8.3",
76
+ "unocss": "66.2.3",
77
+ "vite": "^7.0.0",
78
+ "vite-plugin-mock-dev-server": "^1.9.1",
79
+ "vite-plugin-pwa": "^1.0.0",
80
+ "vite-plugin-sitemap": "^0.8.2",
81
+ "vite-plugin-vconsole": "^2.1.1",
82
+ "vite-plugin-vue-devtools": "^7.7.7",
83
+ "vue-tsc": "^2.2.10"
84
+ },
85
+ "pnpm": {
86
+ "allowedDeprecatedVersions": {
87
+ "glob": "7.2.3",
88
+ "inflight": "1.0.6",
89
+ "sourcemap-codec": "1.4.8"
90
+ },
91
+ "peerDependencyRules": {
92
+ "allowedVersions": {
93
+ "typescript": "5.8.3"
94
+ }
95
+ },
96
+ "onlyBuiltDependencies": [
97
+ "core-js",
98
+ "esbuild",
99
+ "simple-git-hooks",
100
+ "unrs-resolver"
101
+ ]
102
+ },
103
+ "resolutions": {
104
+ "vite": "^7.0.0"
105
+ },
106
+ "simple-git-hooks": {
107
+ "pre-commit": "pnpm lint-staged",
108
+ "commit-msg": "pnpm commitlint $1"
109
+ },
110
+ "lint-staged": {
111
+ "*": "eslint --fix"
112
+ }
113
+ }
@@ -1,40 +1,40 @@
1
- import { loginApi } from '@af-mobile-client-vue3/services/api/Login'
2
-
3
- import { get, post } from '@af-mobile-client-vue3/services/restTools'
4
- import { http } from '@af-mobile-client-vue3/utils/http'
5
-
6
- export interface BasicResponseModel<T = any> {
7
- code: number
8
- msg: string
9
- data: T
10
- }
11
-
12
- export function login(data: any) {
13
- return post(
14
- loginApi.Login,
15
- data,
16
- )
17
- }
18
-
19
- export function OALogin(data: any) {
20
- return get(`/af-system/user/${data.username}/${data.password}/智慧OA`)
21
- }
22
-
23
- /**
24
- * @description: 获取用户信息
25
- */
26
- export function getUserInfo() {
27
- return get(
28
- '/getUserInfo',
29
- )
30
- }
31
-
32
- /**
33
- * @description: 用户登出
34
- */
35
- export function doLogout() {
36
- return http.request({
37
- url: loginApi.Logout,
38
- method: 'DELETE',
39
- })
40
- }
1
+ import { loginApi } from '@af-mobile-client-vue3/services/api/Login'
2
+
3
+ import { get, post } from '@af-mobile-client-vue3/services/restTools'
4
+ import { http } from '@af-mobile-client-vue3/utils/http'
5
+
6
+ export interface BasicResponseModel<T = any> {
7
+ code: number
8
+ msg: string
9
+ data: T
10
+ }
11
+
12
+ export function login(data: any) {
13
+ return post(
14
+ loginApi.Login,
15
+ data,
16
+ )
17
+ }
18
+
19
+ export function OALogin(data: any) {
20
+ return get(`/af-system/user/${data.username}/${data.password}/智慧OA`)
21
+ }
22
+
23
+ /**
24
+ * @description: 获取用户信息
25
+ */
26
+ export function getUserInfo() {
27
+ return get(
28
+ '/getUserInfo',
29
+ )
30
+ }
31
+
32
+ /**
33
+ * @description: 用户登出
34
+ */
35
+ export function doLogout() {
36
+ return http.request({
37
+ url: loginApi.Logout,
38
+ method: 'DELETE',
39
+ })
40
+ }
@@ -141,6 +141,9 @@ const buttonState = ref(undefined)
141
141
  const groupFormItems = ref({})
142
142
  const title = ref('')
143
143
 
144
+ // 按钮权限
145
+ const buttonPermissions = ref([])
146
+
144
147
  const slots = useSlots()
145
148
 
146
149
  // 当前组件实例(不推荐使用,可能会在后续的版本更迭中调整,暂时用来绑定函数的上下文)
@@ -202,9 +205,10 @@ function initComponent() {
202
205
 
203
206
  if (result.buttonState) {
204
207
  buttonState.value = result.buttonState
205
- if (buttonState.value.edit && buttonState.value.edit === true)
208
+ buttonPermissions.value = result.buttonPermissions
209
+ if (buttonState.value.edit && buttonState.value.edit === true && (filterButtonPermissions('edit').state === false || ((filterButtonPermissions('edit').state === true && userState.f.resources.f_role_name.includes((filterButtonPermissions('edit').roleStr))))))
206
210
  allActions.value.push({ text: '修改', func: 'updateRow' })
207
- if (buttonState.value.delete && buttonState.value.delete === true)
211
+ if (buttonState.value.delete && buttonState.value.delete === true && (filterButtonPermissions('delete').state === false || ((filterButtonPermissions('delete').state === true && userState.f.resources.f_role_name.includes((filterButtonPermissions('delete').roleStr))))))
208
212
  allActions.value.push({ text: '删除', func: 'deleteRow' })
209
213
  }
210
214
  splitArrayAt(allActions.value, 3)
@@ -452,6 +456,11 @@ function addOption() {
452
456
  }
453
457
  }
454
458
 
459
+ // 按钮权限信息筛选
460
+ function filterButtonPermissions(btn) {
461
+ return buttonPermissions.value.find(item => item.btnName === btn)
462
+ }
463
+
455
464
  // 处理按钮点击
456
465
  function handleButtonClick(btn, item) {
457
466
  emit(`${btn.btnIcon}`, item)
@@ -546,6 +555,7 @@ defineExpose({
546
555
  :order-list="orderList"
547
556
  :form-query="formQueryList"
548
557
  :button-state="buttonState"
558
+ :button-permissions="buttonPermissions"
549
559
  :scan-options="scanOptions"
550
560
  @on-refresh="onRefresh"
551
561
  @add-option="addOption"
@@ -1,6 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import XGridDropOption from '@af-mobile-client-vue3/components/core/XGridDropOption/index.vue'
3
3
  import XFormItem from '@af-mobile-client-vue3/components/data/XFormItem/index.vue'
4
+ import useUserStore from '@af-mobile-client-vue3/stores/modules/user'
4
5
  import { Icon } from '@iconify/vue'
5
6
  import {
6
7
  showFailToast,
@@ -23,6 +24,7 @@ const props = defineProps<{
23
24
  orderList?: any[]
24
25
  formQuery?: any[]
25
26
  buttonState?: any
27
+ buttonPermissions?: any[]
26
28
  scanOptions?: {
27
29
  show?: boolean // 是否显示扫码按钮
28
30
  type?: string | string[] // 显示类型:可以是单个类型,也可以是类型数组
@@ -41,6 +43,8 @@ const emit = defineEmits([
41
43
  'onNFC',
42
44
  ])
43
45
 
46
+ const userState = useUserStore().getLogin()
47
+
44
48
  // 定义扫描模式枚举,便于扩展
45
49
  const SCAN_MODES = {
46
50
  SCAN: 'scan', // 扫码模式
@@ -276,6 +280,11 @@ function handleFilterMenuChange(value: boolean) {
276
280
  function handleCloseScanButton() {
277
281
  listFilterMenu.value.close(false)
278
282
  }
283
+
284
+ // 按钮权限信息筛选
285
+ function filterButtonPermissions(btn) {
286
+ return props.buttonPermissions.find(item => item.btnName === btn)
287
+ }
279
288
  </script>
280
289
 
281
290
  <template>
@@ -385,7 +394,11 @@ function handleCloseScanButton() {
385
394
  <VanButton type="default" @click="resetOption">
386
395
  重置
387
396
  </VanButton>
388
- <VanButton v-if="props.buttonState.add && props.buttonState.add === true" type="primary" @click="addOption">
397
+ <VanButton
398
+ v-if="props.buttonState.add && props.buttonState.add === true && (filterButtonPermissions('add').state === false || ((filterButtonPermissions('add').state === true && userState.f.resources.f_role_name.includes((filterButtonPermissions('add').roleStr)))))"
399
+ type="primary"
400
+ @click="addOption"
401
+ >
389
402
  新增
390
403
  </VanButton>
391
404
  <VanButton type="primary" @click="confirmOption">
@@ -7,7 +7,8 @@ import XGridDropOption from '@af-mobile-client-vue3/components/core/XGridDropOpt
7
7
  import XMultiSelect from '@af-mobile-client-vue3/components/core/XMultiSelect/index.vue'
8
8
  import XSelect from '@af-mobile-client-vue3/components/core/XSelect/index.vue'
9
9
  import XLocationPicker from '@af-mobile-client-vue3/components/data/XOlMap/XLocationPicker/index.vue'
10
- import { runLogic } from '@af-mobile-client-vue3/services/api/common'
10
+ import { getConfigByNameAsync, runLogic } from '@af-mobile-client-vue3/services/api/common'
11
+ import { post } from '@af-mobile-client-vue3/services/restTools'
11
12
  import { searchToListOption, searchToOption } from '@af-mobile-client-vue3/services/v3Api'
12
13
  import { useUserStore } from '@af-mobile-client-vue3/stores/modules/user'
13
14
  import { getDict } from '@af-mobile-client-vue3/utils/dictUtil'
@@ -94,6 +95,7 @@ const emits = defineEmits(['update:modelValue', 'set-form'])
94
95
  // 判断并初始化防抖函数
95
96
  let debouncedUserLinkFunc: (() => void) | null = null
96
97
  let debouncedDepLinkFunc: (() => void) | null = null
98
+ let debouncedUpdateOptions: (() => void) | null = null
97
99
 
98
100
  const { attr, form, mode, serviceName, getDataParams, columnsField } = props
99
101
  const calendarShow = ref(false)
@@ -445,6 +447,10 @@ onBeforeMount(() => {
445
447
 
446
448
  if (attr?.keyName?.toString()?.startsWith('search@根据表单项[') && attr?.keyName?.toString().endsWith(']联动部门'))
447
449
  debouncedDepLinkFunc = debounce(() => updateResOptions('部门'), 200)
450
+
451
+ if (attr.keyName && (attr?.keyName?.toString().indexOf('async ') !== -1 || attr?.keyName?.toString()?.indexOf('function') !== -1)) {
452
+ debouncedUpdateOptions = debounce(updateOptions, 200)
453
+ }
448
454
  })
449
455
  // 是否展示表单左侧label文字
450
456
  const labelData = computed(() => {
@@ -474,6 +480,13 @@ function onCalendarConfirm(values) {
474
480
  calendarShow.value = false
475
481
  }
476
482
 
483
+ // js 函数作为数据源
484
+ async function updateOptions() {
485
+ if (attr.keyName && (attr.keyName.toString().includes('async ') || attr.keyName.toString().includes('function '))) {
486
+ option.value = await executeStrFunctionByContext(this, attr.keyName, [form, runLogic, mode, getConfigByNameAsync, post])
487
+ }
488
+ }
489
+
477
490
  function init() {
478
491
  if (attr.keyName && typeof attr.keyName === 'string') {
479
492
  if (attr.keyName && attr.keyName.includes('logic@')) {
@@ -509,6 +522,9 @@ function init() {
509
522
  else
510
523
  searchToOption(searchData, res => getDataCallback(res))
511
524
  }
525
+ else if (attr.keyName.toString().includes('async ') || attr.keyName.toString().includes('function ')) {
526
+ updateOptions()
527
+ }
512
528
  else {
513
529
  initRadioValue()
514
530
  }
@@ -1,6 +1,6 @@
1
- const loginApi = {
2
- Login: '/af-auth/login',
3
- Logout: '/af-auth/logout',
4
- }
5
-
6
- export { loginApi }
1
+ const loginApi = {
2
+ Login: '/af-auth/login',
3
+ Logout: '/af-auth/logout',
4
+ }
5
+
6
+ export { loginApi }
@@ -1,62 +1,58 @@
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
- wxLoginAge: boolean
15
- wxAutoLogin: string
16
- tenantName: string
17
- }
18
-
19
- // 存放 webConfig 中的 setting 配置
20
- export const useSettingStore = defineStore('setting', () => {
21
- const setting = ref<WebConfig>(undefined)
22
- const isInitialized = ref(false)
23
-
24
- const setSetting = (newSetting: WebConfig) => {
25
- setting.value = newSetting
26
- }
27
-
28
- const getSetting = () => {
29
- return setting.value
30
- }
31
-
32
- // 将 init 作为 store 的方法导出
33
- const init = async () => {
34
- if (isInitialized.value)
35
- return
36
-
37
- const useStore = createStorage()
38
- const catchWebConfig = useStore.get(APP_WEB_CONFIG_KEY)
39
- if (catchWebConfig?.setting) {
40
- setSetting(catchWebConfig?.setting)
41
- }
42
- else {
43
- const res = await getConfigByNameAsync('webMobileConfig')
44
- if (res.setting) {
45
- useStore.set(APP_WEB_CONFIG_KEY, res)
46
- console.log('res.setting', res.setting)
47
- setSetting(res.setting)
48
- }
49
- }
50
-
51
- isInitialized.value = true
52
- }
53
-
54
- return {
55
- setSetting,
56
- getSetting,
57
- init, // 导出 init 方法
58
- isInitialized,
59
- }
60
- })
61
-
62
- 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 isInitialized = ref(false)
20
+
21
+ const setSetting = (newSetting: WebConfig) => {
22
+ setting.value = newSetting
23
+ }
24
+
25
+ const getSetting = () => {
26
+ return setting.value
27
+ }
28
+
29
+ // 将 init 作为 store 的方法导出
30
+ const init = async () => {
31
+ if (isInitialized.value)
32
+ return
33
+
34
+ const useStore = createStorage()
35
+ const catchWebConfig = useStore.get(APP_WEB_CONFIG_KEY)
36
+ if (catchWebConfig) {
37
+ setSetting(catchWebConfig)
38
+ }
39
+ else {
40
+ const res = await getConfigByNameAsync('webMobileConfig')
41
+ if (res.setting) {
42
+ useStore.set(APP_WEB_CONFIG_KEY, res)
43
+ setSetting(res.setting)
44
+ }
45
+ }
46
+
47
+ isInitialized.value = true
48
+ }
49
+
50
+ return {
51
+ setSetting,
52
+ getSetting,
53
+ init, // 导出 init 方法
54
+ isInitialized,
55
+ }
56
+ })
57
+
58
+ export default useSettingStore