af-mobile-client-vue3 1.1.48 → 1.1.50

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,112 +1,113 @@
1
- {
2
- "name": "af-mobile-client-vue3",
3
- "type": "module",
4
- "version": "1.1.48",
5
- "description": "Vue + Vite component lib",
6
- "license": "MIT",
7
- "engines": {
8
- "node": ">=18.12.0",
9
- "pnpm": ">=8.15.0"
10
- },
11
- "scripts": {
12
- "dev": "cross-env MOCK_SERVER_PORT=8086 vite",
13
- "build": "vue-tsc --noEmit && vite build",
14
- "build:dev": "vue-tsc --noEmit && vite build --mode=development",
15
- "preview": "vite preview",
16
- "lint": "eslint . && vue-tsc --noEmit",
17
- "lint:fix": "eslint . --fix",
18
- "test": "vitest",
19
- "release": "bumpp --commit --push --tag"
20
- },
21
- "dependencies": {
22
- "@iconify/vue": "4.3.0",
23
- "@micro-zoe/micro-app": "1.0.0-rc.24",
24
- "@unhead/vue": "^2.0.5",
25
- "@vant/area-data": "^2.0.0",
26
- "@vant/touch-emulator": "^1.4.0",
27
- "@vant/use": "^1.6.0",
28
- "@vueuse/core": "^13.1.0",
29
- "animate.css": "^4.1.1",
30
- "axios": "^1.8.4",
31
- "crypto-js": "^4.2.0",
32
- "echarts": "^5.6.0",
33
- "lodash-es": "^4.17.21",
34
- "nprogress": "^0.2.0",
35
- "ol": "^10.5.0",
36
- "pinia": "^3.0.2",
37
- "pinia-plugin-persistedstate": "^4.2.0",
38
- "qs": "^6.14.0",
39
- "resize-detector": "^0.3.0",
40
- "store": "^2.0.12",
41
- "vant": "^4.9.18",
42
- "vconsole": "^3.15.1",
43
- "vue": "^3.5.13",
44
- "vue-router": "^4.5.0",
45
- "vue3-hash-calendar": "^1.1.3"
46
- },
47
- "devDependencies": {
48
- "@antfu/eslint-config": "^4.12.0",
49
- "@iconify/json": "2.2.318",
50
- "@types/crypto-js": "^4.2.2",
51
- "@types/lodash-es": "^4.17.12",
52
- "@types/node": "^22.14.1",
53
- "@types/nprogress": "^0.2.3",
54
- "@types/store": "^2.0.5",
55
- "@unocss/eslint-plugin": "^66.1.0-beta.11",
56
- "@unocss/preset-rem-to-px": "66.1.0-beta.11",
57
- "@vitejs/plugin-legacy": "^6.0.2",
58
- "@vitejs/plugin-vue": "^5.2.3",
59
- "autoprefixer": "^10.4.21",
60
- "bumpp": "^10.1.0",
61
- "commitizen": "^4.3.1",
62
- "consola": "^3.4.2",
63
- "cross-env": "^7.0.3",
64
- "cz-emoji-chinese": "^0.3.1",
65
- "eslint": "^9.24.0",
66
- "eslint-ts-patch": "^8.57.0-0",
67
- "husky": "^9.1.7",
68
- "less": "^4.3.0",
69
- "mockjs": "^1.1.0",
70
- "postcss-mobile-forever": "^5.0.0",
71
- "rollup": "^4.40.0",
72
- "terser": "^5.39.0",
73
- "typescript": "^5.8.3",
74
- "unocss": "^66.1.0-beta.11",
75
- "unplugin-auto-import": "^19.1.2",
76
- "unplugin-vue-components": "^28.4.1",
77
- "unplugin-vue-router": "^0.12.0",
78
- "vite": "^6.2.6",
79
- "vite-plugin-compression": "^0.5.1",
80
- "vite-plugin-mock-dev-server": "^1.8.5",
81
- "vite-plugin-pwa": "^1.0.0",
82
- "vite-plugin-sitemap": "^0.7.1",
83
- "vite-plugin-svg-icons": "^2.0.1",
84
- "vite-plugin-vconsole": "^2.1.1",
85
- "vite-plugin-vue-devtools": "^7.7.2",
86
- "vite-plugin-vue-layouts": "^0.11.0",
87
- "vitest": "^3.1.1",
88
- "vue-tsc": "^2.2.8"
89
- },
90
- "pnpm": {
91
- "peerDependencyRules": {
92
- "ignoreMissing": [
93
- "postcss",
94
- "esbuild"
95
- ],
96
- "allowedVersions": {
97
- "rollup": "^4.x"
98
- }
99
- }
100
- },
101
- "config": {
102
- "commitizen": {
103
- "path": "./node_modules/cz-emoji-chinese"
104
- },
105
- "cz-emoji-chinese": {
106
- "skipQuestions": [
107
- "body",
108
- "scope"
109
- ]
110
- }
111
- }
112
- }
1
+ {
2
+ "name": "af-mobile-client-vue3",
3
+ "type": "module",
4
+ "version": "1.1.50",
5
+ "description": "Vue + Vite component lib",
6
+ "license": "MIT",
7
+ "engines": {
8
+ "node": ">=18.12.0",
9
+ "pnpm": ">=8.15.0"
10
+ },
11
+ "scripts": {
12
+ "dev": "cross-env MOCK_SERVER_PORT=8086 vite",
13
+ "build": "vue-tsc --noEmit && vite build",
14
+ "build:dev": "vue-tsc --noEmit && vite build --mode=development",
15
+ "preview": "vite preview",
16
+ "lint": "eslint . && vue-tsc --noEmit",
17
+ "lint:fix": "eslint . --fix",
18
+ "test": "vitest",
19
+ "release": "bumpp --commit --push --tag"
20
+ },
21
+ "dependencies": {
22
+ "@iconify/vue": "4.3.0",
23
+ "@micro-zoe/micro-app": "1.0.0-rc.24",
24
+ "@unhead/vue": "^2.0.5",
25
+ "@vant/area-data": "^2.0.0",
26
+ "@vant/touch-emulator": "^1.4.0",
27
+ "@vant/use": "^1.6.0",
28
+ "@vueuse/core": "^13.1.0",
29
+ "animate.css": "^4.1.1",
30
+ "axios": "^1.8.4",
31
+ "crypto-js": "^4.2.0",
32
+ "dayjs": "^1.11.13",
33
+ "echarts": "^5.6.0",
34
+ "lodash-es": "^4.17.21",
35
+ "nprogress": "^0.2.0",
36
+ "ol": "^10.5.0",
37
+ "pinia": "^3.0.2",
38
+ "pinia-plugin-persistedstate": "^4.2.0",
39
+ "qs": "^6.14.0",
40
+ "resize-detector": "^0.3.0",
41
+ "store": "^2.0.12",
42
+ "vant": "^4.9.18",
43
+ "vconsole": "^3.15.1",
44
+ "vue": "^3.5.13",
45
+ "vue-router": "^4.5.0",
46
+ "vue3-hash-calendar": "^1.1.3"
47
+ },
48
+ "devDependencies": {
49
+ "@antfu/eslint-config": "^4.12.0",
50
+ "@iconify/json": "2.2.318",
51
+ "@types/crypto-js": "^4.2.2",
52
+ "@types/lodash-es": "^4.17.12",
53
+ "@types/node": "^22.14.1",
54
+ "@types/nprogress": "^0.2.3",
55
+ "@types/store": "^2.0.5",
56
+ "@unocss/eslint-plugin": "^66.1.0-beta.11",
57
+ "@unocss/preset-rem-to-px": "66.1.0-beta.11",
58
+ "@vitejs/plugin-legacy": "^6.0.2",
59
+ "@vitejs/plugin-vue": "^5.2.3",
60
+ "autoprefixer": "^10.4.21",
61
+ "bumpp": "^10.1.0",
62
+ "commitizen": "^4.3.1",
63
+ "consola": "^3.4.2",
64
+ "cross-env": "^7.0.3",
65
+ "cz-emoji-chinese": "^0.3.1",
66
+ "eslint": "^9.24.0",
67
+ "eslint-ts-patch": "^8.57.0-0",
68
+ "husky": "^9.1.7",
69
+ "less": "^4.3.0",
70
+ "mockjs": "^1.1.0",
71
+ "postcss-mobile-forever": "^5.0.0",
72
+ "rollup": "^4.40.0",
73
+ "terser": "^5.39.0",
74
+ "typescript": "^5.8.3",
75
+ "unocss": "^66.1.0-beta.11",
76
+ "unplugin-auto-import": "^19.1.2",
77
+ "unplugin-vue-components": "^28.4.1",
78
+ "unplugin-vue-router": "^0.12.0",
79
+ "vite": "^6.2.6",
80
+ "vite-plugin-compression": "^0.5.1",
81
+ "vite-plugin-mock-dev-server": "^1.8.5",
82
+ "vite-plugin-pwa": "^1.0.0",
83
+ "vite-plugin-sitemap": "^0.7.1",
84
+ "vite-plugin-svg-icons": "^2.0.1",
85
+ "vite-plugin-vconsole": "^2.1.1",
86
+ "vite-plugin-vue-devtools": "^7.7.2",
87
+ "vite-plugin-vue-layouts": "^0.11.0",
88
+ "vitest": "^3.1.1",
89
+ "vue-tsc": "^2.2.8"
90
+ },
91
+ "pnpm": {
92
+ "peerDependencyRules": {
93
+ "ignoreMissing": [
94
+ "postcss",
95
+ "esbuild"
96
+ ],
97
+ "allowedVersions": {
98
+ "rollup": "^4.x"
99
+ }
100
+ }
101
+ },
102
+ "config": {
103
+ "commitizen": {
104
+ "path": "./node_modules/cz-emoji-chinese"
105
+ },
106
+ "cz-emoji-chinese": {
107
+ "skipQuestions": [
108
+ "body",
109
+ "scope"
110
+ ]
111
+ }
112
+ }
113
+ }
@@ -1,159 +1,159 @@
1
- <script setup lang="ts">
2
- import { deleteFile } from '@af-mobile-client-vue3/services/api/common'
3
- import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
4
- import {
5
- Button as vanButton,
6
- Uploader as vanUploader,
7
- } from 'vant'
8
- import { ref, watch } from 'vue'
9
-
10
- const props = defineProps({
11
- imageList: Array<any>,
12
- outerIndex: { default: undefined },
13
- authority: { default: 'user' },
14
- uploadMode: { default: 'server' },
15
- attr: { type: Object as () => { addOrEdit?: string }, default: () => ({}) },
16
- })
17
- const emit = defineEmits(['updateFileList'])
18
-
19
- const imageList = ref<Array<any>>(props.imageList ?? [])
20
-
21
- // 同步 props.imageList 到内部 imageList,保证每次变化都响应
22
- watch(() => props.imageList, (newVal) => {
23
- imageList.value = Array.isArray(newVal) ? [...newVal] : []
24
- }, { immediate: true })
25
-
26
- // 触发拍照
27
- function triggerCamera() {
28
- mobileUtil.execute({
29
- funcName: 'takePicture',
30
- param: {},
31
- callbackFunc: (result: any) => {
32
- if (result.status === 'success') {
33
- handlePhotoUpload(result.data)
34
- }
35
- },
36
- })
37
- }
38
-
39
- // 处理拍照后的上传
40
- function getImageMimeType(fileName: string): string {
41
- const ext = fileName.split('.').pop()?.toLowerCase()
42
- if (ext === 'jpg' || ext === 'jpeg')
43
- return 'image/jpeg'
44
- if (ext === 'png')
45
- return 'image/png'
46
- if (ext === 'gif')
47
- return 'image/gif'
48
- return 'image/png' // 默认
49
- }
50
-
51
- function handlePhotoUpload(photoData: any) {
52
- // 添加临时预览
53
- const mimeType = getImageMimeType(photoData.filePath)
54
- const tempFile = {
55
- uid: Date.now() + Math.random().toString(36).substr(2, 5),
56
- name: photoData.filePath.split('/').pop(),
57
- status: 'uploading',
58
- message: '上传中...',
59
- url: `data:${mimeType};base64,${photoData.content}`,
60
- }
61
-
62
- if (!imageList.value) {
63
- imageList.value = [tempFile]
64
- }
65
- else {
66
- imageList.value.push(tempFile)
67
- }
68
-
69
- const param = {
70
- resUploadMode: props.uploadMode,
71
- pathKey: 'Default',
72
- formType: 'image',
73
- useType: 'Default',
74
- resUploadStock: '1',
75
- filename: photoData.name,
76
- filesize: photoData.size,
77
- f_operator: 'server',
78
- imgPath: photoData.filePath,
79
- urlPath: `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`,
80
- }
81
- // 上传到服务器
82
- mobileUtil.execute({
83
- funcName: 'uploadResource',
84
- param,
85
- callbackFunc: (result: any) => {
86
- if (result.status === 'success') {
87
- const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
88
- if (index !== -1) {
89
- imageList.value[index].uid = result.data.id
90
- imageList.value[index].id = result.data.id
91
- delete imageList.value[index].message
92
- imageList.value[index].status = 'done'
93
- imageList.value[index].url = result.data.f_downloadpath
94
- }
95
- }
96
- else {
97
- const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
98
- if (index !== -1) {
99
- imageList.value[index].status = 'failed'
100
- imageList.value[index].message = '上传失败'
101
- }
102
- }
103
-
104
- if (props.outerIndex !== undefined)
105
- emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
106
- else
107
- emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
108
- },
109
- })
110
- }
111
-
112
- // 删除图片
113
- function deleteFileFunction(file: any) {
114
- if (file.id) {
115
- deleteFile({ ids: [file.id], f_state: '删除' }).then((res: any) => {
116
- if (res.msg !== undefined) {
117
- const targetIndex = imageList.value.findIndex(item => item.id === file.id)
118
- if (targetIndex !== -1) {
119
- imageList.value.splice(targetIndex, 1)
120
- if (props.outerIndex !== undefined)
121
- emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
122
- else
123
- emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
124
- }
125
- }
126
- })
127
- }
128
- }
129
- </script>
130
-
131
- <template>
132
- <div class="uploader-container">
133
- <van-button
134
- v-if="props.attr?.addOrEdit !== 'readonly'"
135
- icon="photograph"
136
- type="primary"
137
- @click="triggerCamera"
138
- >
139
- 拍照
140
- </van-button>
141
-
142
- <van-uploader
143
- v-model="imageList"
144
- :show-upload="false"
145
- :deletable="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin'"
146
- :multiple="props.authority === 'admin'"
147
- :preview-image="true"
148
- :before-delete="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin' ? deleteFileFunction : undefined"
149
- />
150
- </div>
151
- </template>
152
-
153
- <style scoped lang="less">
154
- .uploader-container {
155
- display: flex;
156
- flex-direction: column;
157
- gap: 16px;
158
- }
159
- </style>
1
+ <script setup lang="ts">
2
+ import { deleteFile } from '@af-mobile-client-vue3/services/api/common'
3
+ import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
4
+ import {
5
+ Button as vanButton,
6
+ Uploader as vanUploader,
7
+ } from 'vant'
8
+ import { ref, watch } from 'vue'
9
+
10
+ const props = defineProps({
11
+ imageList: Array<any>,
12
+ outerIndex: { default: undefined },
13
+ authority: { default: 'user' },
14
+ uploadMode: { default: 'server' },
15
+ attr: { type: Object as () => { addOrEdit?: string }, default: () => ({}) },
16
+ })
17
+ const emit = defineEmits(['updateFileList'])
18
+
19
+ const imageList = ref<Array<any>>(props.imageList ?? [])
20
+
21
+ // 同步 props.imageList 到内部 imageList,保证每次变化都响应
22
+ watch(() => props.imageList, (newVal) => {
23
+ imageList.value = Array.isArray(newVal) ? [...newVal] : []
24
+ }, { immediate: true })
25
+
26
+ // 触发拍照
27
+ function triggerCamera() {
28
+ mobileUtil.execute({
29
+ funcName: 'takePicture',
30
+ param: {},
31
+ callbackFunc: (result: any) => {
32
+ if (result.status === 'success') {
33
+ handlePhotoUpload(result.data)
34
+ }
35
+ },
36
+ })
37
+ }
38
+
39
+ // 处理拍照后的上传
40
+ function getImageMimeType(fileName: string): string {
41
+ const ext = fileName.split('.').pop()?.toLowerCase()
42
+ if (ext === 'jpg' || ext === 'jpeg')
43
+ return 'image/jpeg'
44
+ if (ext === 'png')
45
+ return 'image/png'
46
+ if (ext === 'gif')
47
+ return 'image/gif'
48
+ return 'image/png' // 默认
49
+ }
50
+
51
+ function handlePhotoUpload(photoData: any) {
52
+ // 添加临时预览
53
+ const mimeType = getImageMimeType(photoData.filePath)
54
+ const tempFile = {
55
+ uid: Date.now() + Math.random().toString(36).substr(2, 5),
56
+ name: photoData.filePath.split('/').pop(),
57
+ status: 'uploading',
58
+ message: '上传中...',
59
+ url: `data:${mimeType};base64,${photoData.content}`,
60
+ }
61
+
62
+ if (!imageList.value) {
63
+ imageList.value = [tempFile]
64
+ }
65
+ else {
66
+ imageList.value.push(tempFile)
67
+ }
68
+
69
+ const param = {
70
+ resUploadMode: props.uploadMode,
71
+ pathKey: 'Default',
72
+ formType: 'image',
73
+ useType: 'Default',
74
+ resUploadStock: '1',
75
+ filename: photoData.name,
76
+ filesize: photoData.size,
77
+ f_operator: 'server',
78
+ imgPath: photoData.filePath,
79
+ urlPath: `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`,
80
+ }
81
+ // 上传到服务器
82
+ mobileUtil.execute({
83
+ funcName: 'uploadResource',
84
+ param,
85
+ callbackFunc: (result: any) => {
86
+ if (result.status === 'success') {
87
+ const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
88
+ if (index !== -1) {
89
+ imageList.value[index].uid = result.data.id
90
+ imageList.value[index].id = result.data.id
91
+ delete imageList.value[index].message
92
+ imageList.value[index].status = 'done'
93
+ imageList.value[index].url = result.data.f_downloadpath
94
+ }
95
+ }
96
+ else {
97
+ const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
98
+ if (index !== -1) {
99
+ imageList.value[index].status = 'failed'
100
+ imageList.value[index].message = '上传失败'
101
+ }
102
+ }
103
+
104
+ if (props.outerIndex !== undefined)
105
+ emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
106
+ else
107
+ emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
108
+ },
109
+ })
110
+ }
111
+
112
+ // 删除图片
113
+ function deleteFileFunction(file: any) {
114
+ if (file.id) {
115
+ deleteFile({ ids: [file.id], f_state: '删除' }).then((res: any) => {
116
+ if (res.msg !== undefined) {
117
+ const targetIndex = imageList.value.findIndex(item => item.id === file.id)
118
+ if (targetIndex !== -1) {
119
+ imageList.value.splice(targetIndex, 1)
120
+ if (props.outerIndex !== undefined)
121
+ emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
122
+ else
123
+ emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
124
+ }
125
+ }
126
+ })
127
+ }
128
+ }
129
+ </script>
130
+
131
+ <template>
132
+ <div class="uploader-container">
133
+ <van-button
134
+ v-if="props.attr?.addOrEdit !== 'readonly'"
135
+ icon="photograph"
136
+ type="primary"
137
+ @click="triggerCamera"
138
+ >
139
+ 拍照
140
+ </van-button>
141
+
142
+ <van-uploader
143
+ v-model="imageList"
144
+ :show-upload="false"
145
+ :deletable="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin'"
146
+ :multiple="props.authority === 'admin'"
147
+ :preview-image="true"
148
+ :before-delete="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin' ? deleteFileFunction : undefined"
149
+ />
150
+ </div>
151
+ </template>
152
+
153
+ <style scoped lang="less">
154
+ .uploader-container {
155
+ display: flex;
156
+ flex-direction: column;
157
+ gap: 16px;
158
+ }
159
+ </style>
@@ -146,7 +146,21 @@ function init(params) {
146
146
  }
147
147
 
148
148
  function setFormProps(form, item) {
149
- form.value[item.model] = undefined
149
+ // 只有在字段未定义时,按类型赋有意义的默认值
150
+ if (form.value[item.model] === undefined) {
151
+ switch (item.rule?.type) {
152
+ case 'number':
153
+ case 'integer':
154
+ case 'float':
155
+ form.value[item.model] = 0
156
+ break
157
+ case 'string':
158
+ form.value[item.model] = ''
159
+ break
160
+ default:
161
+ form.value[item.model] = ''
162
+ }
163
+ }
150
164
  if (item.rule) {
151
165
  rules[item.model] = []
152
166
  let defaultValue