af-mobile-client-vue3 1.3.11 → 1.3.13

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.
Files changed (268) hide show
  1. package/.claude/settings.local.json +10 -0
  2. package/.cursorrules +60 -60
  3. package/.editorconfig +9 -9
  4. package/.env +10 -10
  5. package/.env.development +1 -1
  6. package/.env.production +1 -1
  7. package/.node-version +1 -1
  8. package/.vscode/extensions.json +12 -12
  9. package/.vscode/settings.json +66 -66
  10. package/CLAUDE.md +189 -184
  11. package/README.md +182 -181
  12. package/af-example-mobile-vue-web.iml +9 -9
  13. package/build/vite/index.ts +98 -98
  14. package/build/vite/optimize.ts +34 -34
  15. package/build/vite/vconsole.ts +47 -47
  16. package/commitlint.config.ts +32 -32
  17. package/compress.js +36 -36
  18. package/eslint.config.ts +30 -30
  19. package/index.html +23 -23
  20. package/mock/data.ts +20 -20
  21. package/mock/index.ts +7 -7
  22. package/mock/modules/prose.mock.ts +13 -13
  23. package/mock/modules/user.mock.ts +152 -152
  24. package/mock/util.ts +19 -19
  25. package/netlify.toml +12 -12
  26. package/package.json +114 -114
  27. package/postcss.config.ts +27 -27
  28. package/public/favicon.svg +4 -4
  29. package/public/safari-pinned-tab.svg +4 -4
  30. package/scripts/verifyCommit.js +19 -19
  31. package/src/App.vue +79 -79
  32. package/src/api/mock/index.ts +30 -30
  33. package/src/api/user/index.ts +40 -40
  34. package/src/assets/img/user/login/background-shadow-1.svg +20 -20
  35. package/src/assets/img/user/login/logo-background.svg +20 -20
  36. package/src/bootstrap.ts +26 -26
  37. package/src/components/core/BeautifulLoading/index.vue +52 -52
  38. package/src/components/core/ImageUploader/index.vue +244 -244
  39. package/src/components/core/NavBar/index.vue +53 -53
  40. package/src/components/core/Tabbar/index.vue +32 -32
  41. package/src/components/core/Uploader/index.vue +124 -124
  42. package/src/components/core/XGridDropOption/index.vue +154 -156
  43. package/src/components/core/XMultiSelect/index.vue +183 -183
  44. package/src/components/core/XSelect/index.vue +149 -149
  45. package/src/components/data/InfoDisplay/index.vue +132 -0
  46. package/src/components/data/UserDetail/api.ts +24 -0
  47. package/src/components/data/UserDetail/index.vue +539 -0
  48. package/src/components/data/UserDetail/recordEntries.ts +159 -0
  49. package/src/components/data/UserDetail/types.ts +26 -0
  50. package/src/components/data/XBadge/index.vue +82 -82
  51. package/src/components/data/XCellDetail/index.vue +105 -105
  52. package/src/components/data/XCellList/XCellList.md +313 -313
  53. package/src/components/data/XCellList/index.vue +1075 -1075
  54. package/src/components/data/XCellListFilter/QrScanner/index.vue +207 -207
  55. package/src/components/data/XCellListFilter/QrScanner/startScanAnimation.ts +53 -53
  56. package/src/components/data/XCellListFilter/VpnRecognition/index.vue +119 -119
  57. package/src/components/data/XCellListFilter/index.vue +705 -705
  58. package/src/components/data/XForm/index.vue +659 -659
  59. package/src/components/data/XFormGroup/doc/DeviceForm.vue +121 -121
  60. package/src/components/data/XFormGroup/doc/FormGroupDemo.vue +56 -56
  61. package/src/components/data/XFormGroup/doc/README.md +286 -273
  62. package/src/components/data/XFormGroup/doc/UserForm.vue +101 -101
  63. package/src/components/data/XFormGroup/index.vue +240 -240
  64. package/src/components/data/XFormItem/index.vue +1310 -1310
  65. package/src/components/data/XOlMap/README.md +227 -227
  66. package/src/components/data/XOlMap/XLocationPicker/index.vue +226 -225
  67. package/src/components/data/XOlMap/index.vue +1490 -1490
  68. package/src/components/data/XOlMap/types.ts +149 -149
  69. package/src/components/data/XOlMap/utils/wgs84ToGcj02.js +154 -154
  70. package/src/components/data/XReportForm/DateTimeSecondsPicker.vue +208 -208
  71. package/src/components/data/XReportForm/XReportFormJsonRender.vue +220 -220
  72. package/src/components/data/XReportForm/index.vue +1393 -1393
  73. package/src/components/data/XReportGrid/XAddReport/XAddReport.vue +198 -198
  74. package/src/components/data/XReportGrid/XAddReport/index.js +3 -3
  75. package/src/components/data/XReportGrid/XAddReport/index.md +53 -52
  76. package/src/components/data/XReportGrid/XAddReport/index.ts +10 -10
  77. package/src/components/data/XReportGrid/XReport.vue +960 -960
  78. package/src/components/data/XReportGrid/XReportDesign.vue +597 -597
  79. package/src/components/data/XReportGrid/XReportDrawer/XReportDrawer.vue +148 -148
  80. package/src/components/data/XReportGrid/XReportDrawer/index.js +3 -3
  81. package/src/components/data/XReportGrid/XReportDrawer/index.ts +10 -10
  82. package/src/components/data/XReportGrid/XReportJsonRender.vue +399 -399
  83. package/src/components/data/XReportGrid/XReportTrGroup.vue +592 -592
  84. package/src/components/data/XReportGrid/index.md +46 -42
  85. package/src/components/data/XSignature/index.vue +284 -285
  86. package/src/components/data/XTag/index.vue +10 -10
  87. package/src/components/layout/NormalDataLayout/index.vue +69 -69
  88. package/src/components/layout/TabBarLayout/index.vue +40 -40
  89. package/src/composables/dark.ts +5 -5
  90. package/src/config/routes.ts +9 -9
  91. package/src/constants/index.ts +2 -2
  92. package/src/enums/requestEnum.ts +25 -25
  93. package/src/expression/ExpressionRunner.ts +28 -28
  94. package/src/expression/TestExpression.ts +510 -510
  95. package/src/expression/core/Delegate.ts +116 -116
  96. package/src/expression/core/Expression.ts +1359 -1359
  97. package/src/expression/core/Program.ts +985 -985
  98. package/src/expression/core/Token.ts +29 -29
  99. package/src/expression/enums/ExpressionType.ts +81 -81
  100. package/src/expression/enums/TokenType.ts +11 -11
  101. package/src/expression/exception/BreakWayException.ts +2 -2
  102. package/src/expression/exception/ContinueWayException.ts +2 -2
  103. package/src/expression/exception/ExpressionException.ts +29 -29
  104. package/src/expression/exception/ReturnWayException.ts +14 -14
  105. package/src/expression/exception/ServiceException.ts +22 -22
  106. package/src/expression/instances/JSONArray.ts +52 -52
  107. package/src/expression/instances/JSONObject.ts +118 -118
  108. package/src/expression/instances/LogicConsole.ts +31 -31
  109. package/src/font-style/font.css +4 -4
  110. package/src/hooks/useBoolean.ts +26 -0
  111. package/src/hooks/useCommon.ts +9 -9
  112. package/src/hooks/useLogin.ts +97 -97
  113. package/src/icons/svg/check-in.svg +32 -32
  114. package/src/icons/svg/dark.svg +4 -4
  115. package/src/icons/svg/github.svg +4 -4
  116. package/src/icons/svg/light.svg +4 -4
  117. package/src/icons/svg/link.svg +4 -4
  118. package/src/icons/svgo.yml +22 -22
  119. package/src/layout/GridView/index.vue +16 -16
  120. package/src/layout/PageLayout.vue +9 -9
  121. package/src/layout/SingleLayout.vue +9 -9
  122. package/src/locales/en-US.json +128 -128
  123. package/src/locales/zh-CN.json +128 -128
  124. package/src/logic/LogicRunner.ts +67 -67
  125. package/src/logic/TestLogic.ts +13 -13
  126. package/src/logic/plugins/common/DateTools.ts +35 -35
  127. package/src/logic/plugins/common/VueTools.ts +30 -30
  128. package/src/logic/plugins/index.ts +7 -7
  129. package/src/main.ts +44 -44
  130. package/src/plugins/AppData.ts +38 -38
  131. package/src/plugins/GetLoginInfoService.ts +10 -10
  132. package/src/plugins/collectIcons.ts +10 -0
  133. package/src/plugins/index.ts +11 -11
  134. package/src/router/README.md +8 -8
  135. package/src/router/guards.ts +59 -59
  136. package/src/router/index.ts +35 -35
  137. package/src/router/invoiceRoutes.ts +33 -33
  138. package/src/router/routes.ts +341 -171
  139. package/src/router/types.ts +7 -7
  140. package/src/services/api/Login.ts +6 -6
  141. package/src/services/api/common.ts +109 -109
  142. package/src/services/api/index.ts +7 -7
  143. package/src/services/api/manage.ts +8 -8
  144. package/src/services/api/search.ts +16 -16
  145. package/src/services/api/user.ts +17 -17
  146. package/src/services/restTools.ts +56 -56
  147. package/src/services/v3Api.ts +147 -147
  148. package/src/stores/index.ts +11 -11
  149. package/src/stores/modules/counter.ts +19 -19
  150. package/src/stores/modules/routeCache.ts +23 -23
  151. package/src/stores/modules/setting.ts +76 -76
  152. package/src/stores/modules/user.ts +235 -235
  153. package/src/stores/mutation-type.ts +7 -7
  154. package/src/styles/app.less +36 -36
  155. package/src/styles/login.less +109 -109
  156. package/src/styles/var.less +16 -16
  157. package/src/types/env.d.ts +16 -16
  158. package/src/types/settings.ts +1 -1
  159. package/src/types/vue-router.d.ts +9 -9
  160. package/src/utils/Storage.ts +124 -124
  161. package/src/utils/authority-utils.ts +84 -84
  162. package/src/utils/common.ts +41 -41
  163. package/src/utils/crypto.ts +39 -39
  164. package/src/utils/dataUtil.ts +42 -42
  165. package/src/utils/dictUtil.ts +52 -52
  166. package/src/utils/http/index.ts +199 -199
  167. package/src/utils/i18n.ts +72 -72
  168. package/src/utils/indexedDB.ts +195 -195
  169. package/src/utils/inline-px-to-vw.ts +28 -28
  170. package/src/utils/mobileUtil.ts +34 -34
  171. package/src/utils/progress.ts +19 -19
  172. package/src/utils/queryFormDefaultRangePicker.ts +57 -57
  173. package/src/utils/routerUtil.ts +271 -271
  174. package/src/utils/runEvalFunction.ts +13 -13
  175. package/src/utils/secureStorage.ts +71 -71
  176. package/src/utils/set-page-title.ts +5 -5
  177. package/src/utils/validate.ts +6 -6
  178. package/src/utils/wechatUtil.ts +9 -9
  179. package/src/views/chat/index.vue +153 -153
  180. package/src/views/common/LoadError.vue +63 -63
  181. package/src/views/common/NotFound.vue +67 -67
  182. package/src/views/component/EvaluateRecordView/index.vue +40 -40
  183. package/src/views/component/IconifyView/index.vue +504 -507
  184. package/src/views/component/UserDetailView/UserDetailPage.vue +77 -0
  185. package/src/views/component/UserDetailView/index.vue +224 -0
  186. package/src/views/component/XCellDetailView/index.vue +217 -217
  187. package/src/views/component/XCellListView/index.vue +108 -147
  188. package/src/views/component/XFormAppraiseView/index.vue +174 -174
  189. package/src/views/component/XFormGroupView/index.vue +78 -91
  190. package/src/views/component/XFormView/index.vue +27 -107
  191. package/src/views/component/XOlMapView/XLocationPicker/index.vue +118 -118
  192. package/src/views/component/XOlMapView/index.vue +434 -434
  193. package/src/views/component/XOlMapView/testData.ts +64 -64
  194. package/src/views/component/XReportFormIframeView/index.vue +47 -47
  195. package/src/views/component/XReportFormView/index.vue +13 -13
  196. package/src/views/component/XReportGridView/index.vue +17 -17
  197. package/src/views/component/XRequestView/index.vue +234 -234
  198. package/src/views/component/XSignatureView/index.vue +50 -50
  199. package/src/views/component/index.vue +181 -177
  200. package/src/views/component/menu.vue +117 -117
  201. package/src/views/component/notice.vue +46 -46
  202. package/src/views/component/topNav.vue +36 -36
  203. package/src/views/invoiceShow/index.vue +61 -61
  204. package/src/views/user/login/ForgetPasswordForm.vue +94 -94
  205. package/src/views/user/login/LoginForm.vue +346 -346
  206. package/src/views/user/login/LoginTitle.vue +76 -76
  207. package/src/views/user/login/LoginWave.vue +109 -109
  208. package/src/views/user/login/index.vue +22 -22
  209. package/src/views/user/my/comm/ModifyPassword.vue +346 -346
  210. package/src/views/user/my/index.vue +340 -340
  211. package/src/views/userRecords/AbnormalAlarmRecords.vue +21 -0
  212. package/src/views/userRecords/CardReplacementRecords.vue +21 -0
  213. package/src/views/userRecords/ChangeRecords.vue +19 -0
  214. package/src/views/userRecords/CommandViewRecords.vue +20 -0
  215. package/src/views/userRecords/GasCompensationRecords.vue +20 -0
  216. package/src/views/userRecords/InstrumentCollectionRecords.vue +21 -0
  217. package/src/views/userRecords/MeterRecords.vue +20 -0
  218. package/src/views/userRecords/OperateRecords.vue +51 -0
  219. package/src/views/userRecords/OtherChargeRecords.vue +19 -0
  220. package/src/views/userRecords/PaymentRecords.vue +28 -0
  221. package/src/views/userRecords/PriceAdjustmentRecords.vue +19 -0
  222. package/src/views/userRecords/ReplacementRecords.vue +19 -0
  223. package/src/views/userRecords/SafetyRecords.vue +19 -0
  224. package/src/views/userRecords/TransactionRecords.vue +21 -0
  225. package/src/views/userRecords/TransferRecords.vue +19 -0
  226. package/src/views/userRecords/operateRecordDetail/index.vue +316 -0
  227. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AddUserDetail.vue +124 -0
  228. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AdvanceDeliveryDetail.vue +88 -0
  229. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AutoAccountsCancelDetail.vue +205 -0
  230. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AutoAccountsDetail.vue +192 -0
  231. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/BankDkDetail.vue +192 -0
  232. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/BankPayDetail.vue +192 -0
  233. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/BlacklistDetail.vue +153 -0
  234. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CancellationDetail.vue +101 -0
  235. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CardMeterCenterCancelDetail.vue +127 -0
  236. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CardMeterCenterDetail.vue +153 -0
  237. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CardOverUserDetail.vue +153 -0
  238. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ChangeMeterCancelDetail.vue +166 -0
  239. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ChangeMeterDetail.vue +205 -0
  240. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/DisableManageDetail.vue +127 -0
  241. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/EnableManageDetail.vue +114 -0
  242. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/FaZheChangeDetail.vue +124 -0
  243. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/FeeDeductionDetail.vue +153 -0
  244. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/GasPriceChangeDetail.vue +126 -0
  245. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/InputtorChangeDetail.vue +126 -0
  246. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/IotMeterCenterCancelDetail.vue +114 -0
  247. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/IotMeterCenterDetail.vue +127 -0
  248. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/IotOpenDetail.vue +88 -0
  249. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/MachineCardDetail.vue +101 -0
  250. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/MachineMeterCenterCancelDetail.vue +218 -0
  251. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/MachineMeterCenterDetail.vue +153 -0
  252. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OffGasAddGasDetail.vue +140 -0
  253. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OtherChargeCancelDetail.vue +127 -0
  254. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OtherChargeDetail.vue +114 -0
  255. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OverUserChangeDetail.vue +127 -0
  256. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ReBillDetail.vue +127 -0
  257. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/RefundDetail.vue +114 -0
  258. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ReplaceCardManageCancelDetail.vue +127 -0
  259. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ReplaceCardManageDetail.vue +114 -0
  260. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/SaleCardGasDetail.vue +140 -0
  261. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/TransferManageCancelDetail.vue +152 -0
  262. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/TransferManageDetail.vue +178 -0
  263. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/UserChangeDetail.vue +123 -0
  264. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/WechatPayDetail.vue +192 -0
  265. package/src/views/userRecords/types.ts +66 -0
  266. package/tsconfig.json +39 -39
  267. package/uno.config.ts +82 -78
  268. package/vite.config.ts +118 -118
@@ -1,102 +1,102 @@
1
- <script setup lang="ts">
2
- import { CellGroup as VanCellGroup, Field as VanField } from 'vant'
3
- import { defineExpose, defineProps, onMounted, onUnmounted, ref } from 'vue'
4
-
5
- interface UserFormProps {
6
- setRef?: (refValue: any) => void
7
- removeRef?: (refValue: any) => void
8
- formGroupName?: string
9
- formData?: any
10
- }
11
-
12
- const props = withDefaults(defineProps<UserFormProps>(), {
13
- setRef: () => {},
14
- removeRef: () => {},
15
- formGroupName: 'userInfo',
16
- formData: () => ({}),
17
- })
18
-
19
- const formData = ref({
20
- name: '',
21
- phone: '',
22
- email: '',
23
- ...props.formData,
24
- })
25
-
26
- async function validate() {
27
- if (!formData.value.name) {
28
- throw new Error('姓名不能为空')
29
- }
30
- if (!formData.value.phone) {
31
- throw new Error('手机号不能为空')
32
- }
33
- const phoneRegex = /^1[3-9]\d{9}$/
34
- if (!phoneRegex.test(formData.value.phone)) {
35
- throw new Error('手机号格式不正确')
36
- }
37
- return Promise.resolve()
38
- }
39
-
40
- function getFormData() {
41
- return {
42
- name: formData.value.name,
43
- phone: formData.value.phone,
44
- email: formData.value.email,
45
- }
46
- }
47
-
48
- function resetForm() {
49
- formData.value = {
50
- name: '',
51
- phone: '',
52
- email: '',
53
- }
54
- }
55
-
56
- const exposeObj = {
57
- validate,
58
- getFormData,
59
- resetForm,
60
- formGroupName: props.formGroupName,
61
- }
62
-
63
- defineExpose(exposeObj)
64
-
65
- onMounted(() => {
66
- props.setRef(exposeObj)
67
- })
68
-
69
- onUnmounted(() => {
70
- props.removeRef(exposeObj)
71
- })
72
- </script>
73
-
74
- <template>
75
- <div class="user-form">
76
- <VanCellGroup inset>
77
- <VanField
78
- v-model="formData.name"
79
- label="姓名"
80
- placeholder="请输入姓名"
81
- :rules="[{ required: true, message: '请输入姓名' }]"
82
- />
83
- <VanField
84
- v-model="formData.phone"
85
- label="手机号"
86
- placeholder="请输入手机号"
87
- :rules="[{ required: true, message: '请输入手机号' }]"
88
- />
89
- <VanField
90
- v-model="formData.email"
91
- label="邮箱"
92
- placeholder="请输入邮箱"
93
- />
94
- </VanCellGroup>
95
- </div>
96
- </template>
97
-
98
- <style scoped lang="less">
99
- .user-form {
100
- padding: 16px;
101
- }
1
+ <script setup lang="ts">
2
+ import { CellGroup as VanCellGroup, Field as VanField } from 'vant'
3
+ import { defineExpose, defineProps, onMounted, onUnmounted, ref } from 'vue'
4
+
5
+ interface UserFormProps {
6
+ setRef?: (refValue: any) => void
7
+ removeRef?: (refValue: any) => void
8
+ formGroupName?: string
9
+ formData?: any
10
+ }
11
+
12
+ const props = withDefaults(defineProps<UserFormProps>(), {
13
+ setRef: () => {},
14
+ removeRef: () => {},
15
+ formGroupName: 'userInfo',
16
+ formData: () => ({}),
17
+ })
18
+
19
+ const formData = ref({
20
+ name: '',
21
+ phone: '',
22
+ email: '',
23
+ ...props.formData,
24
+ })
25
+
26
+ async function validate() {
27
+ if (!formData.value.name) {
28
+ throw new Error('姓名不能为空')
29
+ }
30
+ if (!formData.value.phone) {
31
+ throw new Error('手机号不能为空')
32
+ }
33
+ const phoneRegex = /^1[3-9]\d{9}$/
34
+ if (!phoneRegex.test(formData.value.phone)) {
35
+ throw new Error('手机号格式不正确')
36
+ }
37
+ return Promise.resolve()
38
+ }
39
+
40
+ function getFormData() {
41
+ return {
42
+ name: formData.value.name,
43
+ phone: formData.value.phone,
44
+ email: formData.value.email,
45
+ }
46
+ }
47
+
48
+ function resetForm() {
49
+ formData.value = {
50
+ name: '',
51
+ phone: '',
52
+ email: '',
53
+ }
54
+ }
55
+
56
+ const exposeObj = {
57
+ validate,
58
+ getFormData,
59
+ resetForm,
60
+ formGroupName: props.formGroupName,
61
+ }
62
+
63
+ defineExpose(exposeObj)
64
+
65
+ onMounted(() => {
66
+ props.setRef(exposeObj)
67
+ })
68
+
69
+ onUnmounted(() => {
70
+ props.removeRef(exposeObj)
71
+ })
72
+ </script>
73
+
74
+ <template>
75
+ <div class="user-form">
76
+ <VanCellGroup inset>
77
+ <VanField
78
+ v-model="formData.name"
79
+ label="姓名"
80
+ placeholder="请输入姓名"
81
+ :rules="[{ required: true, message: '请输入姓名' }]"
82
+ />
83
+ <VanField
84
+ v-model="formData.phone"
85
+ label="手机号"
86
+ placeholder="请输入手机号"
87
+ :rules="[{ required: true, message: '请输入手机号' }]"
88
+ />
89
+ <VanField
90
+ v-model="formData.email"
91
+ label="邮箱"
92
+ placeholder="请输入邮箱"
93
+ />
94
+ </VanCellGroup>
95
+ </div>
96
+ </template>
97
+
98
+ <style scoped lang="less">
99
+ .user-form {
100
+ padding: 16px;
101
+ }
102
102
  </style>
@@ -1,240 +1,240 @@
1
- <script setup lang="ts">
2
- import XForm from '@af-mobile-client-vue3/components/data/XForm/index.vue'
3
- import { getConfigByName } from '@af-mobile-client-vue3/services/api/common'
4
- import { Button as VanButton, Tab as VanTab, Tabs as VanTabs } from 'vant'
5
- import { computed, defineEmits, defineProps, onBeforeMount, onMounted, ref, useSlots, watch } from 'vue'
6
-
7
- const props = withDefaults(defineProps<{
8
- configName?: string
9
- serviceName?: string
10
- groupFormData?: object
11
- mode?: string
12
- isScrollspy?: boolean
13
- formShow?: any
14
- showTabHeader?: boolean
15
- }>(), {
16
- configName: '',
17
- serviceName: undefined,
18
- groupFormData: () => ({}),
19
- mode: '查询',
20
- isScrollspy: true,
21
- formShow: undefined,
22
- showTabHeader: true,
23
- })
24
- const emit = defineEmits(['submit', 'xFormItemEmitFunc'])
25
-
26
- const groupItems = ref([])
27
- const formData = ref({})
28
- const submitGroup = ref(false)
29
- const submitSimple = ref(false)
30
- const isInit = ref(false)
31
-
32
- const slots = useSlots()
33
- const renderableGroupItems = computed(() => {
34
- return groupItems.value.filter((item) => {
35
- if (props.formShow && (item.groupName || item.slotName)) {
36
- const showKey = `show${item.groupName || item.slotName}`
37
- if (props.formShow[showKey] === false) {
38
- return false
39
- }
40
- }
41
- if (item.formGroupType === 'slot') {
42
- return !!(item.slotName && slots[item.slotName])
43
- }
44
- return true
45
- })
46
- })
47
-
48
- // 组件初始化函数
49
- function init() {
50
- formData.value = props.groupFormData
51
- getConfigByName(props.configName, (result) => {
52
- if (result?.groups) {
53
- groupItems.value = result.groups
54
- result.groups.forEach((group) => {
55
- if (!formData.value[group.groupName] && group.formGroupType !== 'slot')
56
- formData.value[group.groupName] = {}
57
- if (group.showSubmitBtn)
58
- submitGroup.value = true
59
- })
60
- }
61
- else {
62
- submitSimple.value = result?.showSubmitBtn
63
- groupItems.value = [{ ...result }]
64
- }
65
- isInit.value = true
66
- }, props.serviceName)
67
- }
68
- // watch(() => props.groupFormData, (_val) => {
69
- // formData.value = { ...formData.value, ...props.groupFormData }
70
- // })
71
- onBeforeMount(() => {
72
- init()
73
- })
74
- interface XFormLike {
75
- validate: () => Promise<void>
76
- formGroupName?: string
77
- form?: any
78
- getFormData?: () => object
79
- }
80
- const xFormListRef = ref<XFormLike[]>([])
81
-
82
- // 注册表单实例,避免重复
83
- function setRef(refValue: XFormLike) {
84
- if (refValue && !xFormListRef.value.includes(refValue)) {
85
- xFormListRef.value.push(refValue)
86
- }
87
- }
88
- // 注销表单实例
89
- function removeRef(refValue: XFormLike) {
90
- const idx = xFormListRef.value.indexOf(refValue)
91
- if (idx !== -1)
92
- xFormListRef.value.splice(idx, 1)
93
- }
94
-
95
- async function submit() {
96
- console.log(props.groupFormData)
97
- for (const res of xFormListRef.value) {
98
- try {
99
- await res.validate()
100
- if (res.formGroupName && typeof res.getFormData === 'function') {
101
- formData.value[res.formGroupName] = res.getFormData()
102
- }
103
- }
104
- catch (msg) {
105
- console.log('error:', msg)
106
- return
107
- }
108
- }
109
- emit('submit', formData.value)
110
- }
111
- function emitFunc(func: any, data: any, value: any) {
112
- emit(func, data, value)
113
- emit('xFormItemEmitFunc', func, data, value)
114
- }
115
- // 动态计算 offsetTop = var(--van-nav-bar-height) + 10px
116
- const offsetTop = ref(0)
117
- onMounted(() => {
118
- const root = document.documentElement
119
- const navBarHeight = getComputedStyle(root).getPropertyValue('--van-nav-bar-height')
120
- offsetTop.value = Number.parseInt(navBarHeight, 10) || 60 + 10
121
- })
122
-
123
- defineExpose({ init, removeRef, xFormListRef })
124
- </script>
125
-
126
- <template>
127
- <div v-if="isInit" id="x-form-group">
128
- <VanTabs :scrollspy="props.isScrollspy" sticky :offset-top="offsetTop" :show-header="props.showTabHeader">
129
- <VanTab
130
- v-for="(item, index) in renderableGroupItems"
131
- :key="item.groupName ? (item.groupName + index) : index"
132
- :title="item.describe ? item.describe : item.tableName "
133
- >
134
- <div
135
- class="x-form-group-item"
136
- :class="{ 'is-last': index === renderableGroupItems.length - 1 }"
137
- >
138
- <div v-if="item.describe && props.isScrollspy && (item.groupName || item.slotName)" class="form-group-title">
139
- <span class="form-group-bar" />
140
- <span class="form-group-text">{{ item.describe }}</span>
141
- </div>
142
- <template v-if="item.formGroupType === 'slot'">
143
- <slot
144
- :name="item.slotName"
145
- :item="item"
146
- :form-data="item.groupName ? formData[item.groupName] : formData"
147
- :set-ref="setRef"
148
- :remove-ref="removeRef"
149
- />
150
- </template>
151
- <template v-else>
152
- <XForm
153
- ref="xFormListRef"
154
- :mode="props.mode"
155
- :is-group-form="true"
156
- :group-form-items="item"
157
- :form-data="item.groupName ? formData[item.groupName] : formData"
158
- :form-name="item.groupName"
159
- :service-name="props.serviceName"
160
- :submit-button="submitSimple"
161
- @on-submit="submit"
162
- @x-form-item-emit-func="emitFunc"
163
- />
164
- </template>
165
- </div>
166
- </VanTab>
167
- </VanTabs>
168
- <div class="form-footer-fixed">
169
- <VanButton v-if="submitGroup" round block type="primary" @click="submit">
170
- 提交
171
- </VanButton>
172
- </div>
173
- </div>
174
- </template>
175
-
176
- <style scoped lang="less">
177
- #x-form-group {
178
- display: flex;
179
- flex-direction: column;
180
- background-color: rgb(247, 248, 250);
181
- height: calc(100vh - var(--van-nav-bar-height) - 20px);
182
- flex: 1;
183
- overflow-y: auto;
184
- // 让 Tabs 区域自适应剩余空间
185
- .van-tabs {
186
- flex: 1;
187
- min-height: 0;
188
- overflow: auto;
189
- }
190
- .x-form-group-item {
191
- margin-bottom: 20px;
192
- }
193
- .form-footer-fixed {
194
- position: fixed;
195
- bottom: 0;
196
- left: 0;
197
- width: 100%;
198
-
199
- padding: 12px;
200
- box-sizing: border-box;
201
-
202
- /* 阴影效果 - 向上投射 */
203
- box-shadow:
204
- 0 -4px 12px rgba(0, 0, 0, 0.1),
205
- 0 -2px 4px rgba(0, 0, 0, 0.06);
206
-
207
- /* 毛玻璃背景 (移动端高级效果) */
208
- background-color: rgba(255, 255, 255, 0.85);
209
- -webkit-backdrop-filter: blur(10px);
210
- backdrop-filter: blur(10px);
211
-
212
- /* 边框增强立体感 */
213
- border-top: 1px solid rgba(0, 0, 0, 0.05);
214
- }
215
- }
216
- .x-form-group-item.is-last {
217
- min-height: calc(100vh - var(--van-nav-bar-height) - 40px);
218
- }
219
- .form-group-title {
220
- display: flex;
221
- align-items: center;
222
- padding-top: 12px;
223
- background: none;
224
- margin: 0 0 16px 4px;
225
- }
226
- .form-group-bar {
227
- width: 4px;
228
- height: 20px;
229
- background: #1989fa;
230
- border-radius: 4px;
231
- margin-right: 8px;
232
- flex-shrink: 0;
233
- }
234
- .form-group-text {
235
- font-weight: 600;
236
- font-size: 15px;
237
- color: #222;
238
- letter-spacing: 0.5px;
239
- }
240
- </style>
1
+ <script setup lang="ts">
2
+ import XForm from '@af-mobile-client-vue3/components/data/XForm/index.vue'
3
+ import { getConfigByName } from '@af-mobile-client-vue3/services/api/common'
4
+ import { Button as VanButton, Tab as VanTab, Tabs as VanTabs } from 'vant'
5
+ import { computed, defineEmits, defineProps, onBeforeMount, onMounted, ref, useSlots } from 'vue'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ configName?: string
9
+ serviceName?: string
10
+ groupFormData?: object
11
+ mode?: string
12
+ isScrollspy?: boolean
13
+ formShow?: any
14
+ showTabHeader?: boolean
15
+ }>(), {
16
+ configName: '',
17
+ serviceName: undefined,
18
+ groupFormData: () => ({}),
19
+ mode: '查询',
20
+ isScrollspy: true,
21
+ formShow: undefined,
22
+ showTabHeader: true,
23
+ })
24
+ const emit = defineEmits(['submit', 'xFormItemEmitFunc'])
25
+
26
+ const groupItems = ref([])
27
+ const formData = ref({})
28
+ const submitGroup = ref(false)
29
+ const submitSimple = ref(false)
30
+ const isInit = ref(false)
31
+
32
+ const slots = useSlots()
33
+ const renderableGroupItems = computed(() => {
34
+ return groupItems.value.filter((item) => {
35
+ if (props.formShow && (item.groupName || item.slotName)) {
36
+ const showKey = `show${item.groupName || item.slotName}`
37
+ if (props.formShow[showKey] === false) {
38
+ return false
39
+ }
40
+ }
41
+ if (item.formGroupType === 'slot') {
42
+ return !!(item.slotName && slots[item.slotName])
43
+ }
44
+ return true
45
+ })
46
+ })
47
+
48
+ // 组件初始化函数
49
+ function init() {
50
+ formData.value = props.groupFormData
51
+ getConfigByName(props.configName, (result) => {
52
+ if (result?.groups) {
53
+ groupItems.value = result.groups
54
+ result.groups.forEach((group) => {
55
+ if (!formData.value[group.groupName] && group.formGroupType !== 'slot')
56
+ formData.value[group.groupName] = {}
57
+ if (group.showSubmitBtn)
58
+ submitGroup.value = true
59
+ })
60
+ }
61
+ else {
62
+ submitSimple.value = result?.showSubmitBtn
63
+ groupItems.value = [{ ...result }]
64
+ }
65
+ isInit.value = true
66
+ }, props.serviceName)
67
+ }
68
+ // watch(() => props.groupFormData, (_val) => {
69
+ // formData.value = { ...formData.value, ...props.groupFormData }
70
+ // })
71
+ onBeforeMount(() => {
72
+ init()
73
+ })
74
+ interface XFormLike {
75
+ validate: () => Promise<void>
76
+ formGroupName?: string
77
+ form?: any
78
+ getFormData?: () => object
79
+ }
80
+ const xFormListRef = ref<XFormLike[]>([])
81
+
82
+ // 注册表单实例,避免重复
83
+ function setRef(refValue: XFormLike) {
84
+ if (refValue && !xFormListRef.value.includes(refValue)) {
85
+ xFormListRef.value.push(refValue)
86
+ }
87
+ }
88
+ // 注销表单实例
89
+ function removeRef(refValue: XFormLike) {
90
+ const idx = xFormListRef.value.indexOf(refValue)
91
+ if (idx !== -1)
92
+ xFormListRef.value.splice(idx, 1)
93
+ }
94
+
95
+ async function submit() {
96
+ console.log(props.groupFormData)
97
+ for (const res of xFormListRef.value) {
98
+ try {
99
+ await res.validate()
100
+ if (res.formGroupName && typeof res.getFormData === 'function') {
101
+ formData.value[res.formGroupName] = res.getFormData()
102
+ }
103
+ }
104
+ catch (msg) {
105
+ console.log('error:', msg)
106
+ return
107
+ }
108
+ }
109
+ emit('submit', formData.value)
110
+ }
111
+ function emitFunc(func: any, data: any, value: any) {
112
+ emit(func, data, value)
113
+ emit('xFormItemEmitFunc', func, data, value)
114
+ }
115
+ // 动态计算 offsetTop = var(--van-nav-bar-height) + 10px
116
+ const offsetTop = ref(0)
117
+ onMounted(() => {
118
+ const root = document.documentElement
119
+ const navBarHeight = getComputedStyle(root).getPropertyValue('--van-nav-bar-height')
120
+ offsetTop.value = Number.parseInt(navBarHeight, 10) || 60 + 10
121
+ })
122
+
123
+ defineExpose({ init, removeRef, xFormListRef })
124
+ </script>
125
+
126
+ <template>
127
+ <div v-if="isInit" id="x-form-group">
128
+ <VanTabs :scrollspy="props.isScrollspy" sticky :offset-top="offsetTop" :show-header="props.showTabHeader">
129
+ <VanTab
130
+ v-for="(item, index) in renderableGroupItems"
131
+ :key="item.groupName ? (item.groupName + index) : index"
132
+ :title="item.describe ? item.describe : item.tableName "
133
+ >
134
+ <div
135
+ class="x-form-group-item"
136
+ :class="{ 'is-last': index === renderableGroupItems.length - 1 }"
137
+ >
138
+ <div v-if="item.describe && props.isScrollspy && (item.groupName || item.slotName)" class="form-group-title">
139
+ <span class="form-group-bar" />
140
+ <span class="form-group-text">{{ item.describe }}</span>
141
+ </div>
142
+ <template v-if="item.formGroupType === 'slot'">
143
+ <slot
144
+ :name="item.slotName"
145
+ :item="item"
146
+ :form-data="item.groupName ? formData[item.groupName] : formData"
147
+ :set-ref="setRef"
148
+ :remove-ref="removeRef"
149
+ />
150
+ </template>
151
+ <template v-else>
152
+ <XForm
153
+ ref="xFormListRef"
154
+ :mode="props.mode"
155
+ :is-group-form="true"
156
+ :group-form-items="item"
157
+ :form-data="item.groupName ? formData[item.groupName] : formData"
158
+ :form-name="item.groupName"
159
+ :service-name="props.serviceName"
160
+ :submit-button="submitSimple"
161
+ @on-submit="submit"
162
+ @x-form-item-emit-func="emitFunc"
163
+ />
164
+ </template>
165
+ </div>
166
+ </VanTab>
167
+ </VanTabs>
168
+ <div class="form-footer-fixed">
169
+ <VanButton v-if="submitGroup" round block type="primary" @click="submit">
170
+ 提交
171
+ </VanButton>
172
+ </div>
173
+ </div>
174
+ </template>
175
+
176
+ <style scoped lang="less">
177
+ #x-form-group {
178
+ display: flex;
179
+ flex-direction: column;
180
+ background-color: rgb(247, 248, 250);
181
+ height: calc(100vh - var(--van-nav-bar-height) - 20px);
182
+ flex: 1;
183
+ overflow-y: auto;
184
+ // 让 Tabs 区域自适应剩余空间
185
+ .van-tabs {
186
+ flex: 1;
187
+ min-height: 0;
188
+ overflow: auto;
189
+ }
190
+ .x-form-group-item {
191
+ margin-bottom: 20px;
192
+ }
193
+ .form-footer-fixed {
194
+ position: fixed;
195
+ bottom: 0;
196
+ left: 0;
197
+ width: 100%;
198
+
199
+ padding: 12px;
200
+ box-sizing: border-box;
201
+
202
+ /* 阴影效果 - 向上投射 */
203
+ box-shadow:
204
+ 0 -4px 12px rgba(0, 0, 0, 0.1),
205
+ 0 -2px 4px rgba(0, 0, 0, 0.06);
206
+
207
+ /* 毛玻璃背景 (移动端高级效果) */
208
+ background-color: rgba(255, 255, 255, 0.85);
209
+ -webkit-backdrop-filter: blur(10px);
210
+ backdrop-filter: blur(10px);
211
+
212
+ /* 边框增强立体感 */
213
+ border-top: 1px solid rgba(0, 0, 0, 0.05);
214
+ }
215
+ }
216
+ .x-form-group-item.is-last {
217
+ min-height: calc(100vh - var(--van-nav-bar-height) - 40px);
218
+ }
219
+ .form-group-title {
220
+ display: flex;
221
+ align-items: center;
222
+ padding-top: 12px;
223
+ background: none;
224
+ margin: 0 0 16px 4px;
225
+ }
226
+ .form-group-bar {
227
+ width: 4px;
228
+ height: 20px;
229
+ background: #1989fa;
230
+ border-radius: 4px;
231
+ margin-right: 8px;
232
+ flex-shrink: 0;
233
+ }
234
+ .form-group-text {
235
+ font-weight: 600;
236
+ font-size: 15px;
237
+ color: #222;
238
+ letter-spacing: 0.5px;
239
+ }
240
+ </style>