af-mobile-client-vue3 1.3.35 → 1.3.37

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 (281) hide show
  1. package/.cursorrules +60 -60
  2. package/.editorconfig +9 -9
  3. package/.env +10 -10
  4. package/.env.development +1 -1
  5. package/.env.production +1 -1
  6. package/.node-version +1 -1
  7. package/.vscode/extensions.json +12 -12
  8. package/.vscode/settings.json +68 -68
  9. package/CLAUDE.md +218 -218
  10. package/README.md +182 -182
  11. package/af-example-mobile-vue-web.iml +9 -9
  12. package/build/vite/index.ts +98 -98
  13. package/build/vite/optimize.ts +34 -34
  14. package/build/vite/vconsole.ts +47 -47
  15. package/commitlint.config.ts +32 -32
  16. package/compress.js +36 -36
  17. package/eslint.config.ts +31 -31
  18. package/index.html +23 -23
  19. package/mock/data.ts +20 -20
  20. package/mock/index.ts +7 -7
  21. package/mock/modules/prose.mock.ts +13 -13
  22. package/mock/modules/user.mock.ts +95 -95
  23. package/mock/util.ts +19 -19
  24. package/netlify.toml +12 -12
  25. package/package.json +114 -114
  26. package/postcss.config.ts +27 -27
  27. package/public/favicon.svg +4 -4
  28. package/public/safari-pinned-tab.svg +4 -4
  29. package/scripts/verifyCommit.js +19 -19
  30. package/src/App.vue +79 -79
  31. package/src/api/auth/index.ts +77 -77
  32. package/src/api/auth/types.ts +200 -200
  33. package/src/api/mock/index.ts +30 -30
  34. package/src/api/user/index.ts +40 -40
  35. package/src/assets/img/user/login/background-shadow-1.svg +20 -20
  36. package/src/assets/img/user/login/logo-background.svg +20 -20
  37. package/src/bootstrap.ts +26 -26
  38. package/src/components/core/BeautifulLoading/index.vue +52 -52
  39. package/src/components/core/ImageUploader/index.vue +251 -251
  40. package/src/components/core/NavBar/index.vue +53 -53
  41. package/src/components/core/Tabbar/index.vue +32 -32
  42. package/src/components/core/Uploader/index.vue +124 -124
  43. package/src/components/core/XGridDropOption/index.vue +154 -154
  44. package/src/components/core/XMultiSelect/index.vue +183 -183
  45. package/src/components/core/XSelect/index.vue +149 -149
  46. package/src/components/data/CardContainer/CardContainer.vue +118 -118
  47. package/src/components/data/CardContainer/CardHeader.vue +99 -99
  48. package/src/components/data/InfoDisplay/index.vue +132 -132
  49. package/src/components/data/UserDetail/api.ts +24 -24
  50. package/src/components/data/UserDetail/index.vue +620 -620
  51. package/src/components/data/UserDetail/recordEntries.ts +159 -159
  52. package/src/components/data/UserDetail/types.ts +26 -26
  53. package/src/components/data/XBadge/index.vue +82 -82
  54. package/src/components/data/XCellDetail/index.vue +105 -105
  55. package/src/components/data/XCellList/XCellList.md +432 -432
  56. package/src/components/data/XCellList/index.vue +1436 -1436
  57. package/src/components/data/XCellListFilter/QrScanner/index.vue +207 -207
  58. package/src/components/data/XCellListFilter/QrScanner/startScanAnimation.ts +53 -53
  59. package/src/components/data/XCellListFilter/VpnRecognition/index.vue +119 -119
  60. package/src/components/data/XCellListFilter/index.vue +705 -705
  61. package/src/components/data/XForm/index.vue +659 -659
  62. package/src/components/data/XFormGroup/doc/DeviceForm.vue +122 -122
  63. package/src/components/data/XFormGroup/doc/FormGroupDemo.vue +56 -56
  64. package/src/components/data/XFormGroup/doc/README.md +286 -286
  65. package/src/components/data/XFormGroup/doc/UserForm.vue +102 -102
  66. package/src/components/data/XFormGroup/index.vue +240 -240
  67. package/src/components/data/XFormItem/index.vue +1311 -1311
  68. package/src/components/data/XOlMap/README.md +227 -227
  69. package/src/components/data/XOlMap/XLocationPicker/index.vue +226 -226
  70. package/src/components/data/XOlMap/index.vue +1490 -1490
  71. package/src/components/data/XOlMap/types.ts +149 -149
  72. package/src/components/data/XOlMap/utils/wgs84ToGcj02.ts +171 -171
  73. package/src/components/data/XReportForm/DateTimeSecondsPicker.vue +208 -208
  74. package/src/components/data/XReportForm/XReportFormJsonRender.vue +220 -220
  75. package/src/components/data/XReportForm/index.vue +1393 -1393
  76. package/src/components/data/XReportGrid/XAddReport/XAddReport.vue +198 -198
  77. package/src/components/data/XReportGrid/XAddReport/index.js +3 -3
  78. package/src/components/data/XReportGrid/XAddReport/index.md +53 -53
  79. package/src/components/data/XReportGrid/XAddReport/index.ts +10 -10
  80. package/src/components/data/XReportGrid/XReport.vue +960 -960
  81. package/src/components/data/XReportGrid/XReportDemo.vue +33 -33
  82. package/src/components/data/XReportGrid/XReportDesign.vue +597 -597
  83. package/src/components/data/XReportGrid/XReportDrawer/XReportDrawer.vue +148 -148
  84. package/src/components/data/XReportGrid/XReportDrawer/index.js +3 -3
  85. package/src/components/data/XReportGrid/XReportDrawer/index.ts +10 -10
  86. package/src/components/data/XReportGrid/XReportJsonRender.vue +399 -399
  87. package/src/components/data/XReportGrid/XReportTrGroup.vue +592 -592
  88. package/src/components/data/XReportGrid/index.md +46 -46
  89. package/src/components/data/XReportGrid/print.js +184 -184
  90. package/src/components/data/XSignature/index.vue +284 -284
  91. package/src/components/data/XTag/index.vue +10 -10
  92. package/src/components/layout/NormalDataLayout/index.vue +69 -69
  93. package/src/components/layout/TabBarLayout/index.vue +40 -40
  94. package/src/composables/dark.ts +5 -5
  95. package/src/config/routes.ts +9 -9
  96. package/src/constants/index.ts +2 -2
  97. package/src/enums/requestEnum.ts +25 -25
  98. package/src/expression/ExpressionRunner.ts +28 -28
  99. package/src/expression/TestExpression.ts +510 -510
  100. package/src/expression/core/Delegate.ts +116 -116
  101. package/src/expression/core/Expression.ts +1359 -1359
  102. package/src/expression/core/Program.ts +985 -985
  103. package/src/expression/core/Token.ts +29 -29
  104. package/src/expression/enums/ExpressionType.ts +81 -81
  105. package/src/expression/enums/TokenType.ts +11 -11
  106. package/src/expression/exception/BreakWayException.ts +2 -2
  107. package/src/expression/exception/ContinueWayException.ts +2 -2
  108. package/src/expression/exception/ExpressionException.ts +29 -29
  109. package/src/expression/exception/ReturnWayException.ts +14 -14
  110. package/src/expression/exception/ServiceException.ts +22 -22
  111. package/src/expression/instances/JSONArray.ts +52 -52
  112. package/src/expression/instances/JSONObject.ts +118 -118
  113. package/src/expression/instances/LogicConsole.ts +31 -31
  114. package/src/font-style/font.css +4 -4
  115. package/src/hooks/useBoolean.ts +26 -26
  116. package/src/hooks/useCommon.ts +9 -9
  117. package/src/hooks/useLoading.ts +16 -16
  118. package/src/hooks/useLogin.ts +97 -97
  119. package/src/icons/svg/check-in.svg +32 -32
  120. package/src/icons/svg/dark.svg +4 -4
  121. package/src/icons/svg/github.svg +4 -4
  122. package/src/icons/svg/light.svg +4 -4
  123. package/src/icons/svg/link.svg +4 -4
  124. package/src/icons/svgo.yml +22 -22
  125. package/src/layout/GridView/index.vue +16 -16
  126. package/src/layout/PageLayout.vue +9 -9
  127. package/src/layout/SingleLayout.vue +9 -9
  128. package/src/locales/en-US.json +128 -128
  129. package/src/locales/zh-CN.json +128 -128
  130. package/src/logic/LogicRunner.ts +67 -67
  131. package/src/logic/TestLogic.ts +13 -13
  132. package/src/logic/plugins/common/DateTools.ts +35 -35
  133. package/src/logic/plugins/common/VueTools.ts +30 -30
  134. package/src/logic/plugins/index.ts +7 -7
  135. package/src/main.ts +44 -44
  136. package/src/plugins/AppData.ts +38 -38
  137. package/src/plugins/GetLoginInfoService.ts +10 -10
  138. package/src/plugins/collectIcons.ts +10 -10
  139. package/src/plugins/index.ts +11 -11
  140. package/src/router/README.md +8 -8
  141. package/src/router/external-routes.ts +60 -60
  142. package/src/router/guards.ts +131 -131
  143. package/src/router/index.ts +35 -35
  144. package/src/router/invoiceRoutes.ts +33 -33
  145. package/src/router/routes.ts +421 -421
  146. package/src/services/api/Login.ts +6 -6
  147. package/src/services/api/common.ts +109 -109
  148. package/src/services/api/index.ts +7 -7
  149. package/src/services/api/manage.ts +8 -8
  150. package/src/services/api/search.ts +16 -16
  151. package/src/services/api/user.ts +17 -17
  152. package/src/services/restTools.ts +56 -56
  153. package/src/services/v3Api.ts +147 -147
  154. package/src/stores/index.ts +13 -13
  155. package/src/stores/modules/counter.ts +19 -19
  156. package/src/stores/modules/homeApp.ts +55 -55
  157. package/src/stores/modules/routeCache.ts +22 -22
  158. package/src/stores/modules/setting.ts +87 -87
  159. package/src/stores/modules/user.ts +326 -326
  160. package/src/stores/mutation-type.ts +12 -12
  161. package/src/styles/app.less +36 -36
  162. package/src/styles/login.less +109 -109
  163. package/src/styles/var.less +25 -25
  164. package/src/types/auth.ts +89 -89
  165. package/src/types/env.d.ts +16 -16
  166. package/src/types/platform.ts +194 -194
  167. package/src/types/settings.ts +1 -1
  168. package/src/types/vue-router.d.ts +13 -13
  169. package/src/utils/Storage.ts +124 -124
  170. package/src/utils/authority-utils.ts +84 -84
  171. package/src/utils/common.ts +41 -41
  172. package/src/utils/crypto.ts +39 -39
  173. package/src/utils/dataUtil.ts +42 -42
  174. package/src/utils/dictUtil.ts +52 -52
  175. package/src/utils/http/index.ts +201 -201
  176. package/src/utils/i18n.ts +72 -72
  177. package/src/utils/indexedDB.ts +195 -195
  178. package/src/utils/inline-px-to-vw.ts +28 -28
  179. package/src/utils/mobileUtil.ts +33 -33
  180. package/src/utils/platform-auth.ts +135 -135
  181. package/src/utils/progress.ts +19 -19
  182. package/src/utils/queryFormDefaultRangePicker.ts +57 -57
  183. package/src/utils/routerUtil.ts +271 -271
  184. package/src/utils/runEvalFunction.ts +13 -13
  185. package/src/utils/secureStorage.ts +70 -70
  186. package/src/utils/set-page-title.ts +5 -5
  187. package/src/utils/validate.ts +6 -6
  188. package/src/views/chat/index.vue +153 -153
  189. package/src/views/common/Forbidden.vue +97 -97
  190. package/src/views/common/LoadError.vue +63 -63
  191. package/src/views/common/NotFound.vue +67 -67
  192. package/src/views/component/EvaluateRecordView/index.vue +40 -40
  193. package/src/views/component/IconifyView/index.vue +504 -504
  194. package/src/views/component/UserDetailView/UserDetailPage.vue +77 -77
  195. package/src/views/component/UserDetailView/index.vue +234 -234
  196. package/src/views/component/XCellDetailView/index.vue +217 -217
  197. package/src/views/component/XCellListView/index.vue +108 -108
  198. package/src/views/component/XFormAppraiseView/index.vue +174 -174
  199. package/src/views/component/XFormGroupView/index.vue +78 -78
  200. package/src/views/component/XFormView/index.vue +27 -27
  201. package/src/views/component/XOlMapView/index.vue +434 -434
  202. package/src/views/component/XOlMapView/testData.ts +64 -64
  203. package/src/views/component/XReportFormIframeView/index.vue +47 -47
  204. package/src/views/component/XReportFormView/index.vue +13 -13
  205. package/src/views/component/XReportGridView/index.vue +17 -17
  206. package/src/views/component/XRequestView/index.vue +234 -234
  207. package/src/views/component/XSignatureView/index.vue +50 -50
  208. package/src/views/component/index.vue +181 -181
  209. package/src/views/component/menu.vue +117 -117
  210. package/src/views/component/notice.vue +46 -46
  211. package/src/views/component/topNav.vue +36 -36
  212. package/src/views/external/index.vue +152 -152
  213. package/src/views/invoiceShow/index.vue +61 -61
  214. package/src/views/loading/AuthLoading.vue +345 -345
  215. package/src/views/user/login/ForgetPasswordForm.vue +94 -94
  216. package/src/views/user/login/LoginForm.vue +350 -350
  217. package/src/views/user/login/LoginTitle.vue +76 -76
  218. package/src/views/user/login/LoginWave.vue +109 -109
  219. package/src/views/user/login/index.vue +22 -22
  220. package/src/views/user/my/comm/ModifyPassword.vue +346 -346
  221. package/src/views/user/my/index.vue +507 -507
  222. package/src/views/user/register/index.vue +952 -952
  223. package/src/views/userRecords/AbnormalAlarmRecords.vue +21 -21
  224. package/src/views/userRecords/CardReplacementRecords.vue +21 -21
  225. package/src/views/userRecords/ChangeRecords.vue +19 -19
  226. package/src/views/userRecords/CommandViewRecords.vue +20 -20
  227. package/src/views/userRecords/GasCompensationRecords.vue +20 -20
  228. package/src/views/userRecords/InstrumentCollectionRecords.vue +21 -21
  229. package/src/views/userRecords/MeterRecords.vue +20 -20
  230. package/src/views/userRecords/OperateRecords.vue +51 -51
  231. package/src/views/userRecords/OtherChargeRecords.vue +19 -19
  232. package/src/views/userRecords/PaymentRecords.vue +28 -28
  233. package/src/views/userRecords/PriceAdjustmentRecords.vue +19 -19
  234. package/src/views/userRecords/ReplacementRecords.vue +19 -19
  235. package/src/views/userRecords/SafetyRecords.vue +19 -19
  236. package/src/views/userRecords/TransactionRecords.vue +21 -21
  237. package/src/views/userRecords/TransferRecords.vue +19 -19
  238. package/src/views/userRecords/operateRecordDetail/index.vue +316 -316
  239. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AddUserDetail.vue +124 -124
  240. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AdvanceDeliveryDetail.vue +88 -88
  241. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AutoAccountsCancelDetail.vue +205 -205
  242. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/AutoAccountsDetail.vue +192 -192
  243. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/BankDkDetail.vue +192 -192
  244. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/BankPayDetail.vue +192 -192
  245. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/BlacklistDetail.vue +153 -153
  246. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CancellationDetail.vue +101 -101
  247. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CardMeterCenterCancelDetail.vue +127 -127
  248. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CardMeterCenterDetail.vue +153 -153
  249. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/CardOverUserDetail.vue +153 -153
  250. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ChangeMeterCancelDetail.vue +166 -166
  251. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ChangeMeterDetail.vue +205 -205
  252. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/DisableManageDetail.vue +127 -127
  253. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/EnableManageDetail.vue +114 -114
  254. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/FaZheChangeDetail.vue +124 -124
  255. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/FeeDeductionDetail.vue +153 -153
  256. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/GasPriceChangeDetail.vue +126 -126
  257. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/InputtorChangeDetail.vue +126 -126
  258. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/IotMeterCenterCancelDetail.vue +114 -114
  259. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/IotMeterCenterDetail.vue +127 -127
  260. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/IotOpenDetail.vue +88 -88
  261. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/MachineCardDetail.vue +101 -101
  262. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/MachineMeterCenterCancelDetail.vue +218 -218
  263. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/MachineMeterCenterDetail.vue +153 -153
  264. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OffGasAddGasDetail.vue +140 -140
  265. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OtherChargeCancelDetail.vue +127 -127
  266. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OtherChargeDetail.vue +114 -114
  267. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/OverUserChangeDetail.vue +127 -127
  268. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ReBillDetail.vue +127 -127
  269. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/RefundDetail.vue +114 -114
  270. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ReplaceCardManageCancelDetail.vue +127 -127
  271. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/ReplaceCardManageDetail.vue +114 -114
  272. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/SaleCardGasDetail.vue +140 -140
  273. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/TransferManageCancelDetail.vue +152 -152
  274. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/TransferManageDetail.vue +178 -178
  275. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/UserChangeDetail.vue +123 -123
  276. package/src/views/userRecords/operateRecordDetail/operateRecordDetails/WechatPayDetail.vue +192 -192
  277. package/src/views/userRecords/types.ts +66 -66
  278. package/tsconfig.json +39 -39
  279. package/uno.config.ts +82 -82
  280. package/vite.config.ts +114 -114
  281. package/.claude/settings.local.json +0 -14
package/src/bootstrap.ts CHANGED
@@ -1,26 +1,26 @@
1
- import type { Router } from 'vue-router'
2
- import guards from '@af-mobile-client-vue3/router/guards'
3
- import { useSettingStore } from '@af-mobile-client-vue3/stores/modules/setting'
4
- import { loadGuards, loadRoutes } from '@af-mobile-client-vue3/utils/routerUtil'
5
-
6
- type GuardFunction = (to: any, from: any, next?: any) => void
7
- interface Guards {
8
- beforeEach?: GuardFunction[]
9
- afterEach?: GuardFunction[]
10
- }
11
-
12
- async function bootstrap(router: Router, customGuard: Guards = {}) {
13
- // 加载路由
14
- loadRoutes()
15
- // 加载路由守卫
16
- loadGuards({ ...guards, ...customGuard }, router)
17
- // 初始化时先加载webMobileConfig,防止登录页拿不到配置信息
18
- try {
19
- await useSettingStore().init()
20
- }
21
- catch (e) {
22
- console.error(e)
23
- }
24
- }
25
-
26
- export default bootstrap
1
+ import type { Router } from 'vue-router'
2
+ import guards from '@af-mobile-client-vue3/router/guards'
3
+ import { useSettingStore } from '@af-mobile-client-vue3/stores/modules/setting'
4
+ import { loadGuards, loadRoutes } from '@af-mobile-client-vue3/utils/routerUtil'
5
+
6
+ type GuardFunction = (to: any, from: any, next?: any) => void
7
+ interface Guards {
8
+ beforeEach?: GuardFunction[]
9
+ afterEach?: GuardFunction[]
10
+ }
11
+
12
+ async function bootstrap(router: Router, customGuard: Guards = {}) {
13
+ // 加载路由
14
+ loadRoutes()
15
+ // 加载路由守卫
16
+ loadGuards({ ...guards, ...customGuard }, router)
17
+ // 初始化时先加载webMobileConfig,防止登录页拿不到配置信息
18
+ try {
19
+ await useSettingStore().init()
20
+ }
21
+ catch (e) {
22
+ console.error(e)
23
+ }
24
+ }
25
+
26
+ export default bootstrap
@@ -1,52 +1,52 @@
1
- <script setup>
2
- </script>
3
-
4
- <template>
5
- <div class="main">
6
- <div class="bird-container">
7
- <div class="bird i-svg:bird" />
8
- </div>
9
- <div class="loading-text">
10
- 加载中,请稍候...
11
- </div>
12
- </div>
13
- </template>
14
-
15
- <style scoped>
16
- .main {
17
- display: flex;
18
- flex-direction: column;
19
- justify-content: center;
20
- align-items: center;
21
- height: 100vh;
22
- }
23
-
24
- .bird-container {
25
- width: 60px;
26
- height: 60px;
27
- animation: fade 3s ease-out infinite;
28
- }
29
-
30
- .bird {
31
- width: 60px;
32
- height: 60px;
33
- }
34
-
35
- .loading-text {
36
- margin-top: 20px;
37
- font-size: 14px;
38
- color: #333;
39
- }
40
-
41
- @keyframes fade {
42
- 0% {
43
- opacity: 1;
44
- }
45
- 50% {
46
- opacity: 0.3;
47
- }
48
- 100% {
49
- opacity: 1;
50
- }
51
- }
52
- </style>
1
+ <script setup>
2
+ </script>
3
+
4
+ <template>
5
+ <div class="main">
6
+ <div class="bird-container">
7
+ <div class="bird i-svg:bird" />
8
+ </div>
9
+ <div class="loading-text">
10
+ 加载中,请稍候...
11
+ </div>
12
+ </div>
13
+ </template>
14
+
15
+ <style scoped>
16
+ .main {
17
+ display: flex;
18
+ flex-direction: column;
19
+ justify-content: center;
20
+ align-items: center;
21
+ height: 100vh;
22
+ }
23
+
24
+ .bird-container {
25
+ width: 60px;
26
+ height: 60px;
27
+ animation: fade 3s ease-out infinite;
28
+ }
29
+
30
+ .bird {
31
+ width: 60px;
32
+ height: 60px;
33
+ }
34
+
35
+ .loading-text {
36
+ margin-top: 20px;
37
+ font-size: 14px;
38
+ color: #333;
39
+ }
40
+
41
+ @keyframes fade {
42
+ 0% {
43
+ opacity: 1;
44
+ }
45
+ 50% {
46
+ opacity: 0.3;
47
+ }
48
+ 100% {
49
+ opacity: 1;
50
+ }
51
+ }
52
+ </style>
@@ -1,251 +1,251 @@
1
- <script setup lang="ts">
2
- import cameraIcon from '@af-mobile-client-vue3/assets/img/component/camera.png'
3
- import { deleteFile } from '@af-mobile-client-vue3/services/api/common'
4
- import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
5
- import {
6
- ActionSheet,
7
- Uploader as vanUploader,
8
- } from 'vant'
9
- import { ref } from 'vue'
10
-
11
- const props = defineProps({
12
- imageList: Array<any>,
13
- outerIndex: { default: undefined },
14
- authority: { default: 'user' },
15
- uploadMode: { default: 'server' },
16
- attr: { type: Object as () => { addOrEdit?: string, acceptCount?: number, uploadImage?: boolean }, default: () => ({}) },
17
- mode: { default: '新增' }, // 预览
18
- })
19
- const emit = defineEmits(['updateFileList', 'updateAllFileList'])
20
-
21
- const imageList = ref<Array<any>>(props.imageList ?? [])
22
-
23
- // 触发拍照
24
- function triggerCamera() {
25
- mobileUtil.execute({
26
- funcName: 'takePicture',
27
- param: {},
28
- callbackFunc: (result: any) => {
29
- if (result.status === 'success') {
30
- handlePhotoUpload(result.data)
31
- }
32
- },
33
- })
34
- }
35
-
36
- // 处理拍照后的上传
37
- function getImageMimeType(fileName: string): string {
38
- const ext = fileName.split('.').pop()?.toLowerCase()
39
- if (ext === 'jpg' || ext === 'jpeg')
40
- return 'image/jpeg'
41
- if (ext === 'png')
42
- return 'image/png'
43
- if (ext === 'gif')
44
- return 'image/gif'
45
- return 'image/png' // 默认
46
- }
47
-
48
- function handlePhotoUpload(photoData: any) {
49
- // 添加临时预览
50
- const mimeType = getImageMimeType(photoData.filePath)
51
- const tempFile = {
52
- uid: Date.now() + Math.random().toString(36).substr(2, 5),
53
- name: photoData.filePath.split('/').pop(),
54
- status: 'uploading',
55
- message: '上传中...',
56
- url: `data:${mimeType};base64,${photoData.content}`,
57
- }
58
-
59
- if (!imageList.value) {
60
- imageList.value = [tempFile]
61
- }
62
- else {
63
- imageList.value.push(tempFile)
64
- }
65
-
66
- const param = {
67
- resUploadMode: props.uploadMode,
68
- pathKey: 'Default',
69
- formType: 'image',
70
- useType: 'Default',
71
- resUploadStock: '1',
72
- filename: photoData.name,
73
- filesize: photoData.size,
74
- f_operator: 'server',
75
- imgPath: photoData.filePath,
76
- urlPath: `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`,
77
- }
78
- // 上传到服务器
79
- mobileUtil.execute({
80
- funcName: 'uploadResource',
81
- param,
82
- callbackFunc: (result: any) => {
83
- const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
84
- if (result.status === 'success') {
85
- if (index !== -1) {
86
- imageList.value[index].uid = result.data.id
87
- imageList.value[index].id = result.data.id
88
- delete imageList.value[index].message
89
- imageList.value[index].status = 'done'
90
- imageList.value[index].url = result.data.f_downloadpath
91
- }
92
- }
93
- else {
94
- if (index !== -1) {
95
- imageList.value[index].status = 'failed'
96
- imageList.value[index].message = '上传失败'
97
- }
98
- }
99
-
100
- emit('updateAllFileList', imageList.value.filter(item => item.status === 'done').map(item => item)) // 新增
101
-
102
- const doneIds = Object.values(imageList.value)
103
- .filter(item => item.status === 'done')
104
- .map(item => item.id)
105
-
106
- if (props.outerIndex !== undefined)
107
- emit('updateFileList', doneIds, props.outerIndex)
108
- else
109
- emit('updateFileList', doneIds)
110
- },
111
- })
112
- }
113
-
114
- // 删除图片
115
- function deleteFileFunction(file: any) {
116
- if (file.id) {
117
- deleteFile({ ids: [file.id], f_state: '删除' }).then((res: any) => {
118
- if (res.msg !== undefined) {
119
- const targetIndex = imageList.value.findIndex(item => item.id === file.id)
120
- if (targetIndex !== -1) {
121
- imageList.value.splice(targetIndex, 1)
122
-
123
- emit('updateAllFileList', imageList.value.filter(item => item.status === 'done').map(item => item)) // 新增
124
-
125
- const doneIds = Object.values(imageList.value)
126
- .filter(item => item.status === 'done')
127
- .map(item => item.id)
128
- if (props.outerIndex !== undefined)
129
- emit('updateFileList', doneIds, props.outerIndex)
130
- else
131
- emit('updateFileList', doneIds)
132
- }
133
- }
134
- })
135
- }
136
- }
137
-
138
- const showActionSheet = ref(false)
139
- const uploaderRef = ref()
140
-
141
- const actionOptions = [
142
- { name: '拍照', key: 'camera' },
143
- { name: '上传', key: 'file' },
144
- ]
145
-
146
- function handleUploadAreaClick() {
147
- if (props.attr?.uploadImage) {
148
- showActionSheet.value = true
149
- }
150
- else {
151
- triggerCamera()
152
- }
153
- }
154
-
155
- function handleActionSelect(option: any) {
156
- showActionSheet.value = false
157
- if (option.key === 'camera') {
158
- triggerCamera()
159
- }
160
- else if (option.key === 'file') {
161
- mobileUtil.execute({
162
- funcName: 'photoAlbum',
163
- param: {},
164
- callbackFunc: (result: any) => {
165
- if (result.status === 'success') {
166
- result.data?.photos.forEach((photo: any) => {
167
- handlePhotoUpload(photo)
168
- })
169
- }
170
- },
171
- })
172
- }
173
- }
174
- </script>
175
-
176
- <template>
177
- <div class="uploader-container">
178
- <div
179
- v-if="props.mode !== '预览' && (imageList.length < props.attr?.acceptCount && props.attr?.addOrEdit !== 'readonly')"
180
- class="custom-upload-area"
181
- @click="handleUploadAreaClick"
182
- >
183
- <img :src="cameraIcon" alt="camera" class="upload-camera-img">
184
- <div class="upload-title">
185
- 上传附件
186
- </div>
187
- <div v-if="props.attr?.acceptCount" class="upload-desc">
188
- 已上传 {{ imageList.length }} 个,最多可上传 {{ props.attr?.acceptCount }} 个
189
- </div>
190
- </div>
191
- <van-uploader
192
- ref="uploaderRef"
193
- v-model="imageList"
194
- :show-upload="false"
195
- :deletable="(props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin') && props.mode !== '预览'"
196
- :multiple="props.authority === 'admin'"
197
- :preview-image="true"
198
- :before-delete="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin' ? deleteFileFunction : undefined"
199
- />
200
- <ActionSheet
201
- v-model:show="showActionSheet"
202
- :actions="actionOptions"
203
- cancel-text="取消"
204
- @select="handleActionSelect"
205
- />
206
- </div>
207
- </template>
208
-
209
- <style scoped lang="less">
210
- .uploader-container {
211
- display: flex;
212
- flex-direction: column;
213
- // 该属性会影响表单布局
214
- // gap: 16px;
215
- }
216
- .custom-upload-area {
217
- width: 100%;
218
- min-width: 220px;
219
- min-height: 100px;
220
- // 该属性会影响表单布局
221
- // margin: 0 auto 12px auto;
222
- box-sizing: border-box;
223
- border: 1px dashed #d9d9d9;
224
- border-radius: 10px;
225
- background: #fff;
226
- display: flex;
227
- flex-direction: column;
228
- align-items: center;
229
- justify-content: center;
230
- cursor: pointer;
231
- padding: 12px 0 10px 0;
232
- .upload-camera-img {
233
- width: 28px;
234
- height: 28px;
235
- margin-bottom: 6px;
236
- object-fit: contain;
237
- display: block;
238
- }
239
- .upload-title {
240
- font-size: 14px;
241
- color: #bfc1c6;
242
- font-weight: 400;
243
- margin-bottom: 2px;
244
- }
245
- .upload-desc {
246
- font-size: 12px;
247
- color: #bfc1c6;
248
- margin-top: 0;
249
- }
250
- }
251
- </style>
1
+ <script setup lang="ts">
2
+ import cameraIcon from '@af-mobile-client-vue3/assets/img/component/camera.png'
3
+ import { deleteFile } from '@af-mobile-client-vue3/services/api/common'
4
+ import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
5
+ import {
6
+ ActionSheet,
7
+ Uploader as vanUploader,
8
+ } from 'vant'
9
+ import { ref } from 'vue'
10
+
11
+ const props = defineProps({
12
+ imageList: Array<any>,
13
+ outerIndex: { default: undefined },
14
+ authority: { default: 'user' },
15
+ uploadMode: { default: 'server' },
16
+ attr: { type: Object as () => { addOrEdit?: string, acceptCount?: number, uploadImage?: boolean }, default: () => ({}) },
17
+ mode: { default: '新增' }, // 预览
18
+ })
19
+ const emit = defineEmits(['updateFileList', 'updateAllFileList'])
20
+
21
+ const imageList = ref<Array<any>>(props.imageList ?? [])
22
+
23
+ // 触发拍照
24
+ function triggerCamera() {
25
+ mobileUtil.execute({
26
+ funcName: 'takePicture',
27
+ param: {},
28
+ callbackFunc: (result: any) => {
29
+ if (result.status === 'success') {
30
+ handlePhotoUpload(result.data)
31
+ }
32
+ },
33
+ })
34
+ }
35
+
36
+ // 处理拍照后的上传
37
+ function getImageMimeType(fileName: string): string {
38
+ const ext = fileName.split('.').pop()?.toLowerCase()
39
+ if (ext === 'jpg' || ext === 'jpeg')
40
+ return 'image/jpeg'
41
+ if (ext === 'png')
42
+ return 'image/png'
43
+ if (ext === 'gif')
44
+ return 'image/gif'
45
+ return 'image/png' // 默认
46
+ }
47
+
48
+ function handlePhotoUpload(photoData: any) {
49
+ // 添加临时预览
50
+ const mimeType = getImageMimeType(photoData.filePath)
51
+ const tempFile = {
52
+ uid: Date.now() + Math.random().toString(36).substr(2, 5),
53
+ name: photoData.filePath.split('/').pop(),
54
+ status: 'uploading',
55
+ message: '上传中...',
56
+ url: `data:${mimeType};base64,${photoData.content}`,
57
+ }
58
+
59
+ if (!imageList.value) {
60
+ imageList.value = [tempFile]
61
+ }
62
+ else {
63
+ imageList.value.push(tempFile)
64
+ }
65
+
66
+ const param = {
67
+ resUploadMode: props.uploadMode,
68
+ pathKey: 'Default',
69
+ formType: 'image',
70
+ useType: 'Default',
71
+ resUploadStock: '1',
72
+ filename: photoData.name,
73
+ filesize: photoData.size,
74
+ f_operator: 'server',
75
+ imgPath: photoData.filePath,
76
+ urlPath: `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`,
77
+ }
78
+ // 上传到服务器
79
+ mobileUtil.execute({
80
+ funcName: 'uploadResource',
81
+ param,
82
+ callbackFunc: (result: any) => {
83
+ const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
84
+ if (result.status === 'success') {
85
+ if (index !== -1) {
86
+ imageList.value[index].uid = result.data.id
87
+ imageList.value[index].id = result.data.id
88
+ delete imageList.value[index].message
89
+ imageList.value[index].status = 'done'
90
+ imageList.value[index].url = result.data.f_downloadpath
91
+ }
92
+ }
93
+ else {
94
+ if (index !== -1) {
95
+ imageList.value[index].status = 'failed'
96
+ imageList.value[index].message = '上传失败'
97
+ }
98
+ }
99
+
100
+ emit('updateAllFileList', imageList.value.filter(item => item.status === 'done').map(item => item)) // 新增
101
+
102
+ const doneIds = Object.values(imageList.value)
103
+ .filter(item => item.status === 'done')
104
+ .map(item => item.id)
105
+
106
+ if (props.outerIndex !== undefined)
107
+ emit('updateFileList', doneIds, props.outerIndex)
108
+ else
109
+ emit('updateFileList', doneIds)
110
+ },
111
+ })
112
+ }
113
+
114
+ // 删除图片
115
+ function deleteFileFunction(file: any) {
116
+ if (file.id) {
117
+ deleteFile({ ids: [file.id], f_state: '删除' }).then((res: any) => {
118
+ if (res.msg !== undefined) {
119
+ const targetIndex = imageList.value.findIndex(item => item.id === file.id)
120
+ if (targetIndex !== -1) {
121
+ imageList.value.splice(targetIndex, 1)
122
+
123
+ emit('updateAllFileList', imageList.value.filter(item => item.status === 'done').map(item => item)) // 新增
124
+
125
+ const doneIds = Object.values(imageList.value)
126
+ .filter(item => item.status === 'done')
127
+ .map(item => item.id)
128
+ if (props.outerIndex !== undefined)
129
+ emit('updateFileList', doneIds, props.outerIndex)
130
+ else
131
+ emit('updateFileList', doneIds)
132
+ }
133
+ }
134
+ })
135
+ }
136
+ }
137
+
138
+ const showActionSheet = ref(false)
139
+ const uploaderRef = ref()
140
+
141
+ const actionOptions = [
142
+ { name: '拍照', key: 'camera' },
143
+ { name: '上传', key: 'file' },
144
+ ]
145
+
146
+ function handleUploadAreaClick() {
147
+ if (props.attr?.uploadImage) {
148
+ showActionSheet.value = true
149
+ }
150
+ else {
151
+ triggerCamera()
152
+ }
153
+ }
154
+
155
+ function handleActionSelect(option: any) {
156
+ showActionSheet.value = false
157
+ if (option.key === 'camera') {
158
+ triggerCamera()
159
+ }
160
+ else if (option.key === 'file') {
161
+ mobileUtil.execute({
162
+ funcName: 'photoAlbum',
163
+ param: {},
164
+ callbackFunc: (result: any) => {
165
+ if (result.status === 'success') {
166
+ result.data?.photos.forEach((photo: any) => {
167
+ handlePhotoUpload(photo)
168
+ })
169
+ }
170
+ },
171
+ })
172
+ }
173
+ }
174
+ </script>
175
+
176
+ <template>
177
+ <div class="uploader-container">
178
+ <div
179
+ v-if="props.mode !== '预览' && (imageList.length < props.attr?.acceptCount && props.attr?.addOrEdit !== 'readonly')"
180
+ class="custom-upload-area"
181
+ @click="handleUploadAreaClick"
182
+ >
183
+ <img :src="cameraIcon" alt="camera" class="upload-camera-img">
184
+ <div class="upload-title">
185
+ 上传附件
186
+ </div>
187
+ <div v-if="props.attr?.acceptCount" class="upload-desc">
188
+ 已上传 {{ imageList.length }} 个,最多可上传 {{ props.attr?.acceptCount }} 个
189
+ </div>
190
+ </div>
191
+ <van-uploader
192
+ ref="uploaderRef"
193
+ v-model="imageList"
194
+ :show-upload="false"
195
+ :deletable="(props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin') && props.mode !== '预览'"
196
+ :multiple="props.authority === 'admin'"
197
+ :preview-image="true"
198
+ :before-delete="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin' ? deleteFileFunction : undefined"
199
+ />
200
+ <ActionSheet
201
+ v-model:show="showActionSheet"
202
+ :actions="actionOptions"
203
+ cancel-text="取消"
204
+ @select="handleActionSelect"
205
+ />
206
+ </div>
207
+ </template>
208
+
209
+ <style scoped lang="less">
210
+ .uploader-container {
211
+ display: flex;
212
+ flex-direction: column;
213
+ // 该属性会影响表单布局
214
+ // gap: 16px;
215
+ }
216
+ .custom-upload-area {
217
+ width: 100%;
218
+ min-width: 220px;
219
+ min-height: 100px;
220
+ // 该属性会影响表单布局
221
+ // margin: 0 auto 12px auto;
222
+ box-sizing: border-box;
223
+ border: 1px dashed #d9d9d9;
224
+ border-radius: 10px;
225
+ background: #fff;
226
+ display: flex;
227
+ flex-direction: column;
228
+ align-items: center;
229
+ justify-content: center;
230
+ cursor: pointer;
231
+ padding: 12px 0 10px 0;
232
+ .upload-camera-img {
233
+ width: 28px;
234
+ height: 28px;
235
+ margin-bottom: 6px;
236
+ object-fit: contain;
237
+ display: block;
238
+ }
239
+ .upload-title {
240
+ font-size: 14px;
241
+ color: #bfc1c6;
242
+ font-weight: 400;
243
+ margin-bottom: 2px;
244
+ }
245
+ .upload-desc {
246
+ font-size: 12px;
247
+ color: #bfc1c6;
248
+ margin-top: 0;
249
+ }
250
+ }
251
+ </style>