hrp-ui-base 1.0.1 → 1.0.3

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 (269) hide show
  1. package/dist/components.cjs +1 -1
  2. package/dist/components.es.js +3595 -1224
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.es.js +100 -67
  5. package/dist/style.css +1 -1
  6. package/package.json +16 -4
  7. package/packages/approval-process/.eslintrc +7 -0
  8. package/packages/approval-process/README.md +130 -0
  9. package/packages/approval-process/index.ts +65 -0
  10. package/packages/approval-process/package.json +17 -0
  11. package/packages/approval-process/packages/components/choose-member/BO/departBo.ts +8 -0
  12. package/packages/approval-process/packages/components/choose-member/BO/memberBo.ts +14 -0
  13. package/packages/approval-process/packages/components/choose-member/BO/role.svg +1 -0
  14. package/packages/approval-process/packages/components/choose-member/BO/roleBo.ts +16 -0
  15. package/packages/approval-process/packages/components/choose-member/index.vue +497 -0
  16. package/packages/approval-process/packages/components/choose-member/styles/common.scss +134 -0
  17. package/packages/approval-process/packages/components/comment/assets/avatar.svg +1 -0
  18. package/packages/approval-process/packages/components/comment/assets/download.svg +4 -0
  19. package/packages/approval-process/packages/components/comment/assets/mp3.svg +11 -0
  20. package/packages/approval-process/packages/components/comment/assets/mp4.svg +11 -0
  21. package/packages/approval-process/packages/components/comment/assets/other.svg +11 -0
  22. package/packages/approval-process/packages/components/comment/assets/pdf.svg +11 -0
  23. package/packages/approval-process/packages/components/comment/assets/ppt.svg +11 -0
  24. package/packages/approval-process/packages/components/comment/assets/preview.svg +4 -0
  25. package/packages/approval-process/packages/components/comment/assets/remove.png +0 -0
  26. package/packages/approval-process/packages/components/comment/assets/word.svg +11 -0
  27. package/packages/approval-process/packages/components/comment/assets/xls.svg +11 -0
  28. package/packages/approval-process/packages/components/comment/index.vue +843 -0
  29. package/packages/approval-process/packages/components/comment/modules/previewMp.vue +54 -0
  30. package/packages/approval-process/packages/components/comment/styles/comment-style.scss +304 -0
  31. package/packages/approval-process/packages/components/image-cropper/index.vue +202 -0
  32. package/packages/approval-process/packages/components/sign/index.vue +766 -0
  33. package/packages/approval-process/packages/components/sign/modules/full-screen-sign.vue +20 -0
  34. package/packages/approval-process/packages/components/urge-dialog/index.vue +121 -0
  35. package/packages/approval-process/packages/components/vue-esign/index.vue +289 -0
  36. package/packages/approval-process/packages/flow/approve-component/approve-success.vue +82 -0
  37. package/packages/approval-process/packages/flow/approve-component/route-params-error.vue +49 -0
  38. package/packages/approval-process/packages/flow/approve-component/submit-success.vue +59 -0
  39. package/packages/approval-process/packages/flow/examine-approve-itr.vue +978 -0
  40. package/packages/approval-process/packages/flow/examine-approve.vue +1065 -0
  41. package/packages/approval-process/packages/flow/form-component/associated-approval-form/README.md +38 -0
  42. package/packages/approval-process/packages/flow/form-component/associated-approval-form/assets/avatar.svg +1 -0
  43. package/packages/approval-process/packages/flow/form-component/associated-approval-form/index.vue +159 -0
  44. package/packages/approval-process/packages/flow/form-component/associated-approval-form/modules/associated-approval-form-mobile.vue +297 -0
  45. package/packages/approval-process/packages/flow/form-component/associated-approval-form/modules/associated-approval-form-pc.vue +314 -0
  46. package/packages/approval-process/packages/flow/form-component/associated-approval-form/style/curd-area-mobile.scss +110 -0
  47. package/packages/approval-process/packages/flow/form-component/associated-approval-form/style/curd-area.scss +96 -0
  48. package/packages/approval-process/packages/flow/form-component/associated-approval-form/style/out-put.scss +48 -0
  49. package/packages/approval-process/packages/flow/form-component/show-sign.vue +27 -0
  50. package/packages/approval-process/packages/flow/styles/common.scss +134 -0
  51. package/packages/approval-process/packages/flow/styles/examine-approve-pc.scss +465 -0
  52. package/packages/approval-process/packages/flow/styles/examine-approve-phone.scss +293 -0
  53. package/packages/approval-process/packages/flow/styles/submit-approve-pc.scss +379 -0
  54. package/packages/approval-process/packages/flow/styles/submit-approve-phone.scss +337 -0
  55. package/packages/approval-process/packages/flow/submit-approve-itr.vue +623 -0
  56. package/packages/approval-process/packages/flow/submit-approve.vue +628 -0
  57. package/packages/approval-process/packages/flow/systemCom/BO/departBo.ts +8 -0
  58. package/packages/approval-process/packages/flow/systemCom/BO/memberBo.ts +14 -0
  59. package/packages/approval-process/packages/flow/systemCom/BO/role.svg +1 -0
  60. package/packages/approval-process/packages/flow/systemCom/BO/roleBo.ts +16 -0
  61. package/packages/approval-process/packages/flow/systemCom/choose-depart.vue +399 -0
  62. package/packages/approval-process/packages/flow/systemCom/choose-member-phone.vue +515 -0
  63. package/packages/approval-process/packages/flow/systemCom/choose-member.vue +565 -0
  64. package/packages/approval-process/packages/flow/systemCom/choose-role.vue +301 -0
  65. package/packages/approval-process/packages/styles/common.scss +134 -0
  66. package/packages/approval-process/packages/styles/flex-common.scss +118 -0
  67. package/packages/approval-process/packages/styles/flexCommon.scss +73 -0
  68. package/packages/approval-process/packages/styles/main.css +216 -0
  69. package/packages/approval-process/packages/styles/router-page.scss +371 -0
  70. package/packages/approval-process/packages/styles/style-set.ts +207 -0
  71. package/packages/approval-process/packages/types.d.ts +4 -0
  72. package/packages/approval-process/packages/utils/base.ts +15 -0
  73. package/packages/approval-process/packages/utils/crypto.ts +67 -0
  74. package/packages/approval-process/packages/utils/ddUtils.ts +56 -0
  75. package/packages/approval-process/packages/utils/debounce.ts +36 -0
  76. package/packages/approval-process/packages/utils/des.js +1107 -0
  77. package/packages/approval-process/packages/utils/download.ts +38 -0
  78. package/packages/approval-process/packages/utils/editor.ts +37 -0
  79. package/packages/approval-process/packages/utils/getEnv.ts +36 -0
  80. package/packages/approval-process/packages/utils/os.ts +20 -0
  81. package/packages/approval-process/packages/utils/path-util.ts +31 -0
  82. package/packages/approval-process/packages/utils/routerUtil.ts +304 -0
  83. package/packages/approval-process/packages/utils/string-utils.ts +13 -0
  84. package/packages/approval-process/packages/utils/throttle.ts +44 -0
  85. package/packages/approval-process/packages/utils/validate.ts +92 -0
  86. package/packages/approval-process/packages/utils/ws.ts +218 -0
  87. package/packages/approval-process/tsconfig.json +72 -0
  88. package/packages/approval-process/vite.config.ts +56 -0
  89. package/src/api/bms/flow/FlowCommentController.ts +50 -0
  90. package/src/api/bms/flow/FlowInstanceController.ts +167 -0
  91. package/src/api/bms/flow/FlowProcessController.ts +55 -0
  92. package/src/api/bms/flow/FlowSheetController.ts +27 -0
  93. package/src/api/bms/flow/FlowSignController.ts +76 -0
  94. package/src/api/bms/flow/bo/AssociatedApprovalBO.ts +15 -0
  95. package/src/api/bms/flow/bo/AssociatedApprovalVO.ts +35 -0
  96. package/src/api/bms/flow/bo/AuditBaseInfo.ts +39 -0
  97. package/src/api/bms/flow/bo/ButtonVo.ts +7 -0
  98. package/src/api/bms/flow/bo/DingCallbackBo.ts +13 -0
  99. package/src/api/bms/flow/bo/FlowCommentBO.ts +12 -0
  100. package/src/api/bms/flow/bo/FlowCommentVO.ts +23 -0
  101. package/src/api/bms/flow/bo/FlowInstanceBO.ts +14 -0
  102. package/src/api/bms/flow/bo/FlowNodeVO.ts +24 -0
  103. package/src/api/bms/flow/bo/FlowNoticeBO.ts +17 -0
  104. package/src/api/bms/flow/bo/FlowProcessBO.ts +13 -0
  105. package/src/api/bms/flow/bo/FlowProcessVO.ts +9 -0
  106. package/src/api/bms/flow/bo/FlowReplyVO.ts +23 -0
  107. package/src/api/bms/flow/bo/FlowSheetVO.ts +16 -0
  108. package/src/api/bms/flow/bo/InstanceBackBO.ts +9 -0
  109. package/src/api/bms/flow/bo/InstanceNodeBO.ts +13 -0
  110. package/src/api/bms/flow/bo/InstanceNodeVO.ts +21 -0
  111. package/src/api/bms/flow/bo/NodeShowVo.ts +19 -0
  112. package/src/api/bms/flow/bo/ReviewBO.ts +11 -0
  113. package/src/api/bms/flow/bo/SheetSearchBO.ts +11 -0
  114. package/src/api/bms/flow/bo/SystemVO.ts +7 -0
  115. package/src/api/bms/flow/bo/TransmitBO.ts +9 -0
  116. package/src/api/bms/flow/bo/UrgeFlowBO.ts +7 -0
  117. package/src/api/bms/flow/bo/UserBaseInfoVo.ts +13 -0
  118. package/src/api/bms/flow/bo/UserInfoVo.ts +44 -0
  119. package/src/api/bms/flow/bo/UserResultVo.ts +17 -0
  120. package/src/api/bms/flow/bo/ValueMapBo.ts +7 -0
  121. package/src/api/bms/home/HomeController.ts +106 -0
  122. package/src/api/bms/home/bo/CollectedMenuBo.ts +9 -0
  123. package/src/api/bms/home/bo/DeptBaseVo.ts +9 -0
  124. package/src/api/bms/home/bo/DomainVO.ts +13 -0
  125. package/src/api/bms/home/bo/FunPermission.ts +17 -0
  126. package/src/api/bms/home/bo/GroupVO.ts +10 -0
  127. package/src/api/bms/home/bo/HomeMenu.ts +22 -0
  128. package/src/api/bms/home/bo/HomeMenuVo.ts +11 -0
  129. package/src/api/bms/home/bo/PersonalizationBo.ts +17 -0
  130. package/src/api/bms/home/bo/PersonalizationVo.ts +19 -0
  131. package/src/api/bms/home/bo/PhoneMenu.ts +14 -0
  132. package/src/api/bms/home/bo/SearchMenuVo.ts +10 -0
  133. package/src/api/bms/home/bo/UserBaseInfoVo.ts +11 -0
  134. package/src/api/hrms/dept/bo/DeptBaseVo.ts +6 -0
  135. package/src/api/hrms/dept/bo/DeptTreeVo.ts +23 -0
  136. package/src/api/hrms/dept/bo/DeptUserVo.ts +9 -0
  137. package/src/api/hrms/dept/bo/DeptUsersVo.ts +10 -0
  138. package/src/api/hrms/dept/bo/DeptVo.ts +19 -0
  139. package/src/api/hrms/dept/bo/UserBaseInfoVo.ts +8 -0
  140. package/src/api/hrms/dept/deptController.ts +100 -0
  141. package/src/api/hrms/role/bo/RoleBaseVo.ts +6 -0
  142. package/src/api/hrms/role/bo/RoleGroupVo.ts +11 -0
  143. package/src/api/hrms/role/bo/RoleVo.ts +22 -0
  144. package/src/api/hrms/role/roleController.ts +19 -0
  145. package/src/api/hrms/user/bo/UserBaseInfoVo.ts +11 -0
  146. package/src/api/hrms/user/bo/UserCardVO.ts +14 -0
  147. package/src/api/hrms/user/bo/UserDeptBO.ts +13 -0
  148. package/src/api/hrms/user/bo/UserRoleBO.ts +11 -0
  149. package/src/api/hrms/user/bo/UserVO.ts +23 -0
  150. package/src/api/hrms/user/userController.ts +86 -0
  151. package/src/api/notice/NoticeController.ts +73 -0
  152. package/src/api/notice/bo/NoticePageBO.ts +24 -0
  153. package/src/api/notice/bo/NoticeVO.ts +31 -0
  154. package/src/api/work-order-pc/flow/Bo/ValueMapBo.ts +7 -0
  155. package/src/api/work-order-pc/flow/ItrFlowProcessController.ts +42 -0
  156. package/src/api/work-order-pc/flow/Vo/FlowNodeVO.ts +24 -0
  157. package/src/api/work-order-pc/flow/Vo/UserInfoVo.ts +44 -0
  158. package/src/assets/layout/avatar-default.svg +6 -0
  159. package/src/assets/layout/collect-active.svg +7 -0
  160. package/src/assets/layout/collect-default.svg +7 -0
  161. package/src/assets/layout/download-active.svg +8 -0
  162. package/src/assets/layout/download-default.svg +8 -0
  163. package/src/assets/layout/export-dark.svg +7 -0
  164. package/src/assets/layout/export-default.svg +7 -0
  165. package/src/assets/layout/font-active.svg +6 -0
  166. package/src/assets/layout/font-default.svg +6 -0
  167. package/src/assets/layout/help-active.svg +10 -0
  168. package/src/assets/layout/help-default.svg +10 -0
  169. package/src/assets/layout/home-active.svg +6 -0
  170. package/src/assets/layout/home.svg +6 -0
  171. package/src/assets/layout/menu-expand.svg +6 -0
  172. package/src/assets/layout/menu-icon.png +0 -0
  173. package/src/assets/layout/menu-position-active.svg +6 -0
  174. package/src/assets/layout/menu-position-default.svg +6 -0
  175. package/src/assets/layout/message-active.svg +9 -0
  176. package/src/assets/layout/message-default.svg +9 -0
  177. package/src/assets/layout/moon.svg +8 -0
  178. package/src/assets/layout/router-all-dark.svg +11 -0
  179. package/src/assets/layout/router-all-default.svg +17 -0
  180. package/src/assets/layout/search-active.svg +20 -0
  181. package/src/assets/layout/search-default.svg +20 -0
  182. package/src/assets/layout/star-active.svg +1 -0
  183. package/src/assets/layout/star-default.svg +3 -0
  184. package/src/assets/layout/sun-active.svg +6 -0
  185. package/src/assets/layout/sun-default.svg +6 -0
  186. package/src/assets/layout/switch-moon.svg +3 -0
  187. package/src/assets/layout/switch-sun.svg +41 -0
  188. package/src/assets/layout/todo-active.svg +12 -0
  189. package/src/assets/layout/todo-default.svg +12 -0
  190. package/src/assets/layout/user-dark.svg +13 -0
  191. package/src/assets/layout/user-default.svg +13 -0
  192. package/src/assets/process/agree.png +0 -0
  193. package/src/assets/process/defaultAvatar.png +0 -0
  194. package/src/assets/process/drawer/departManagerJump.png +0 -0
  195. package/src/assets/process/drawer/manyLevel1close.svg +10 -0
  196. package/src/assets/process/drawer/manyLevel1open.svg +7 -0
  197. package/src/assets/process/drawer/manyLevel2close.svg +7 -0
  198. package/src/assets/process/drawer/manyLevel2open.svg +7 -0
  199. package/src/assets/process/inProcess.png +0 -0
  200. package/src/assets/process/manyPeople.png +0 -0
  201. package/src/assets/process/manyPeople2.png +0 -0
  202. package/src/assets/process/reject.png +0 -0
  203. package/src/assets/process/revoke.png +0 -0
  204. package/src/components/annex-img-upload/index.vue +4 -4
  205. package/src/components/annex-img-upload/modules/previewMp.vue +1 -1
  206. package/src/components/annex-upload/index.vue +4 -4
  207. package/src/components/annex-upload/modules/previewMp.vue +1 -1
  208. package/src/components/annex-upload-weijian/index.vue +4 -4
  209. package/src/components/annex-upload-weijian/modules/previewMp.vue +1 -1
  210. package/src/components/base-layout/index.vue +198 -0
  211. package/src/components/layout/SysHeader.vue +90 -0
  212. package/src/components/layout/SysHeaderLeft.vue +116 -0
  213. package/src/components/layout/SysHeaderRight.vue +112 -0
  214. package/src/components/layout/SysHeaderTabs.vue +289 -0
  215. package/src/components/layout/components/avatar-component.vue +77 -0
  216. package/src/components/layout/components/dark-component.vue +82 -0
  217. package/src/components/layout/components/download-component.vue +49 -0
  218. package/src/components/layout/components/font-size-component.vue +66 -0
  219. package/src/components/layout/components/menu-position-component.vue +97 -0
  220. package/src/components/layout/components/message-component.vue +64 -0
  221. package/src/components/layout/components/todo-component.vue +55 -0
  222. package/src/components/layout/index.ts +24 -0
  223. package/src/components/layout/message/message-dictionary.ts +27 -0
  224. package/src/components/layout/message/message-icon//345/205/250/351/203/250/351/200/232/347/237/245-/350/223/235.svg +8 -0
  225. package/src/components/layout/message/message-icon//345/205/250/351/203/250/351/200/232/347/237/245-/351/273/221.svg +8 -0
  226. package/src/components/layout/message/message-icon//345/205/250/351/203/250/351/200/232/347/237/245.svg +8 -0
  227. package/src/components/layout/message/message-icon//345/205/254/345/221/212/351/200/232/347/237/245-/350/223/235.svg +12 -0
  228. package/src/components/layout/message/message-icon//345/205/254/345/221/212/351/200/232/347/237/245-/351/273/221.svg +12 -0
  229. package/src/components/layout/message/message-icon//345/205/254/345/221/212/351/200/232/347/237/245.svg +12 -0
  230. package/src/components/layout/message/message-icon//345/256/241/346/211/271/351/200/232/347/237/245-/350/223/235.svg +8 -0
  231. package/src/components/layout/message/message-icon//345/256/241/346/211/271/351/200/232/347/237/245-/351/273/221.svg +8 -0
  232. package/src/components/layout/message/message-icon//345/256/241/346/211/271/351/200/232/347/237/245.svg +8 -0
  233. package/src/components/layout/message/message-icon//345/257/274/345/207/272/351/200/232/347/237/245-/350/223/235.svg +13 -0
  234. package/src/components/layout/message/message-icon//345/257/274/345/207/272/351/200/232/347/237/245-/351/273/221.svg +13 -0
  235. package/src/components/layout/message/message-icon//345/257/274/345/207/272/351/200/232/347/237/245.svg +13 -0
  236. package/src/components/layout/message/message-icon//346/234/252/350/257/273/351/200/232/347/237/245-/350/223/235.svg +11 -0
  237. package/src/components/layout/message/message-icon//346/234/252/350/257/273/351/200/232/347/237/245-/351/273/221.svg +11 -0
  238. package/src/components/layout/message/message-icon//346/234/252/350/257/273/351/200/232/347/237/245.svg +11 -0
  239. package/src/components/layout/message/message-icon//347/251/272/347/212/266/346/200/201.svg +17 -0
  240. package/src/components/layout/message/message-icon//347/263/273/347/273/237/351/200/232/347/237/245-/350/223/235.svg +13 -0
  241. package/src/components/layout/message/message-icon//347/263/273/347/273/237/351/200/232/347/237/245-/351/273/221.svg +13 -0
  242. package/src/components/layout/message/message-icon//347/263/273/347/273/237/351/200/232/347/237/245.svg +13 -0
  243. package/src/components/layout/message/message-notification-drawer.vue +529 -0
  244. package/src/components/layout/personalization-guide-dialog.vue +255 -0
  245. package/src/components/layout/sideMenu-global.scss +115 -0
  246. package/src/components/layout/sideMenu.scss +312 -0
  247. package/src/components/layout/sideMenu.vue +542 -0
  248. package/src/components/layout/sideMenuSonList.vue +185 -0
  249. package/src/components/layout/styles/icon.scss +72 -0
  250. package/src/components/layout/types.ts +98 -0
  251. package/src/components/list-search-content/components/search-date-range.vue +1 -1
  252. package/src/components/list-search-content/components/search-date-time-range.vue +1 -1
  253. package/src/components/list-search-content/components/search-date.vue +1 -1
  254. package/src/components/list-search-content/components/search-input-number.vue +1 -1
  255. package/src/components/list-search-content/components/search-input.vue +1 -1
  256. package/src/components/list-search-content/components/search-multiple_select.vue +1 -1
  257. package/src/components/list-search-content/components/search-select.vue +1 -1
  258. package/src/components/list-search-content/index.vue +6 -6
  259. package/src/components/list-search-content/modules/add-views-package-dialog.vue +3 -3
  260. package/src/components/list-search-content/modules/search-condition-area.vue +2 -2
  261. package/src/components/list-search-content/modules/views-package-manage-dialog.vue +5 -5
  262. package/src/components.ts +19 -4
  263. package/src/index.ts +1 -0
  264. package/src/utils/dd-utils.ts +1 -1
  265. package/src/utils/get-dict.ts +2 -2
  266. package/src/utils/permit-utils.ts +2 -2
  267. package/src/api/bms/dict/bo/TotalDictSearchBO.ts +0 -8
  268. package/src/api/bms/file/FileExportController.ts +0 -18
  269. package/src/api/bms/file/bo/FileExportVO.ts +0 -17
@@ -0,0 +1,766 @@
1
+ <template>
2
+ <div class="flexColumnStart bigbox signComponentCommonBoxWeight">
3
+ <div v-if="!toSignStatus" class="flexRowStart signbox">
4
+ <div v-if="isSign" class="haveSign">
5
+ <div class="signImgBox">
6
+ <el-image style="width: 133px; height: 100px" :src="nowBindUrlMsg" fit="contain" v-if="nowBind" />
7
+ <!-- 未签名提示 -->
8
+ <div v-else class="no-sign-tip">
9
+ <svg class="tip-icon" viewBox="0 0 1024 1024" width="32" height="32">
10
+ <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="#d9d9d9"/>
11
+ <path d="M464 336a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm32 120h64c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-64c-4.4 0-8-3.6-8-8V464c0-4.4 3.6-8 8-8z" fill="#d9d9d9"/>
12
+ </svg>
13
+ <span class="tip-text">当前还未进行签字</span>
14
+ </div>
15
+ </div>
16
+ <el-button class="sign-btn" type="primary" @click="handleReSignClick">{{ nowBind ? "重签" : "去签字" }}</el-button>
17
+ </div>
18
+ <div v-else class="unHaveSign">
19
+ <div class="unHaveSignUp">
20
+ <div class="qrCodeImgBox">
21
+ <QrcodeVue :size="143" :value="codeContent" class="order-print-big-qrcode" ref="QrCodeRef" />
22
+ <!-- 已扫描状态覆盖层 -->
23
+ <div v-if="ifScanned" class="qrcode-status-overlay scanned">
24
+ <svg class="status-icon" viewBox="0 0 1024 1024" width="24" height="24">
25
+ <path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" fill="#333333"/>
26
+ </svg>
27
+ <span class="status-text">已扫描</span>
28
+ </div>
29
+ <!-- 已过期状态覆盖层 -->
30
+ <div v-if="ifExpired" class="qrcode-status-overlay expired" @click="handleReSignClick">
31
+ <svg class="status-icon" viewBox="0 0 1024 1024" width="24" height="24">
32
+ <path d="M960 416V192l-73.056 73.056a447.712 447.712 0 0 0-373.6-201.088C265.92 63.968 65.312 264.544 65.312 512S265.92 960.032 513.344 960.032a448.064 448.064 0 0 0 415.232-279.488 38.368 38.368 0 1 0-70.272-29.568 371.36 371.36 0 0 1-344.96 232.064c-205.408 0-371.36-165.984-371.36-371.04 0-205.088 165.952-371.04 371.36-371.04 108.896 0 206.752 47.2 274.464 122.016L736 314.016h224a32 32 0 0 0 32-32z" fill="#b0b0b0"/>
33
+ </svg>
34
+ <span class="status-text">二维码已过期,点击刷新</span>
35
+ </div>
36
+ </div>
37
+ <div class="qrCodeBtnBox">
38
+ <el-button type="primary" size="default" @click="handleReturnClick">取消</el-button>
39
+ </div>
40
+ </div>
41
+ <div class="uploadContent">使用钉钉扫码签名或点击上传</div>
42
+ <div class="uploadContent">为保证签名识别效果最佳,请选择纯白色背景、减少阴影的图片</div>
43
+ <div class="upload-link">
44
+ <a href="javascript:;" @click="triggerFileInput">
45
+ 已有签名?点击上传
46
+ </a>
47
+ </div>
48
+ <!-- 隐藏的 file input -->
49
+ <input
50
+ type="file"
51
+ ref="fileInput"
52
+ style="display: none;"
53
+ accept=".jpg,.jpeg,.png,.bmp,.raw,.heif,.tiff,.gif"
54
+ @change="handleFileChange"
55
+ >
56
+ </div>
57
+ </div>
58
+ <FullScreenSign v-if="fullScreenVisibly"></FullScreenSign>
59
+ <!-- 图片裁剪弹框 -->
60
+ <ImageCropper ref="imageCropperRef" @success="handleCropSuccess"></ImageCropper>
61
+ </div>
62
+ </template>
63
+ <script lang="ts" setup>
64
+ import { ref, onMounted, watch, onUnmounted } from 'vue'
65
+ import { IsPc } from '../../utils/getEnv'
66
+
67
+ import { HttpUtil } from "hrp-ui-base";
68
+ import { getUploadFileMsg } from '../../utils/base'
69
+ import { ElMessage } from 'element-plus'
70
+ import ImageCropper from '../image-cropper/index.vue'
71
+ const props = defineProps({
72
+ // 输出外边的值 同时也是 传入上次的值 ,数据类型是url的字符串
73
+ modelValue: {
74
+ type: String,
75
+ require: false,
76
+ default: ''
77
+ },
78
+ // 类型
79
+ type: {
80
+ type: String,
81
+ require: false,
82
+ default: ''
83
+ },
84
+ // 展示的签字图片的宽度
85
+ width: {
86
+ type: Number,
87
+ require: false
88
+ },
89
+ // 展示的签字图片的高度
90
+ height: {
91
+ type: Number,
92
+ require: false
93
+ },
94
+ // 谁的签字,备注alt
95
+ signOwner: {
96
+ type: String,
97
+ require: false,
98
+ default: ''
99
+ },
100
+ disabled: {
101
+ type: Boolean,
102
+ require: false,
103
+ default: false
104
+ },
105
+ uploadImgId: {
106
+ type: String,
107
+ require: false,
108
+ default: ''
109
+ }
110
+ })
111
+ const emits = defineEmits(['update:modelValue', 'uploadUploadImgId'])
112
+
113
+
114
+ const nowBind = ref<string>('')
115
+ const nowBindUrlMsg = ref<string>('')
116
+ const toSignStatus = ref<boolean>(false)
117
+ const changeSignStatus = (status: boolean) => {
118
+ toSignStatus.value = status
119
+ reset()
120
+ }
121
+ const currentImgId = ref<string>('')
122
+ watch(() => { return props.uploadImgId }, () => {
123
+ currentImgId.value = props.uploadImgId
124
+
125
+ }, { deep: true })
126
+ var canvas: any = document.getElementById("myCanvas")
127
+ console.dir(canvas)
128
+ var firstDraw = true;
129
+ var ifSign = false;
130
+ const canvasHeight = ref<number>(375)
131
+ const canvasWidth = ref<number>(500)
132
+ function clean() {
133
+ ifSign = false
134
+ }
135
+ function reset() {
136
+ ifSign = false
137
+ }
138
+ const ResizeInitFun = () => {
139
+ if (window.innerWidth < 800) {
140
+ if (IsPc()) {
141
+ canvasWidth.value = (window.innerWidth - 60)
142
+ canvasHeight.value = ((window.innerWidth - 60) * 0.75)
143
+ } else {
144
+ canvasWidth.value = (window.innerWidth - 60)
145
+ canvasHeight.value = ((window.innerWidth - 60) * 0.75)
146
+ }
147
+
148
+ } else {
149
+ }
150
+ firstDraw = true
151
+ }
152
+ const cancelSign = () => {
153
+ clean()
154
+ changeSignStatus(false)
155
+ }
156
+ const fullScreenVisibly = ref<boolean>(false)
157
+
158
+ onMounted(() => {
159
+ ResizeInitFun()
160
+ window.removeEventListener("resize", ResizeInitFun)
161
+ window.addEventListener("resize", ResizeInitFun)
162
+ })
163
+ watch(() => { props.modelValue }, () => {
164
+ nowBind.value = props.modelValue
165
+ nowBindUrlMsg.value = props.modelValue
166
+ }, { deep: true, immediate: true })
167
+ watch(nowBind, () => {
168
+ isSign.value = true
169
+ })
170
+ import FileUploadController from "hrp-ui-base/api/bms/file/FileUploadController"
171
+ // import { useUserConfigStore } from "@/stores";
172
+ import QrcodeVue from 'qrcode.vue';
173
+ import FlowSignController from "hrp-ui-base/api/bms/flow/FlowSignController"
174
+ // const userStore = useUserConfigStore();
175
+
176
+ const pageId = ref<string>('01-01-04-001')
177
+ const uploadOss = async (file: any) => {
178
+ const fileData = file;
179
+ FileUploadController.upload(fileData, pageId.value).then((data: any) => {
180
+ if (data.code === 200 && data.res) {
181
+ emits('update:modelValue', data.res.url)
182
+ currentImgId.value = data.res.fileId
183
+ emits('uploadUploadImgId', currentImgId.value)
184
+ cancelSign()
185
+ isSign.value = true
186
+ handleReturnClick()
187
+ } else {
188
+ ElMessage.error("数据发生错误,请重新上传!")
189
+ }
190
+ }).catch((err) => {
191
+ ElMessage.error("oss上传发生错误,请重试!")
192
+ console.error(err)
193
+ }).finally(() => {
194
+
195
+ })
196
+ }
197
+ const isSign = ref<boolean> (true)
198
+ const handleReSignClick = async () =>
199
+ {
200
+ generateQrCode()
201
+ await updateQrCodeStatus("unscanned")
202
+ startQueryStatus()
203
+ isSign.value = false
204
+ }
205
+ const handleReturnClick = async () => {
206
+ await updateQrCodeStatus("expired")
207
+ clearInterval(qrCodeTimeRecord.value)
208
+ clearInterval(queryQrCodeTimeRecord.value)
209
+ isSign.value = true
210
+ }
211
+
212
+ const fileInput = ref<HTMLInputElement>()
213
+ const imageCropperRef = ref<any>()
214
+ // 允许的图片格式
215
+ const allowedTypes = ['image/jpeg','image/png','image/bmp','image/raw','image/heif','image/tiff','image/gif'];
216
+ const allowedExtensions = ['.jpg','.jpeg','.png','.bmp','.raw','.heif','.tiff','.gif'];
217
+ // 最大文件大小(2MB)
218
+ const maxSize = 5 * 1024 * 1024
219
+ // 触发文件选择
220
+ const triggerFileInput = () => {
221
+ if (!fileInput.value)return
222
+ fileInput.value.click()
223
+ }
224
+ const handleFileChange = async (event: any) => {
225
+ const file = event.target.files[0]
226
+
227
+ if (!file) return
228
+
229
+ // 验证文件类型
230
+ if (!allowedTypes.includes(file.type)) {
231
+ ElMessage.error(`仅支持 ${allowedExtensions.join(', ')} 格式`)
232
+ resetFileInput()
233
+ return
234
+ }
235
+ // 验证文件大小
236
+ if (file.size > maxSize) {
237
+ const maxSizeMB = (maxSize / (1024 * 1024)).toFixed(1)
238
+ ElMessage.error(`文件大小不能超过 ${maxSizeMB}MB`)
239
+ resetFileInput()
240
+ return
241
+ }
242
+
243
+ try {
244
+ // 先处理图片(黑白化处理)
245
+ const processedBlob = await extractSignatureImageTransparent(file)
246
+
247
+ // 打开裁剪弹框,传入处理后的 Blob
248
+ imageCropperRef.value?.open(processedBlob)
249
+ } catch (e) {
250
+ console.error(e)
251
+ ElMessage.error('签名图片处理失败')
252
+ } finally {
253
+ resetFileInput()
254
+ }
255
+ }
256
+ // 重置 input
257
+ const resetFileInput = () => {
258
+ if (fileInput.value) {
259
+ fileInput.value.value = ''
260
+ }
261
+ }
262
+
263
+ // 裁剪成功回调
264
+ const handleCropSuccess = async (croppedBlob: Blob) => {
265
+ try {
266
+ // 将裁剪后的 Blob 转为 File 对象
267
+ const croppedFile = new File(
268
+ [croppedBlob],
269
+ '签名文件.png',
270
+ { type: 'image/png' }
271
+ )
272
+
273
+ // 上传裁剪后的图片
274
+ await uploadOss(croppedFile)
275
+ } catch (e) {
276
+ console.error(e)
277
+ ElMessage.error('签名图片上传失败')
278
+ }
279
+ }
280
+
281
+ const codeContent = ref<string>('')
282
+ const qrCodeUUID = ref<string>('')
283
+ const generateUUID = () => {
284
+ const timestamp = performance.now().toString(36)
285
+ const random = Math.random().toString(36).slice(2)
286
+ const random2 = Math.random().toString(36).slice(2)
287
+
288
+ return `${timestamp}-${random}-${random2}`.replace(/\./g, '')
289
+ }
290
+ const generateQrCode = () => {
291
+ ifScanned.value = false
292
+ ifExpired.value = false
293
+ qrCodeUUID.value = generateUUID()
294
+ const urlStr = `${window.location.origin}/mobile/login/index.html?host=${localStorage.getItem('TenantHost')}&url=${'/full-screen-sign-process'}?qrCodeUUID=${qrCodeUUID.value}`
295
+ // codeContent.value = 'http://172.16.14.36:5176/#/full-screen-sign-process?qrCodeUUID=' + qrCodeUUID.value
296
+ codeContent.value = urlStr
297
+ }
298
+
299
+ const qrCodeTimeRecord = ref<number>()
300
+ const startPolling = () => {
301
+ qrCodeTimeRecord.value = setInterval(async () => {
302
+ try {
303
+ const data = await FlowSignController.startPolling(qrCodeUUID.value)
304
+ if (data.code === 200 && data.res) {
305
+ clearInterval(qrCodeTimeRecord.value)
306
+ emits('update:modelValue', data.res.url)
307
+ currentImgId.value = data.res.fileId
308
+ emits('uploadUploadImgId', currentImgId.value)
309
+ }
310
+ } catch (e) {
311
+ console.log(false)
312
+ }
313
+ }, 2000)
314
+ }
315
+ const queryQrCodeTimeRecord = ref<number>()
316
+ const startQueryStatus = () => {
317
+ queryQrCodeTimeRecord.value = setInterval(() => {
318
+ FlowSignController.queryQrCodeStatus(qrCodeUUID.value).then(data => {
319
+ if (data.code === 200 && data.res === "scanned") {
320
+ clearInterval(queryQrCodeTimeRecord.value)
321
+ ifScanned.value = true
322
+ startPolling()
323
+ } else if (data.code === 200 && (data.res === null || data.res === "expired")) {
324
+ clearInterval(queryQrCodeTimeRecord.value)
325
+ ifExpired.value = true
326
+ ElMessage.error("二维码已过期,请刷新")
327
+ } else {
328
+ console.log("正在轮询二维码状态")
329
+ }
330
+ })
331
+ }, 2000)
332
+ }
333
+ const ifScanned = ref<boolean>(false)
334
+ const ifExpired = ref<boolean>()
335
+ const updateQrCodeStatus = (status: string) => {
336
+ if (status === 'scanned') {
337
+ ifScanned.value = true
338
+ } else if (status === 'expired') {
339
+ ifExpired.value = true
340
+ }
341
+ FlowSignController.updateQrCodeStatus(status, qrCodeUUID.value).then(data => {
342
+ if (data.code === 200 && data.res) {
343
+ console.log("二维码状态更新成功")
344
+ } else if (data.code === 200 && !data.res) {
345
+ ElMessage.error(data.msg || "二维码失效请刷新后重试")
346
+ }
347
+ })
348
+ }
349
+ const dialogClose = () => {
350
+ clearInterval(qrCodeTimeRecord.value)
351
+ clearInterval(queryQrCodeTimeRecord.value)
352
+ ifScanned.value = false
353
+ ifExpired.value = false
354
+ isSign.value = true
355
+ }
356
+
357
+ /**
358
+ * 将签名图片处理成:白色背景 + 黑色笔迹
359
+ */
360
+ const extractSignatureImageTransparent = (file: File): Promise<Blob> => {
361
+ return new Promise((resolve, reject) => {
362
+ const img = new Image()
363
+ img.onload = () => {
364
+ const canvas = document.createElement('canvas')
365
+ const ctx = canvas.getContext('2d')!
366
+
367
+ canvas.width = img.width
368
+ canvas.height = img.height
369
+ ctx.drawImage(img, 0, 0)
370
+
371
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
372
+ const data = imageData.data
373
+
374
+ // 计算灰度
375
+ const grays: number[] = []
376
+ let min = 255, max = 0
377
+ for (let i = 0; i < data.length; i += 4) {
378
+ const gray = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2]
379
+ grays.push(gray)
380
+ min = Math.min(min, gray)
381
+ max = Math.max(max, gray)
382
+ }
383
+
384
+ const threshold = min + (max - min) * 0.35
385
+
386
+ // 设置 alpha 通道
387
+ for (let i = 0; i < data.length; i += 4) {
388
+ const gray = grays[i / 4]
389
+ if (gray > threshold) {
390
+ data[i + 3] = 0 // 背景透明
391
+ } else {
392
+ data[i] = data[i + 1] = data[i + 2] = 0 // 签名黑色
393
+ data[i + 3] = 255 // 签名不透明
394
+ }
395
+ }
396
+
397
+ enhanceContrast(data)
398
+ for (let i = 0; i < 2; i++) {
399
+ dilateAlpha(data, canvas.width, canvas.height, 1)
400
+ fillGapsAlpha(data, canvas.width, canvas.height)
401
+ }
402
+ removeHorizontalLines(data, canvas.width, canvas.height)
403
+ ctx.putImageData(imageData, 0, 0)
404
+
405
+ canvas.toBlob(
406
+ blob => blob ? resolve(blob) : reject(),
407
+ 'image/png',
408
+ 1
409
+ )
410
+ }
411
+
412
+ img.onerror = reject
413
+ img.src = URL.createObjectURL(file)
414
+ })
415
+ }
416
+
417
+ const dilateAlpha = (data: Uint8ClampedArray, width: number, height: number, radius = 1) => {
418
+ const copy = new Uint8ClampedArray(data)
419
+ const idx = (x: number, y: number) => (y * width + x) * 4
420
+
421
+ for (let y = radius; y < height - radius; y++) {
422
+ for (let x = radius; x < width - radius; x++) {
423
+ const center = idx(x, y)
424
+ if (copy[center + 3] === 255) continue
425
+
426
+ // 检查周围 radius 范围内是否有签名像素
427
+ let hasOpaqueNeighbor = false
428
+ for (let dy = -radius; dy <= radius && !hasOpaqueNeighbor; dy++) {
429
+ for (let dx = -radius; dx <= radius; dx++) {
430
+ const i = idx(x + dx, y + dy)
431
+ if (copy[i + 3] === 255) {
432
+ hasOpaqueNeighbor = true
433
+ break
434
+ }
435
+ }
436
+ }
437
+
438
+ if (hasOpaqueNeighbor) {
439
+ // 将 alpha 设为签名不透明,同时保持原颜色
440
+ data[center + 3] = 255
441
+ for (let c = 0; c < 3; c++) {
442
+ data[center + c] = copy[center + c] // 保持原色
443
+ }
444
+ }
445
+ }
446
+ }
447
+ }
448
+
449
+
450
+ const fillGapsAlpha = (data: Uint8ClampedArray, width: number, height: number) => {
451
+ const copy = new Uint8ClampedArray(data)
452
+ const idx = (x: number, y: number) => (y * width + x) * 4
453
+
454
+ for (let y = 1; y < height - 1; y++) {
455
+ for (let x = 1; x < width - 1; x++) {
456
+ const i = idx(x, y)
457
+ if (copy[i + 3] === 255) continue // 空隙才处理
458
+
459
+ let opaqueCount = 0
460
+ let r = [0,0,0]
461
+ for (const [dx, dy] of [[1,0],[-1,0],[0,1],[0,-1]]) {
462
+ const neighbor = idx(x + dx, y + dy)
463
+ if (copy[neighbor + 3] === 255) {
464
+ opaqueCount++
465
+ for (let c = 0; c < 3; c++) r[c] += copy[neighbor + c]
466
+ }
467
+ }
468
+
469
+ if (opaqueCount >= 2) { // 如果周围至少两个像素是签名,则填充
470
+ data[i + 3] = 255
471
+ for (let c = 0; c < 3; c++) data[i + c] = Math.round(r[c] / opaqueCount)
472
+ }
473
+ }
474
+ }
475
+ }
476
+
477
+ const enhanceContrast = (data: Uint8ClampedArray) => {
478
+ for (let i = 0; i < data.length; i += 4) {
479
+ if (data[i + 3] === 255) {
480
+ // gamma增强 + 轻微加粗效果
481
+ for (let c = 0; c < 3; c++) {
482
+ const val = data[i + c] / 255
483
+ data[i + c] = Math.min(255, Math.pow(val, 0.4) * 255) // gamma 0.4,比原先更深
484
+ }
485
+ }
486
+ }
487
+ }
488
+
489
+
490
+ const removeHorizontalLines = (data: Uint8ClampedArray, width: number, height: number) => {
491
+ const threshold = width * 0.7 // 横线长度阈值
492
+ const idx = (x: number, y: number) => (y * width + x) * 4
493
+
494
+ for (let y = 0; y < height; y++) {
495
+ let count = 0
496
+ let startX = 0
497
+ for (let x = 0; x < width; x++) {
498
+ if (data[idx(x, y) + 3] === 255) {
499
+ if (count === 0) startX = x
500
+ count++
501
+ } else {
502
+ if (count > threshold) {
503
+ // 认定为横线噪声,清除
504
+ for (let i = startX; i < x; i++) {
505
+ data[idx(i, y) + 3] = 0
506
+ }
507
+ }
508
+ count = 0
509
+ }
510
+ }
511
+ // 检查行末尾横线
512
+ if (count > threshold) {
513
+ for (let i = startX; i < width; i++) {
514
+ data[idx(i, y) + 3] = 0
515
+ }
516
+ }
517
+ }
518
+ }
519
+
520
+ defineExpose({
521
+ dialogClose: () => dialogClose()
522
+ })
523
+ onUnmounted(() => {
524
+ dialogClose()
525
+ })
526
+ </script>
527
+ <style scoped lang="scss">
528
+ @use '../../styles/common.scss';
529
+
530
+ .bigbox {
531
+ width: 100%;
532
+ }
533
+
534
+ .signbox {
535
+ margin-top: 8px;
536
+ width: 100%;
537
+ }
538
+
539
+ .haveSign {
540
+ display: flex;
541
+ justify-content: center;
542
+ align-items: flex-start;
543
+ width: 100%;
544
+ margin: 0 auto;
545
+ min-height: 197px;
546
+ text-align: center;
547
+ position: relative;
548
+ }
549
+
550
+ .sign-btn {
551
+ position: absolute;
552
+ right: calc(50% - 145px);
553
+ top: 72.5px;
554
+ margin-left: 16px;
555
+ }
556
+
557
+ .unHaveSign {
558
+ width: 100%;
559
+ margin: 0 auto;
560
+ min-height: 197px;
561
+ text-align: center;
562
+ position: relative;
563
+
564
+ .uploadContent {
565
+ margin-bottom: 5px;
566
+ font-size: 11.5px;
567
+ }
568
+
569
+ .upload-link {
570
+ font-weight: 500;
571
+ font-size: 10px;
572
+ color: #409eff;
573
+ text-decoration: none;
574
+ line-height: 1.5;
575
+ letter-spacing: 0.5px;
576
+ word-spacing: 2px;
577
+ text-transform: none;
578
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
579
+ cursor: pointer;
580
+ transition: all 0.3s ease;
581
+ }
582
+ }
583
+
584
+ .signImgBox,.qrCodeImgBox {
585
+ box-sizing: border-box;
586
+ width: 145px;
587
+ height: 145px;
588
+ // border: 1px solid gray;
589
+ overflow: hidden;
590
+ margin: 0 auto 15px;
591
+ position: relative;
592
+
593
+ // 当遮罩层显示时,对底层二维码应用强力视觉破坏
594
+ &:has(.qrcode-status-overlay) {
595
+ .order-print-big-qrcode {
596
+ filter: blur(8px) contrast(0.3) brightness(1.5) saturate(0);
597
+ opacity: 0.15;
598
+ transform: scale(1.2) rotate(5deg);
599
+ }
600
+ }
601
+ }
602
+
603
+ .signImgBox {
604
+ width: 133px;
605
+ height: 100px;
606
+ margin-top: 50px;
607
+ display: flex;
608
+ align-items: center;
609
+ justify-content: center;
610
+
611
+ // 未签名提示样式
612
+ .no-sign-tip {
613
+ display: flex;
614
+ flex-direction: column;
615
+ align-items: center;
616
+ justify-content: center;
617
+ width: 100%;
618
+ height: 100%;
619
+ background: #fafafa;
620
+ border-radius: 4px;
621
+ gap: 8px;
622
+
623
+ .tip-icon {
624
+ flex-shrink: 0;
625
+ }
626
+
627
+ .tip-text {
628
+ font-size: 12px;
629
+ color: #999;
630
+ text-align: center;
631
+ line-height: 1.4;
632
+ padding: 0 8px;
633
+ }
634
+ }
635
+ }
636
+
637
+ .unHaveSignUp {
638
+ display: flex;
639
+ justify-content: center;
640
+ position: relative;
641
+
642
+ .qrCodeBtnBox {
643
+ position: absolute;
644
+ right: calc(50% - 145px);
645
+ top: 72.5px;
646
+ margin-left: 16px;
647
+ display: flex;
648
+ flex-direction: column;
649
+ gap: 8px;
650
+
651
+ .el-button + .el-button {
652
+ margin-left: 0 !important;
653
+ }
654
+
655
+ .el-button {
656
+ min-width: 60px;
657
+ }
658
+ }
659
+
660
+ .uploadContent {
661
+ margin-top: 8px;
662
+ }
663
+ }
664
+
665
+ // 二维码状态覆盖层样式 - PC端简洁风格 + 强力防扫描
666
+ .qrcode-status-overlay {
667
+ position: absolute;
668
+ top: 0;
669
+ left: 0;
670
+ right: 0;
671
+ bottom: 0;
672
+ display: flex;
673
+ flex-direction: column;
674
+ align-items: center;
675
+ justify-content: center;
676
+ gap: 6px;
677
+ animation: fadeIn 0.25s ease-out;
678
+ z-index: 10;
679
+
680
+ // 简洁的单层细密网格
681
+ &::before {
682
+ content: '';
683
+ position: absolute;
684
+ top: 0;
685
+ left: 0;
686
+ right: 0;
687
+ bottom: 0;
688
+ background-image:
689
+ repeating-linear-gradient(
690
+ 0deg,
691
+ transparent,
692
+ transparent 1px,
693
+ currentColor 1px,
694
+ currentColor 2px
695
+ ),
696
+ repeating-linear-gradient(
697
+ 90deg,
698
+ transparent,
699
+ transparent 1px,
700
+ currentColor 1px,
701
+ currentColor 2px
702
+ );
703
+ opacity: 0.25;
704
+ z-index: 1;
705
+ }
706
+
707
+ .status-icon {
708
+ flex-shrink: 0;
709
+ position: relative;
710
+ z-index: 3;
711
+ }
712
+
713
+ .status-text {
714
+ font-size: 12px;
715
+ font-weight: 400;
716
+ letter-spacing: 0.5px;
717
+ line-height: 1;
718
+ position: relative;
719
+ z-index: 3;
720
+ }
721
+
722
+ // 已扫描状态 - 简洁白色
723
+ &.scanned {
724
+ background: rgba(255, 255, 255, 0.96);
725
+ color: rgba(100, 100, 100, 0.3);
726
+
727
+ .status-text {
728
+ color: #333333;
729
+ }
730
+ }
731
+
732
+ // 已过期状态 - 简洁深色
733
+ &.expired {
734
+ background: rgba(40, 40, 40, 0.92);
735
+ color: rgba(180, 180, 180, 0.3);
736
+ cursor: pointer;
737
+
738
+ .status-text {
739
+ color: #e0e0e0;
740
+ }
741
+
742
+ .status-icon path {
743
+ fill: #b0b0b0;
744
+ }
745
+ }
746
+ }
747
+
748
+ // 淡入动画
749
+ @keyframes fadeIn {
750
+ from {
751
+ opacity: 0;
752
+ }
753
+ to {
754
+ opacity: 1;
755
+ }
756
+ }
757
+ </style>
758
+ <style lang="scss">
759
+ .signComponentCommonBoxWeight {
760
+ .el-textarea__inner {
761
+ height: 37px;
762
+ min-height: 37px !important;
763
+ }
764
+
765
+ }
766
+ </style>