af-mobile-client-vue3 1.0.91 → 1.0.92-appraise
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.development +4 -4
- package/build/vite/index.ts +91 -91
- package/index.html +17 -17
- package/package.json +2 -1
- package/src/api/user/index.ts +40 -40
- package/src/components/data/XForm/index.vue +153 -153
- package/src/components/data/XFormItem/index.vue +997 -997
- package/src/components.d.ts +53 -53
- package/src/router/index.ts +60 -60
- package/src/router/routes.ts +145 -145
- package/src/services/api/Login.ts +6 -6
- package/src/views/component/EvaluateRecordView/index.vue +40 -40
- package/src/views/component/XFormAppraiseView/index.vue +168 -168
- package/src/views/component/index.vue +127 -127
- package/certs/127.0.0.1+2-key.pem +0 -28
- package/certs/127.0.0.1+2.pem +0 -27
package/.env.development
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
NODE_ENV=development
|
|
2
|
-
VITE_APP_PUBLIC_PATH=/
|
|
3
|
-
VITE_APP_PREVIEW=true
|
|
4
|
-
VITE_APP_API_BASE_URL=/api
|
|
1
|
+
NODE_ENV=development
|
|
2
|
+
VITE_APP_PUBLIC_PATH=/
|
|
3
|
+
VITE_APP_PREVIEW=true
|
|
4
|
+
VITE_APP_API_BASE_URL=/api
|
package/build/vite/index.ts
CHANGED
|
@@ -1,91 +1,91 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
|
-
import process from 'node:process'
|
|
3
|
-
import vue from '@vitejs/plugin-vue'
|
|
4
|
-
import legacy from '@vitejs/plugin-legacy'
|
|
5
|
-
import UnoCSS from 'unocss/vite'
|
|
6
|
-
import viteCompression from 'vite-plugin-compression'
|
|
7
|
-
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
|
8
|
-
import { VitePWA } from 'vite-plugin-pwa'
|
|
9
|
-
import Sitemap from 'vite-plugin-sitemap'
|
|
10
|
-
import mockDevServerPlugin from 'vite-plugin-mock-dev-server'
|
|
11
|
-
import { createViteVConsole } from './vconsole'
|
|
12
|
-
|
|
13
|
-
export function createVitePlugins() {
|
|
14
|
-
const root = process.cwd()
|
|
15
|
-
|
|
16
|
-
return [
|
|
17
|
-
vue({
|
|
18
|
-
template: {
|
|
19
|
-
compilerOptions: {
|
|
20
|
-
// 注册自定义组件micro-app 防止控制台警告
|
|
21
|
-
isCustomElement: tag => tag.startsWith('micro-app'),
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
}),
|
|
25
|
-
|
|
26
|
-
// https://github.com/jbaubree/vite-plugin-sitemap
|
|
27
|
-
Sitemap(),
|
|
28
|
-
|
|
29
|
-
// https://github.com/pengzhanbo/vite-plugin-mock-dev-server
|
|
30
|
-
mockDevServerPlugin(),
|
|
31
|
-
|
|
32
|
-
// svg icon
|
|
33
|
-
createSvgIconsPlugin({
|
|
34
|
-
// 指定图标文件夹
|
|
35
|
-
iconDirs: [path.resolve(root, 'src/icons/svg')],
|
|
36
|
-
// 指定 symbolId 格式
|
|
37
|
-
symbolId: 'icon-[dir]-[name]',
|
|
38
|
-
}),
|
|
39
|
-
|
|
40
|
-
// 生产环境 gzip 压缩资源
|
|
41
|
-
viteCompression({
|
|
42
|
-
algorithm: 'gzip',
|
|
43
|
-
// 文件大于10240b(10kb)时才压缩文件
|
|
44
|
-
threshold: 10240,
|
|
45
|
-
// 禁止在控制台输出压缩结果
|
|
46
|
-
verbose: false,
|
|
47
|
-
// 压缩完文件后删除源文件
|
|
48
|
-
deleteOriginFile: false,
|
|
49
|
-
}),
|
|
50
|
-
|
|
51
|
-
legacy({
|
|
52
|
-
targets: ['defaults', 'not IE 11'],
|
|
53
|
-
}),
|
|
54
|
-
|
|
55
|
-
// https://github.com/antfu/unocss
|
|
56
|
-
// see uno.config.ts for config
|
|
57
|
-
UnoCSS(),
|
|
58
|
-
|
|
59
|
-
// https://github.com/vadxq/vite-plugin-vconsole
|
|
60
|
-
createViteVConsole(),
|
|
61
|
-
|
|
62
|
-
// https://github.com/antfu/vite-plugin-pwa
|
|
63
|
-
VitePWA({
|
|
64
|
-
registerType: 'autoUpdate',
|
|
65
|
-
includeAssets: ['favicon.svg', 'safari-pinned-tab.svg'],
|
|
66
|
-
manifest: {
|
|
67
|
-
name: 'af-mobile-client-vue3',
|
|
68
|
-
short_name: 'af-mobile-client-vue3',
|
|
69
|
-
theme_color: '#ffffff',
|
|
70
|
-
icons: [
|
|
71
|
-
{
|
|
72
|
-
src: '/pwa-192x192.png',
|
|
73
|
-
sizes: '192x192',
|
|
74
|
-
type: 'image/png',
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
src: '/pwa-512x512.png',
|
|
78
|
-
sizes: '512x512',
|
|
79
|
-
type: 'image/png',
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
src: '/pwa-512x512.png',
|
|
83
|
-
sizes: '512x512',
|
|
84
|
-
type: 'image/png',
|
|
85
|
-
purpose: 'any maskable',
|
|
86
|
-
},
|
|
87
|
-
],
|
|
88
|
-
},
|
|
89
|
-
}),
|
|
90
|
-
]
|
|
91
|
-
}
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import process from 'node:process'
|
|
3
|
+
import vue from '@vitejs/plugin-vue'
|
|
4
|
+
import legacy from '@vitejs/plugin-legacy'
|
|
5
|
+
import UnoCSS from 'unocss/vite'
|
|
6
|
+
import viteCompression from 'vite-plugin-compression'
|
|
7
|
+
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
|
8
|
+
import { VitePWA } from 'vite-plugin-pwa'
|
|
9
|
+
import Sitemap from 'vite-plugin-sitemap'
|
|
10
|
+
import mockDevServerPlugin from 'vite-plugin-mock-dev-server'
|
|
11
|
+
import { createViteVConsole } from './vconsole'
|
|
12
|
+
|
|
13
|
+
export function createVitePlugins() {
|
|
14
|
+
const root = process.cwd()
|
|
15
|
+
|
|
16
|
+
return [
|
|
17
|
+
vue({
|
|
18
|
+
template: {
|
|
19
|
+
compilerOptions: {
|
|
20
|
+
// 注册自定义组件micro-app 防止控制台警告
|
|
21
|
+
isCustomElement: tag => tag.startsWith('micro-app'),
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
}),
|
|
25
|
+
|
|
26
|
+
// https://github.com/jbaubree/vite-plugin-sitemap
|
|
27
|
+
Sitemap(),
|
|
28
|
+
|
|
29
|
+
// https://github.com/pengzhanbo/vite-plugin-mock-dev-server
|
|
30
|
+
mockDevServerPlugin(),
|
|
31
|
+
|
|
32
|
+
// svg icon
|
|
33
|
+
createSvgIconsPlugin({
|
|
34
|
+
// 指定图标文件夹
|
|
35
|
+
iconDirs: [path.resolve(root, 'src/icons/svg')],
|
|
36
|
+
// 指定 symbolId 格式
|
|
37
|
+
symbolId: 'icon-[dir]-[name]',
|
|
38
|
+
}),
|
|
39
|
+
|
|
40
|
+
// 生产环境 gzip 压缩资源
|
|
41
|
+
viteCompression({
|
|
42
|
+
algorithm: 'gzip',
|
|
43
|
+
// 文件大于10240b(10kb)时才压缩文件
|
|
44
|
+
threshold: 10240,
|
|
45
|
+
// 禁止在控制台输出压缩结果
|
|
46
|
+
verbose: false,
|
|
47
|
+
// 压缩完文件后删除源文件
|
|
48
|
+
deleteOriginFile: false,
|
|
49
|
+
}),
|
|
50
|
+
|
|
51
|
+
legacy({
|
|
52
|
+
targets: ['defaults', 'not IE 11'],
|
|
53
|
+
}),
|
|
54
|
+
|
|
55
|
+
// https://github.com/antfu/unocss
|
|
56
|
+
// see uno.config.ts for config
|
|
57
|
+
UnoCSS(),
|
|
58
|
+
|
|
59
|
+
// https://github.com/vadxq/vite-plugin-vconsole
|
|
60
|
+
createViteVConsole(),
|
|
61
|
+
|
|
62
|
+
// https://github.com/antfu/vite-plugin-pwa
|
|
63
|
+
VitePWA({
|
|
64
|
+
registerType: 'autoUpdate',
|
|
65
|
+
includeAssets: ['favicon.svg', 'safari-pinned-tab.svg'],
|
|
66
|
+
manifest: {
|
|
67
|
+
name: 'af-mobile-client-vue3',
|
|
68
|
+
short_name: 'af-mobile-client-vue3',
|
|
69
|
+
theme_color: '#ffffff',
|
|
70
|
+
icons: [
|
|
71
|
+
{
|
|
72
|
+
src: '/pwa-192x192.png',
|
|
73
|
+
sizes: '192x192',
|
|
74
|
+
type: 'image/png',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
src: '/pwa-512x512.png',
|
|
78
|
+
sizes: '512x512',
|
|
79
|
+
type: 'image/png',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
src: '/pwa-512x512.png',
|
|
83
|
+
sizes: '512x512',
|
|
84
|
+
type: 'image/png',
|
|
85
|
+
purpose: 'any maskable',
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
}),
|
|
90
|
+
]
|
|
91
|
+
}
|
package/index.html
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="theme-color" content="#ffffff" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover, user-scalable=no"/>
|
|
7
|
-
<link rel="icon" href="/favicon.ico" />
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<div id="system-app"></div>
|
|
11
|
-
<script type="module" src="/src/main.ts"></script>
|
|
12
|
-
<noscript>
|
|
13
|
-
This website requires JavaScript to function properly.
|
|
14
|
-
Please enable JavaScript to continue.
|
|
15
|
-
</noscript>
|
|
16
|
-
</body>
|
|
17
|
-
</html>
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="theme-color" content="#ffffff" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover, user-scalable=no"/>
|
|
7
|
+
<link rel="icon" href="/favicon.ico" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="system-app"></div>
|
|
11
|
+
<script type="module" src="/src/main.ts"></script>
|
|
12
|
+
<noscript>
|
|
13
|
+
This website requires JavaScript to function properly.
|
|
14
|
+
Please enable JavaScript to continue.
|
|
15
|
+
</noscript>
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "af-mobile-client-vue3",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.92-appraise",
|
|
5
5
|
"description": "Vue + Vite component lib",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"engines": {
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"eslint-ts-patch": "8.57.0-0",
|
|
64
64
|
"husky": "^9.0.11",
|
|
65
65
|
"less": "^4.2.0",
|
|
66
|
+
"lint-staged": "^16.2.4",
|
|
66
67
|
"mockjs": "^1.1.0",
|
|
67
68
|
"postcss-mobile-forever": "^4.1.1",
|
|
68
69
|
"rollup": "^4.12.1",
|
package/src/api/user/index.ts
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { http } from '@af-mobile-client-vue3/utils/http'
|
|
2
|
-
|
|
3
|
-
import { loginApi } from '@af-mobile-client-vue3/services/api/Login'
|
|
4
|
-
import { get, post } from '@af-mobile-client-vue3/services/restTools'
|
|
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 { http } from '@af-mobile-client-vue3/utils/http'
|
|
2
|
+
|
|
3
|
+
import { loginApi } from '@af-mobile-client-vue3/services/api/Login'
|
|
4
|
+
import { get, post } from '@af-mobile-client-vue3/services/restTools'
|
|
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,153 +1,153 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
Button as VanButton,
|
|
4
|
-
CellGroup as VanCellGroup,
|
|
5
|
-
Form as VanForm,
|
|
6
|
-
} from 'vant'
|
|
7
|
-
import type { FormInstance } from 'vant'
|
|
8
|
-
import { computed, defineEmits, defineProps, onBeforeMount, reactive, ref, watch } from 'vue'
|
|
9
|
-
import XFormItem from '@af-mobile-client-vue3/components/data/XFormItem/index.vue'
|
|
10
|
-
|
|
11
|
-
interface FormItem {
|
|
12
|
-
addOrEdit: string
|
|
13
|
-
isOnlyAddOrEdit?: boolean
|
|
14
|
-
type?: string
|
|
15
|
-
model?: string
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface GroupFormItems {
|
|
19
|
-
btnName?: string
|
|
20
|
-
formJson: any[] // 根据实际类型调整
|
|
21
|
-
}
|
|
22
|
-
const props = withDefaults(defineProps<{
|
|
23
|
-
groupFormItems?: GroupFormItems
|
|
24
|
-
serviceName?: string
|
|
25
|
-
formData?: object
|
|
26
|
-
formName?: string
|
|
27
|
-
mode?: string
|
|
28
|
-
submitButton?: boolean
|
|
29
|
-
}>(), {
|
|
30
|
-
groupFormItems: null,
|
|
31
|
-
serviceName: undefined,
|
|
32
|
-
formData: null,
|
|
33
|
-
formName: 'default',
|
|
34
|
-
mode: '查询',
|
|
35
|
-
submitButton: true,
|
|
36
|
-
})
|
|
37
|
-
const emits = defineEmits(['onSubmit'])
|
|
38
|
-
const formRef = ref<FormInstance>()
|
|
39
|
-
const myFormItems = ref<FormItem[]>([])
|
|
40
|
-
const rules = reactive({})
|
|
41
|
-
const form = ref({})
|
|
42
|
-
const formGroupName = ref(null)
|
|
43
|
-
const myServiceName = ref('')
|
|
44
|
-
const loaded = ref(false)
|
|
45
|
-
let myGetDataParams = reactive({})
|
|
46
|
-
const realJsonData = computed(() => {
|
|
47
|
-
return myFormItems.value.filter((item) => {
|
|
48
|
-
return item.addOrEdit !== 'no'
|
|
49
|
-
})
|
|
50
|
-
})
|
|
51
|
-
onBeforeMount(() => {
|
|
52
|
-
init({ formItems: props.groupFormItems, serviceName: props.serviceName, formData: props.formData, formName: props.formName })
|
|
53
|
-
})
|
|
54
|
-
function init(params) {
|
|
55
|
-
const {
|
|
56
|
-
formItems,
|
|
57
|
-
serviceName,
|
|
58
|
-
getDataParams = {},
|
|
59
|
-
formData = null,
|
|
60
|
-
formName = 'default',
|
|
61
|
-
} = params
|
|
62
|
-
loaded.value = false
|
|
63
|
-
myFormItems.value = JSON.parse(JSON.stringify(formItems.formJson)) as FormItem[]
|
|
64
|
-
myServiceName.value = serviceName
|
|
65
|
-
formGroupName.value = formName
|
|
66
|
-
for (let i = 0; i < realJsonData.value.length; i++) {
|
|
67
|
-
const item = realJsonData.value[i]
|
|
68
|
-
setFormProps(form, item)
|
|
69
|
-
}
|
|
70
|
-
if (formData)
|
|
71
|
-
form.value = formData
|
|
72
|
-
|
|
73
|
-
myGetDataParams = getDataParams
|
|
74
|
-
loaded.value = true
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function setFormProps(form, item) {
|
|
78
|
-
form.value[item.model] = undefined
|
|
79
|
-
if (item.rule) {
|
|
80
|
-
rules[item.model] = []
|
|
81
|
-
let defaultValue
|
|
82
|
-
let message
|
|
83
|
-
switch (item.rule.type) {
|
|
84
|
-
case 'number':
|
|
85
|
-
message = '数字'
|
|
86
|
-
defaultValue = 0
|
|
87
|
-
break
|
|
88
|
-
case 'integer':
|
|
89
|
-
message = '整数'
|
|
90
|
-
defaultValue = 0
|
|
91
|
-
break
|
|
92
|
-
case 'float':
|
|
93
|
-
message = '小数'
|
|
94
|
-
defaultValue = 0.0
|
|
95
|
-
break
|
|
96
|
-
case 'string':
|
|
97
|
-
message = '字符串'
|
|
98
|
-
defaultValue = ''
|
|
99
|
-
break
|
|
100
|
-
}
|
|
101
|
-
rules[item.model].push({
|
|
102
|
-
type: item.rule.type,
|
|
103
|
-
message: `${item.name}必须为${message}`,
|
|
104
|
-
transform: (value) => {
|
|
105
|
-
if (value && value.length !== 0)
|
|
106
|
-
return Number(value)
|
|
107
|
-
else
|
|
108
|
-
return defaultValue
|
|
109
|
-
},
|
|
110
|
-
trigger: 'blur',
|
|
111
|
-
})
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function onSubmit() {
|
|
116
|
-
emits('onSubmit', form.value)
|
|
117
|
-
}
|
|
118
|
-
async function validate() {
|
|
119
|
-
await formRef.value?.validate()
|
|
120
|
-
}
|
|
121
|
-
watch(() => props.formData, (_val) => {
|
|
122
|
-
form.value = props.formData
|
|
123
|
-
})
|
|
124
|
-
defineExpose({ init, form, formGroupName, validate })
|
|
125
|
-
</script>
|
|
126
|
-
|
|
127
|
-
<template>
|
|
128
|
-
<VanForm ref="formRef" @submit="onSubmit">
|
|
129
|
-
<VanCellGroup inset>
|
|
130
|
-
<XFormItem
|
|
131
|
-
v-for="(item, index) in realJsonData"
|
|
132
|
-
:key="index"
|
|
133
|
-
v-model="form[item.model]"
|
|
134
|
-
:mode="props.mode"
|
|
135
|
-
:form="form"
|
|
136
|
-
:attr="item"
|
|
137
|
-
:rules="rules"
|
|
138
|
-
:service-name="myServiceName"
|
|
139
|
-
:get-data-params="myGetDataParams"
|
|
140
|
-
/>
|
|
141
|
-
</VanCellGroup>
|
|
142
|
-
<div v-if="props.submitButton && props.mode !== '预览'" style="margin: 16px;">
|
|
143
|
-
<VanButton round block type="primary" native-type="submit">
|
|
144
|
-
{{ props.groupFormItems?.btnName ? props.groupFormItems.btnName : '提交' }}
|
|
145
|
-
</VanButton>
|
|
146
|
-
<slot />
|
|
147
|
-
</div>
|
|
148
|
-
</VanForm>
|
|
149
|
-
</template>
|
|
150
|
-
|
|
151
|
-
<style scoped>
|
|
152
|
-
|
|
153
|
-
</style>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
Button as VanButton,
|
|
4
|
+
CellGroup as VanCellGroup,
|
|
5
|
+
Form as VanForm,
|
|
6
|
+
} from 'vant'
|
|
7
|
+
import type { FormInstance } from 'vant'
|
|
8
|
+
import { computed, defineEmits, defineProps, onBeforeMount, reactive, ref, watch } from 'vue'
|
|
9
|
+
import XFormItem from '@af-mobile-client-vue3/components/data/XFormItem/index.vue'
|
|
10
|
+
|
|
11
|
+
interface FormItem {
|
|
12
|
+
addOrEdit: string
|
|
13
|
+
isOnlyAddOrEdit?: boolean
|
|
14
|
+
type?: string
|
|
15
|
+
model?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface GroupFormItems {
|
|
19
|
+
btnName?: string
|
|
20
|
+
formJson: any[] // 根据实际类型调整
|
|
21
|
+
}
|
|
22
|
+
const props = withDefaults(defineProps<{
|
|
23
|
+
groupFormItems?: GroupFormItems
|
|
24
|
+
serviceName?: string
|
|
25
|
+
formData?: object
|
|
26
|
+
formName?: string
|
|
27
|
+
mode?: string
|
|
28
|
+
submitButton?: boolean
|
|
29
|
+
}>(), {
|
|
30
|
+
groupFormItems: null,
|
|
31
|
+
serviceName: undefined,
|
|
32
|
+
formData: null,
|
|
33
|
+
formName: 'default',
|
|
34
|
+
mode: '查询',
|
|
35
|
+
submitButton: true,
|
|
36
|
+
})
|
|
37
|
+
const emits = defineEmits(['onSubmit'])
|
|
38
|
+
const formRef = ref<FormInstance>()
|
|
39
|
+
const myFormItems = ref<FormItem[]>([])
|
|
40
|
+
const rules = reactive({})
|
|
41
|
+
const form = ref({})
|
|
42
|
+
const formGroupName = ref(null)
|
|
43
|
+
const myServiceName = ref('')
|
|
44
|
+
const loaded = ref(false)
|
|
45
|
+
let myGetDataParams = reactive({})
|
|
46
|
+
const realJsonData = computed(() => {
|
|
47
|
+
return myFormItems.value.filter((item) => {
|
|
48
|
+
return item.addOrEdit !== 'no'
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
onBeforeMount(() => {
|
|
52
|
+
init({ formItems: props.groupFormItems, serviceName: props.serviceName, formData: props.formData, formName: props.formName })
|
|
53
|
+
})
|
|
54
|
+
function init(params) {
|
|
55
|
+
const {
|
|
56
|
+
formItems,
|
|
57
|
+
serviceName,
|
|
58
|
+
getDataParams = {},
|
|
59
|
+
formData = null,
|
|
60
|
+
formName = 'default',
|
|
61
|
+
} = params
|
|
62
|
+
loaded.value = false
|
|
63
|
+
myFormItems.value = JSON.parse(JSON.stringify(formItems.formJson)) as FormItem[]
|
|
64
|
+
myServiceName.value = serviceName
|
|
65
|
+
formGroupName.value = formName
|
|
66
|
+
for (let i = 0; i < realJsonData.value.length; i++) {
|
|
67
|
+
const item = realJsonData.value[i]
|
|
68
|
+
setFormProps(form, item)
|
|
69
|
+
}
|
|
70
|
+
if (formData)
|
|
71
|
+
form.value = formData
|
|
72
|
+
|
|
73
|
+
myGetDataParams = getDataParams
|
|
74
|
+
loaded.value = true
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function setFormProps(form, item) {
|
|
78
|
+
form.value[item.model] = undefined
|
|
79
|
+
if (item.rule) {
|
|
80
|
+
rules[item.model] = []
|
|
81
|
+
let defaultValue
|
|
82
|
+
let message
|
|
83
|
+
switch (item.rule.type) {
|
|
84
|
+
case 'number':
|
|
85
|
+
message = '数字'
|
|
86
|
+
defaultValue = 0
|
|
87
|
+
break
|
|
88
|
+
case 'integer':
|
|
89
|
+
message = '整数'
|
|
90
|
+
defaultValue = 0
|
|
91
|
+
break
|
|
92
|
+
case 'float':
|
|
93
|
+
message = '小数'
|
|
94
|
+
defaultValue = 0.0
|
|
95
|
+
break
|
|
96
|
+
case 'string':
|
|
97
|
+
message = '字符串'
|
|
98
|
+
defaultValue = ''
|
|
99
|
+
break
|
|
100
|
+
}
|
|
101
|
+
rules[item.model].push({
|
|
102
|
+
type: item.rule.type,
|
|
103
|
+
message: `${item.name}必须为${message}`,
|
|
104
|
+
transform: (value) => {
|
|
105
|
+
if (value && value.length !== 0)
|
|
106
|
+
return Number(value)
|
|
107
|
+
else
|
|
108
|
+
return defaultValue
|
|
109
|
+
},
|
|
110
|
+
trigger: 'blur',
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function onSubmit() {
|
|
116
|
+
emits('onSubmit', form.value)
|
|
117
|
+
}
|
|
118
|
+
async function validate() {
|
|
119
|
+
await formRef.value?.validate()
|
|
120
|
+
}
|
|
121
|
+
watch(() => props.formData, (_val) => {
|
|
122
|
+
form.value = props.formData
|
|
123
|
+
})
|
|
124
|
+
defineExpose({ init, form, formGroupName, validate })
|
|
125
|
+
</script>
|
|
126
|
+
|
|
127
|
+
<template>
|
|
128
|
+
<VanForm ref="formRef" @submit="onSubmit">
|
|
129
|
+
<VanCellGroup inset>
|
|
130
|
+
<XFormItem
|
|
131
|
+
v-for="(item, index) in realJsonData"
|
|
132
|
+
:key="index"
|
|
133
|
+
v-model="form[item.model]"
|
|
134
|
+
:mode="props.mode"
|
|
135
|
+
:form="form"
|
|
136
|
+
:attr="item"
|
|
137
|
+
:rules="rules"
|
|
138
|
+
:service-name="myServiceName"
|
|
139
|
+
:get-data-params="myGetDataParams"
|
|
140
|
+
/>
|
|
141
|
+
</VanCellGroup>
|
|
142
|
+
<div v-if="props.submitButton && props.mode !== '预览'" style="margin: 16px;">
|
|
143
|
+
<VanButton round block type="primary" native-type="submit">
|
|
144
|
+
{{ props.groupFormItems?.btnName ? props.groupFormItems.btnName : '提交' }}
|
|
145
|
+
</VanButton>
|
|
146
|
+
<slot />
|
|
147
|
+
</div>
|
|
148
|
+
</VanForm>
|
|
149
|
+
</template>
|
|
150
|
+
|
|
151
|
+
<style scoped>
|
|
152
|
+
|
|
153
|
+
</style>
|