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,42 +1,46 @@
1
- # XReport
2
-
3
- 动态报表控件,根据JSON配置生成一个完整的报表
4
-
5
- ## 何时使用
6
-
7
- 当需要一个动态生成的报表时
8
-
9
- 引用方式:
10
-
11
- ```javascript
12
- import XReport from '@vue2-client/base-client/components/XReport/XReport'
13
-
14
- export default {
15
- components: {
16
- XReport
17
- }
18
- }
19
- ```
20
-
21
- ## API
22
-
23
- | 参数 | 说明 | 类型 | 默认值 |
24
- |-----------------|------|-------|-----------|
25
- | configName | 配置文件名 | String | 无(必填) |
26
- | activatedSlotName| 激活插槽名 | String | undefined |
27
- | files | 文件列表 | Array | [] |
28
- | authority | 权限控制 | String | user |
29
- | localConfig | 本地配置 | Object | undefined |
30
- | dontFormat | 禁止已经格式化后的配置格式化| Boolean | false|
31
- | configData | 配置中的Data | Object | undefined |
32
- ## 例子1
33
- ----
34
- ```vue
35
- <XReport :config-name="'test_tableConfig'" :activated-slot-name="'test_tableConfig_slot'" />
36
- ```
37
- ## 注意事项
38
-
39
- > 在某些情况下,比如手机端,只需要输入表格中一部分的内容。
40
- > 可以将这部分内容作为插槽,并在activatedSlotName中填写插槽名。
41
- > 则会在设计页面仅展示插槽中的输入项,并在预览窗口中,根据configName中的配置,
42
- > 渲染出来完整的表格
1
+ # XReport
2
+
3
+ 动态报表控件,根据JSON配置生成一个完整的报表
4
+
5
+ ## 何时使用
6
+
7
+ 当需要一个动态生成的报表时
8
+
9
+ 引用方式:
10
+
11
+ ```javascript
12
+ import XReport from '@vue2-client/base-client/components/XReport/XReport'
13
+
14
+ export default {
15
+ components: {
16
+ XReport
17
+ }
18
+ }
19
+ ```
20
+
21
+ ## API
22
+
23
+ | 参数 | 说明 | 类型 | 默认值 |
24
+ | ----------------- | ---------------------------- | ------- | ---------- |
25
+ | configName | 配置文件名 | String | 无(必填) |
26
+ | activatedSlotName | 激活插槽名 | String | undefined |
27
+ | files | 文件列表 | Array | [] |
28
+ | authority | 权限控制 | String | user |
29
+ | localConfig | 本地配置 | Object | undefined |
30
+ | dontFormat | 禁止已经格式化后的配置格式化 | Boolean | false |
31
+ | configData | 配置中的Data | Object | undefined |
32
+
33
+ ## 例子1
34
+
35
+ ---
36
+
37
+ ```vue
38
+ <XReport :config-name="'test_tableConfig'" :activated-slot-name="'test_tableConfig_slot'" />
39
+ ```
40
+
41
+ ## 注意事项
42
+
43
+ > 在某些情况下,比如手机端,只需要输入表格中一部分的内容。
44
+ > 可以将这部分内容作为插槽,并在activatedSlotName中填写插槽名。
45
+ > 则会在设计页面仅展示插槽中的输入项,并在预览窗口中,根据configName中的配置,
46
+ > 渲染出来完整的表格
@@ -1,285 +1,284 @@
1
- <script setup lang="ts">
2
- import {
3
- showToast,
4
- Button as VanButton,
5
- Icon as VanIcon,
6
- Popup as VanPopup,
7
- Signature as VanSignature,
8
- } from 'vant'
9
- import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
10
-
11
- interface Props {
12
- /** 签名图片的 base64 字符串 */
13
- modelValue?: string
14
- /** 签名笔画的宽度,默认为 3 */
15
- lineWidth?: number
16
- /** 签名笔画的颜色,默认为黑色 '#000' */
17
- strokeStyle?: string
18
- /** 签名画布的背景颜色,默认为白色 '#fff' */
19
- backgroundColor?: string
20
- /** 未签名时按钮显示的文字,默认为 '签名' */
21
- buttonText?: string
22
- /** 自定义 CSS 类名 */
23
- customClass?: string
24
- /** 是否隐藏底部按钮组,默认为 false */
25
- hideButtons?: boolean
26
- /** 按钮尺寸,可选值为 'small' | 'normal' | 'large',默认为 'normal' */
27
- buttonSize?: 'small' | 'normal' | 'large'
28
- /** 确认按钮文字,默认为 '确认' */
29
- confirmButtonText?: string
30
- /** 清除按钮文字,默认为 '清除' */
31
- clearButtonText?: string
32
- /** 是否显示签名预览图,默认为 true */
33
- showPreview?: boolean
34
- /** 签名完成后是否显示重新签名按钮,默认为 false */
35
- showButtonAfterSigned?: boolean
36
- }
37
-
38
- withDefaults(defineProps<Props>(), {
39
- modelValue: '',
40
- lineWidth: 3,
41
- strokeStyle: '#000',
42
- backgroundColor: '#fff',
43
- buttonText: '签名',
44
- customClass: '',
45
- hideButtons: false,
46
- buttonSize: 'normal',
47
- confirmButtonText: '确认',
48
- clearButtonText: '清除',
49
- showPreview: true,
50
- showButtonAfterSigned: false,
51
- })
52
-
53
- const emit = defineEmits<{
54
- 'update:modelValue': [value: string]
55
- 'save': [image: string]
56
- 'clear': []
57
- }>()
58
-
59
- interface SignatureResult {
60
- image: string
61
- }
62
-
63
- const showSignature = ref(false)
64
-
65
- function onSubmit({ image }: SignatureResult) {
66
- if (!image) {
67
- showToast('获取签名失败')
68
- return
69
- }
70
- emit('update:modelValue', image)
71
- emit('save', image)
72
- showSignature.value = false
73
- }
74
-
75
- function onClear() {
76
- emit('update:modelValue', '')
77
- emit('clear')
78
- showSignature.value = false
79
- }
80
-
81
- const signatureRef = ref()
82
-
83
- function handleSubmit() {
84
- try {
85
- signatureRef.value?.submit()
86
- }
87
- catch (error) {
88
- showToast('签名提交失败')
89
- console.error('Signature submit error:', error)
90
- }
91
- }
92
-
93
- const popupStyle = computed(() => ({
94
- width: '100%',
95
- height: window.innerHeight > window.innerWidth ? 'auto' : '100%',
96
- }))
97
-
98
- function handleOrientationChange() {
99
- if (showSignature.value) {
100
- nextTick(() => {
101
- signatureRef.value?.resize()
102
- })
103
- }
104
- }
105
-
106
- onMounted(() => {
107
- window.addEventListener('orientationchange', handleOrientationChange)
108
- })
109
-
110
- onBeforeUnmount(() => {
111
- window.removeEventListener('orientationchange', handleOrientationChange)
112
- })
113
- </script>
114
-
115
- <template>
116
- <div class="x-signature" role="application" aria-label="签名面板">
117
- <div class="signature-content">
118
- <div v-if="modelValue && showPreview" class="signature-preview" @click="showSignature = true">
119
- <img :src="modelValue" alt="签名预览">
120
- </div>
121
- <VanButton
122
- v-if="!modelValue || showButtonAfterSigned"
123
- type="primary"
124
- size="small"
125
- aria-label="打开签名面板"
126
- @click="showSignature = true"
127
- >
128
- {{ modelValue ? '重新签名' : buttonText }}
129
- </VanButton>
130
- </div>
131
-
132
- <VanPopup v-model:show="showSignature" class="signature-popup" :style="popupStyle">
133
- <div class="signature-wrapper">
134
- <VanSignature
135
- ref="signatureRef"
136
- :line-width="lineWidth"
137
- :stroke-style="strokeStyle"
138
- :background-color="backgroundColor"
139
- @submit="onSubmit"
140
- @clear="onClear"
141
- />
142
- <!-- 自定义浮动按钮,仅在横屏时显示 -->
143
- <div class="custom-buttons">
144
- <VanButton round size="small" aria-label="清除签名" @click="onClear">
145
- <VanIcon name="delete" />
146
- </VanButton>
147
- <VanButton round type="primary" size="small" @click="handleSubmit">
148
- <VanIcon name="success" />
149
- </VanButton>
150
- </div>
151
- </div>
152
- </VanPopup>
153
- </div>
154
- </template>
155
-
156
- <style scoped lang="less">
157
- .x-signature {
158
- width: 100%;
159
-
160
- .signature-content {
161
- display: flex;
162
- align-items: center;
163
- gap: 12px;
164
- }
165
-
166
- .signature-preview {
167
- flex: 1;
168
- border: 1px solid #eee;
169
- border-radius: 4px;
170
- padding: 8px;
171
- display: flex;
172
- align-items: center;
173
-
174
- img {
175
- max-width: 100%;
176
- max-height: 36px;
177
- height: auto;
178
- display: block;
179
- }
180
- }
181
-
182
- .van-button {
183
- flex-shrink: 0;
184
- }
185
-
186
- :deep(.van-popup) {
187
- max-width: none !important;
188
- width: 100% !important;
189
- top: 20% !important;
190
- transform: none !important;
191
- transition: all 0.3s ease-in-out;
192
- }
193
-
194
- .signature-wrapper {
195
- width: 100%;
196
- height: 100%;
197
- position: relative;
198
-
199
- :deep(.van-signature) {
200
- width: 100% !important;
201
- height: 100% !important;
202
- max-width: none !important;
203
- }
204
-
205
- // 默认隐藏自定义按钮
206
- .custom-buttons {
207
- display: none;
208
- }
209
- }
210
-
211
- // 横屏模式样式
212
- @media screen and (orientation: landscape) {
213
- :deep(.van-popup) {
214
- top: 0 !important;
215
- right: 0 !important;
216
- bottom: 0 !important;
217
- left: 0 !important;
218
- width: 100% !important;
219
- height: 100% !important;
220
- display: flex;
221
- flex-direction: column;
222
- }
223
-
224
- .signature-wrapper {
225
- flex: 1;
226
- display: flex;
227
- justify-content: center;
228
- align-items: center;
229
- padding: env(safe-area-inset-top) env(safe-area-inset-right)
230
- env(safe-area-inset-bottom) env(safe-area-inset-left);
231
-
232
- :deep(.van-signature) {
233
- // 隐藏原有的底部按钮
234
- .van-signature__footer {
235
- display: none;
236
- }
237
- }
238
-
239
- :deep(.van-signature__content) {
240
- height: 95% !important;
241
- }
242
-
243
- // 显示自定义浮动按钮
244
- .custom-buttons {
245
- position: absolute;
246
- right: 32px;
247
- bottom: 32px;
248
- display: flex;
249
- gap: 16px;
250
-
251
- .van-button {
252
- width: 48px !important;
253
- height: 48px !important;
254
- border-radius: 50% !important;
255
- padding: 0 !important;
256
- display: flex;
257
- align-items: center;
258
- justify-content: center;
259
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
260
- transition: transform 0.2s ease;
261
-
262
- &--default {
263
- background: #fff;
264
- }
265
-
266
- &:active {
267
- transform: scale(0.95);
268
- }
269
- }
270
- }
271
- }
272
- }
273
-
274
- // 优化按钮触摸反馈
275
- .custom-buttons {
276
- .van-button {
277
- transition: transform 0.2s ease;
278
-
279
- &:active {
280
- transform: scale(0.95);
281
- }
282
- }
283
- }
284
- }
285
- </style>
1
+ <script setup lang="ts">
2
+ import {
3
+ showToast,
4
+ Button as VanButton,
5
+ Icon as VanIcon,
6
+ Popup as VanPopup,
7
+ Signature as VanSignature,
8
+ } from 'vant'
9
+ import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
10
+
11
+ interface Props {
12
+ /** 签名图片的 base64 字符串 */
13
+ modelValue?: string
14
+ /** 签名笔画的宽度,默认为 3 */
15
+ lineWidth?: number
16
+ /** 签名笔画的颜色,默认为黑色 '#000' */
17
+ strokeStyle?: string
18
+ /** 签名画布的背景颜色,默认为白色 '#fff' */
19
+ backgroundColor?: string
20
+ /** 未签名时按钮显示的文字,默认为 '签名' */
21
+ buttonText?: string
22
+ /** 自定义 CSS 类名 */
23
+ customClass?: string
24
+ /** 是否隐藏底部按钮组,默认为 false */
25
+ hideButtons?: boolean
26
+ /** 按钮尺寸,可选值为 'small' | 'normal' | 'large',默认为 'normal' */
27
+ buttonSize?: 'small' | 'normal' | 'large'
28
+ /** 确认按钮文字,默认为 '确认' */
29
+ confirmButtonText?: string
30
+ /** 清除按钮文字,默认为 '清除' */
31
+ clearButtonText?: string
32
+ /** 是否显示签名预览图,默认为 true */
33
+ showPreview?: boolean
34
+ /** 签名完成后是否显示重新签名按钮,默认为 false */
35
+ showButtonAfterSigned?: boolean
36
+ }
37
+
38
+ withDefaults(defineProps<Props>(), {
39
+ modelValue: '',
40
+ lineWidth: 3,
41
+ strokeStyle: '#000',
42
+ backgroundColor: '#fff',
43
+ buttonText: '签名',
44
+ customClass: '',
45
+ hideButtons: false,
46
+ buttonSize: 'normal',
47
+ confirmButtonText: '确认',
48
+ clearButtonText: '清除',
49
+ showPreview: true,
50
+ showButtonAfterSigned: false,
51
+ })
52
+
53
+ const emit = defineEmits<{
54
+ 'update:modelValue': [value: string]
55
+ 'save': [image: string]
56
+ 'clear': []
57
+ }>()
58
+
59
+ interface SignatureResult {
60
+ image: string
61
+ }
62
+
63
+ const showSignature = ref(false)
64
+
65
+ function onSubmit({ image }: SignatureResult) {
66
+ if (!image) {
67
+ showToast('获取签名失败')
68
+ return
69
+ }
70
+ emit('update:modelValue', image)
71
+ emit('save', image)
72
+ showSignature.value = false
73
+ }
74
+
75
+ function onClear() {
76
+ emit('update:modelValue', '')
77
+ emit('clear')
78
+ showSignature.value = false
79
+ }
80
+
81
+ const signatureRef = ref()
82
+
83
+ function handleSubmit() {
84
+ try {
85
+ signatureRef.value?.submit()
86
+ }
87
+ catch (error) {
88
+ showToast('签名提交失败')
89
+ console.error('Signature submit error:', error)
90
+ }
91
+ }
92
+
93
+ const popupStyle = computed(() => ({
94
+ width: '100%',
95
+ height: window.innerHeight > window.innerWidth ? 'auto' : '100%',
96
+ }))
97
+
98
+ function handleOrientationChange() {
99
+ if (showSignature.value) {
100
+ nextTick(() => {
101
+ signatureRef.value?.resize()
102
+ })
103
+ }
104
+ }
105
+
106
+ onMounted(() => {
107
+ window.addEventListener('orientationchange', handleOrientationChange)
108
+ })
109
+
110
+ onBeforeUnmount(() => {
111
+ window.removeEventListener('orientationchange', handleOrientationChange)
112
+ })
113
+ </script>
114
+
115
+ <template>
116
+ <div class="x-signature" role="application" aria-label="签名面板">
117
+ <div class="signature-content">
118
+ <div v-if="modelValue && showPreview" class="signature-preview" @click="showSignature = true">
119
+ <img :src="modelValue" alt="签名预览">
120
+ </div>
121
+ <VanButton
122
+ v-if="!modelValue || showButtonAfterSigned"
123
+ type="primary"
124
+ size="small"
125
+ aria-label="打开签名面板"
126
+ @click="showSignature = true"
127
+ >
128
+ {{ modelValue ? '重新签名' : buttonText }}
129
+ </VanButton>
130
+ </div>
131
+
132
+ <VanPopup v-model:show="showSignature" class="signature-popup" :style="popupStyle">
133
+ <div class="signature-wrapper">
134
+ <VanSignature
135
+ ref="signatureRef"
136
+ :line-width="lineWidth"
137
+ :stroke-style="strokeStyle"
138
+ :background-color="backgroundColor"
139
+ @submit="onSubmit"
140
+ @clear="onClear"
141
+ />
142
+ <!-- 自定义浮动按钮,仅在横屏时显示 -->
143
+ <div class="custom-buttons">
144
+ <VanButton round size="small" aria-label="清除签名" @click="onClear">
145
+ <VanIcon name="delete" />
146
+ </VanButton>
147
+ <VanButton round type="primary" size="small" @click="handleSubmit">
148
+ <VanIcon name="success" />
149
+ </VanButton>
150
+ </div>
151
+ </div>
152
+ </VanPopup>
153
+ </div>
154
+ </template>
155
+
156
+ <style scoped lang="less">
157
+ .x-signature {
158
+ width: 100%;
159
+
160
+ .signature-content {
161
+ display: flex;
162
+ align-items: center;
163
+ gap: 12px;
164
+ }
165
+
166
+ .signature-preview {
167
+ flex: 1;
168
+ border: 1px solid #eee;
169
+ border-radius: 4px;
170
+ padding: 8px;
171
+ display: flex;
172
+ align-items: center;
173
+
174
+ img {
175
+ max-width: 100%;
176
+ max-height: 36px;
177
+ height: auto;
178
+ display: block;
179
+ }
180
+ }
181
+
182
+ .van-button {
183
+ flex-shrink: 0;
184
+ }
185
+
186
+ :deep(.van-popup) {
187
+ max-width: none !important;
188
+ width: 100% !important;
189
+ top: 20% !important;
190
+ transform: none !important;
191
+ transition: all 0.3s ease-in-out;
192
+ }
193
+
194
+ .signature-wrapper {
195
+ width: 100%;
196
+ height: 100%;
197
+ position: relative;
198
+
199
+ :deep(.van-signature) {
200
+ width: 100% !important;
201
+ height: 100% !important;
202
+ max-width: none !important;
203
+ }
204
+
205
+ // 默认隐藏自定义按钮
206
+ .custom-buttons {
207
+ display: none;
208
+ }
209
+ }
210
+
211
+ // 横屏模式样式
212
+ @media screen and (orientation: landscape) {
213
+ :deep(.van-popup) {
214
+ top: 0 !important;
215
+ right: 0 !important;
216
+ bottom: 0 !important;
217
+ left: 0 !important;
218
+ width: 100% !important;
219
+ height: 100% !important;
220
+ display: flex;
221
+ flex-direction: column;
222
+ }
223
+
224
+ .signature-wrapper {
225
+ flex: 1;
226
+ display: flex;
227
+ justify-content: center;
228
+ align-items: center;
229
+ padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
230
+
231
+ :deep(.van-signature) {
232
+ // 隐藏原有的底部按钮
233
+ .van-signature__footer {
234
+ display: none;
235
+ }
236
+ }
237
+
238
+ :deep(.van-signature__content) {
239
+ height: 95% !important;
240
+ }
241
+
242
+ // 显示自定义浮动按钮
243
+ .custom-buttons {
244
+ position: absolute;
245
+ right: 32px;
246
+ bottom: 32px;
247
+ display: flex;
248
+ gap: 16px;
249
+
250
+ .van-button {
251
+ width: 48px !important;
252
+ height: 48px !important;
253
+ border-radius: 50% !important;
254
+ padding: 0 !important;
255
+ display: flex;
256
+ align-items: center;
257
+ justify-content: center;
258
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
259
+ transition: transform 0.2s ease;
260
+
261
+ &--default {
262
+ background: #fff;
263
+ }
264
+
265
+ &:active {
266
+ transform: scale(0.95);
267
+ }
268
+ }
269
+ }
270
+ }
271
+ }
272
+
273
+ // 优化按钮触摸反馈
274
+ .custom-buttons {
275
+ .van-button {
276
+ transition: transform 0.2s ease;
277
+
278
+ &:active {
279
+ transform: scale(0.95);
280
+ }
281
+ }
282
+ }
283
+ }
284
+ </style>
@@ -1,10 +1,10 @@
1
- <script setup lang="ts">
2
- </script>
3
-
4
- <template>
5
- <VanTag />
6
- </template>
7
-
8
- <style scoped lang="less">
9
-
10
- </style>
1
+ <script setup lang="ts">
2
+ </script>
3
+
4
+ <template>
5
+ <VanTag />
6
+ </template>
7
+
8
+ <style scoped lang="less">
9
+
10
+ </style>