@sugarat/easypicker2-client 2.7.3 → 2.8.1

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 (391) hide show
  1. package/dist/assets/aria-legacy-B70JmEZA.js.map +1 -1
  2. package/dist/assets/aria-nkjrUMQ-.js.map +1 -1
  3. package/dist/assets/config-CDHxxo7b.js +2 -0
  4. package/dist/assets/config-CDHxxo7b.js.map +1 -0
  5. package/dist/assets/config-CnEgj70a.css +1 -0
  6. package/dist/assets/config-legacy-n3sQ5kGn.js +2 -0
  7. package/dist/assets/config-legacy-n3sQ5kGn.js.map +1 -0
  8. package/dist/assets/{data-analysis-Bnq_VWU8.js → data-analysis-DBnVKJmJ.js} +2 -2
  9. package/dist/assets/data-analysis-DBnVKJmJ.js.map +1 -0
  10. package/dist/assets/{data-analysis-legacy-_KcR253K.js → data-analysis-legacy-4qD1YhB2.js} +2 -2
  11. package/dist/assets/data-analysis-legacy-4qD1YhB2.js.map +1 -0
  12. package/dist/assets/{data-board-L3s5ouKd.js → data-board-DeJXppeB.js} +2 -2
  13. package/dist/assets/data-board-DeJXppeB.js.map +1 -0
  14. package/dist/assets/{data-board-legacy-BFxWeFnQ.js → data-board-legacy-8OJulkyJ.js} +2 -2
  15. package/dist/assets/data-board-legacy-8OJulkyJ.js.map +1 -0
  16. package/dist/assets/delete-filled-DvkAD61M.js +2 -0
  17. package/dist/assets/delete-filled-DvkAD61M.js.map +1 -0
  18. package/dist/assets/delete-filled-legacy-BhHT0v2W.js +2 -0
  19. package/dist/assets/delete-filled-legacy-BhHT0v2W.js.map +1 -0
  20. package/dist/assets/el-date-picker-BX8jtnY2.js +2 -0
  21. package/dist/assets/el-date-picker-BX8jtnY2.js.map +1 -0
  22. package/dist/assets/el-date-picker-legacy-iQW0501V.js +2 -0
  23. package/dist/assets/el-date-picker-legacy-iQW0501V.js.map +1 -0
  24. package/dist/assets/el-dropdown-item-BQ-7lFIb.js +2 -0
  25. package/dist/assets/el-dropdown-item-BQ-7lFIb.js.map +1 -0
  26. package/dist/assets/el-dropdown-item-legacy-D5N_3F3d.js +2 -0
  27. package/dist/assets/el-dropdown-item-legacy-D5N_3F3d.js.map +1 -0
  28. package/dist/assets/el-empty-BZNyAlA7.js +2 -0
  29. package/dist/assets/el-empty-BZNyAlA7.js.map +1 -0
  30. package/dist/assets/el-empty-C2yupmrg.css +1 -0
  31. package/dist/assets/el-empty-legacy--8JR0M1C.js +2 -0
  32. package/dist/assets/el-empty-legacy--8JR0M1C.js.map +1 -0
  33. package/dist/assets/el-input-number-C0Bp8kfg.js +2 -0
  34. package/dist/assets/el-input-number-C0Bp8kfg.js.map +1 -0
  35. package/dist/assets/el-input-number-CU7OpiYS.css +1 -0
  36. package/dist/assets/el-input-number-legacy-CaZROy3J.js +2 -0
  37. package/dist/assets/el-input-number-legacy-CaZROy3J.js.map +1 -0
  38. package/dist/assets/{el-loading-DNzUD85e.js → el-loading-DgUVClxn.js} +2 -2
  39. package/dist/assets/el-loading-DgUVClxn.js.map +1 -0
  40. package/dist/assets/el-loading-legacy-BpxkUp1m.js +2 -0
  41. package/dist/assets/el-loading-legacy-BpxkUp1m.js.map +1 -0
  42. package/dist/assets/el-pagination-DX6u100-.js +2 -0
  43. package/dist/assets/el-pagination-DX6u100-.js.map +1 -0
  44. package/dist/assets/el-pagination-legacy-BcfQQTNs.js +2 -0
  45. package/dist/assets/el-pagination-legacy-BcfQQTNs.js.map +1 -0
  46. package/dist/assets/el-scrollbar-D2RZSJkX.js +2 -0
  47. package/dist/assets/el-scrollbar-D2RZSJkX.js.map +1 -0
  48. package/dist/assets/el-scrollbar-DFu7lMno.css +1 -0
  49. package/dist/assets/el-scrollbar-legacy-CLEobATW.js +2 -0
  50. package/dist/assets/el-scrollbar-legacy-CLEobATW.js.map +1 -0
  51. package/dist/assets/el-select-DWyBOD47.js +2 -0
  52. package/dist/assets/el-select-DWyBOD47.js.map +1 -0
  53. package/dist/assets/el-select-Dm4tLYz8.css +1 -0
  54. package/dist/assets/el-select-legacy-Cvxrwg7z.js +2 -0
  55. package/dist/assets/el-select-legacy-Cvxrwg7z.js.map +1 -0
  56. package/dist/assets/el-switch-c6xoppF3.js +2 -0
  57. package/dist/assets/el-switch-c6xoppF3.js.map +1 -0
  58. package/dist/assets/el-switch-legacy-DCF_46l4.js +2 -0
  59. package/dist/assets/el-switch-legacy-DCF_46l4.js.map +1 -0
  60. package/dist/assets/el-tab-pane-DWJdeyqN.js +2 -0
  61. package/dist/assets/el-tab-pane-DWJdeyqN.js.map +1 -0
  62. package/dist/assets/{el-tab-pane-legacy-DMdhUCHY.js → el-tab-pane-legacy-Cgd5IxXQ.js} +2 -2
  63. package/dist/assets/el-tab-pane-legacy-Cgd5IxXQ.js.map +1 -0
  64. package/dist/assets/{el-table-column-tkbtgrcD.js → el-table-column-DdhVw628.js} +3 -3
  65. package/dist/assets/el-table-column-DdhVw628.js.map +1 -0
  66. package/dist/assets/el-table-column-legacy-D1aU2dQP.js +24 -0
  67. package/dist/assets/el-table-column-legacy-D1aU2dQP.js.map +1 -0
  68. package/dist/assets/el-tag-Bgje3_SF.css +1 -0
  69. package/dist/assets/el-tag-legacy-DxOZcEw1.js +2 -0
  70. package/dist/assets/el-tag-legacy-DxOZcEw1.js.map +1 -0
  71. package/dist/assets/el-tag-uk6aooq0.js +2 -0
  72. package/dist/assets/el-tag-uk6aooq0.js.map +1 -0
  73. package/dist/assets/el-upload-B2Zxm6X5.css +1 -0
  74. package/dist/assets/el-upload-BxExG7hd.js +2 -0
  75. package/dist/assets/el-upload-BxExG7hd.js.map +1 -0
  76. package/dist/assets/el-upload-legacy-D8KH6HBU.js +2 -0
  77. package/dist/assets/el-upload-legacy-D8KH6HBU.js.map +1 -0
  78. package/dist/assets/index--nCmso-n.js +2 -0
  79. package/dist/assets/index--nCmso-n.js.map +1 -0
  80. package/dist/assets/index-2qujr45D.js +2 -0
  81. package/dist/assets/index-2qujr45D.js.map +1 -0
  82. package/dist/assets/index-6fj8rr7z.js +2 -0
  83. package/dist/assets/index-6fj8rr7z.js.map +1 -0
  84. package/dist/assets/index-8vfFTV-B.css +1 -0
  85. package/dist/assets/index-B-yBTqWJ.js +2 -0
  86. package/dist/assets/index-B-yBTqWJ.js.map +1 -0
  87. package/dist/assets/index-BC_fnfOg.js +2 -0
  88. package/dist/assets/index-BC_fnfOg.js.map +1 -0
  89. package/dist/assets/{index-C4H-Ptjt.css → index-BDkChTag.css} +1 -1
  90. package/dist/assets/index-BDsN2eKB.js +2 -0
  91. package/dist/assets/index-BDsN2eKB.js.map +1 -0
  92. package/dist/assets/index-BSIRw8UD.js +2 -0
  93. package/dist/assets/index-BSIRw8UD.js.map +1 -0
  94. package/dist/assets/index-BSMNPGJ5.css +1 -0
  95. package/dist/assets/index-BVEIUX2D.js +2 -0
  96. package/dist/assets/index-BVEIUX2D.js.map +1 -0
  97. package/dist/assets/index-BVp20vyj.css +1 -0
  98. package/dist/assets/index-BcJxc1ki.css +1 -0
  99. package/dist/assets/index-BgihxBmj.css +1 -0
  100. package/dist/assets/index-BjSgvXxj.css +1 -0
  101. package/dist/assets/index-BmheqIC4.js +2 -0
  102. package/dist/assets/index-BmheqIC4.js.map +1 -0
  103. package/dist/assets/index-BrOLxzFM.js.map +1 -1
  104. package/dist/assets/{index-ehQnwCE_.css → index-Bxvzu7zF.css} +1 -1
  105. package/dist/assets/index-CFpIdG49.css +1 -0
  106. package/dist/assets/index-CKVj2mCd.js +2 -0
  107. package/dist/assets/index-CKVj2mCd.js.map +1 -0
  108. package/dist/assets/index-CLt64lxI.js +2 -0
  109. package/dist/assets/index-CLt64lxI.js.map +1 -0
  110. package/dist/assets/index-COI3CDfm.js +2 -0
  111. package/dist/assets/index-COI3CDfm.js.map +1 -0
  112. package/dist/assets/index-CQud0ONT.css +1 -0
  113. package/dist/assets/index-CkyNID7q.css +1 -0
  114. package/dist/assets/index-CsTsOuFs.js +2 -0
  115. package/dist/assets/index-CsTsOuFs.js.map +1 -0
  116. package/dist/assets/index-CsfbnGni.css +1 -0
  117. package/dist/assets/index-D5EKLT5I.js +2 -0
  118. package/dist/assets/index-D5EKLT5I.js.map +1 -0
  119. package/dist/assets/index-D94P-51I.css +1 -0
  120. package/dist/assets/index-DBQzOZB-.js +23 -0
  121. package/dist/assets/index-DBQzOZB-.js.map +1 -0
  122. package/dist/assets/index-DC08DNQQ.js +2 -0
  123. package/dist/assets/index-DC08DNQQ.js.map +1 -0
  124. package/dist/assets/index-DLuR61Hw.css +1 -0
  125. package/dist/assets/index-DT7ciPLb.js +2 -0
  126. package/dist/assets/index-DT7ciPLb.js.map +1 -0
  127. package/dist/assets/index-DYTxk2nM.js +2 -0
  128. package/dist/assets/index-DYTxk2nM.js.map +1 -0
  129. package/dist/assets/index-DbhWmXsj.js +40 -0
  130. package/dist/assets/index-DbhWmXsj.js.map +1 -0
  131. package/dist/assets/index-DcUtl6Nq.css +1 -0
  132. package/dist/assets/index-DpoyDAhf.js +2 -0
  133. package/dist/assets/index-DpoyDAhf.js.map +1 -0
  134. package/dist/assets/index-Ds7mlGo_.js +2 -0
  135. package/dist/assets/index-Ds7mlGo_.js.map +1 -0
  136. package/dist/assets/index-FISBGs_l.css +1 -0
  137. package/dist/assets/index-FkvPFOBZ.js +2 -0
  138. package/dist/assets/index-FkvPFOBZ.js.map +1 -0
  139. package/dist/assets/index-HJwe3MZ4.js +2 -0
  140. package/dist/assets/index-HJwe3MZ4.js.map +1 -0
  141. package/dist/assets/index-LKJh-8oZ.css +1 -0
  142. package/dist/assets/index-Q8b92C8V.css +1 -0
  143. package/dist/assets/index-legacy-0p9exu0M.js +2 -0
  144. package/dist/assets/index-legacy-0p9exu0M.js.map +1 -0
  145. package/dist/assets/index-legacy-2gZknrAr.js +2 -0
  146. package/dist/assets/index-legacy-2gZknrAr.js.map +1 -0
  147. package/dist/assets/index-legacy-AH8uXlwH.js +2 -0
  148. package/dist/assets/index-legacy-AH8uXlwH.js.map +1 -0
  149. package/dist/assets/index-legacy-BTvagK_v.js +2 -0
  150. package/dist/assets/index-legacy-BTvagK_v.js.map +1 -0
  151. package/dist/assets/index-legacy-BUrH0Ubh.js +2 -0
  152. package/dist/assets/index-legacy-BUrH0Ubh.js.map +1 -0
  153. package/dist/assets/index-legacy-BVk27mxb.js +2 -0
  154. package/dist/assets/index-legacy-BVk27mxb.js.map +1 -0
  155. package/dist/assets/index-legacy-BnfLqgKz.js +2 -0
  156. package/dist/assets/index-legacy-BnfLqgKz.js.map +1 -0
  157. package/dist/assets/index-legacy-BsWj1xV2.js +54 -0
  158. package/dist/assets/index-legacy-BsWj1xV2.js.map +1 -0
  159. package/dist/assets/index-legacy-Bvis80MO.js +2 -0
  160. package/dist/assets/index-legacy-Bvis80MO.js.map +1 -0
  161. package/dist/assets/index-legacy-BxqvVJh6.js +16 -0
  162. package/dist/assets/index-legacy-BxqvVJh6.js.map +1 -0
  163. package/dist/assets/index-legacy-C-gHf8SN.js.map +1 -1
  164. package/dist/assets/index-legacy-C8OALizf.js +2 -0
  165. package/dist/assets/index-legacy-C8OALizf.js.map +1 -0
  166. package/dist/assets/index-legacy-Ca1NdJPm.js +2 -0
  167. package/dist/assets/index-legacy-Ca1NdJPm.js.map +1 -0
  168. package/dist/assets/index-legacy-D3Gbb8pX.js +2 -0
  169. package/dist/assets/index-legacy-D3Gbb8pX.js.map +1 -0
  170. package/dist/assets/index-legacy-DFUJlpQR.js +2 -0
  171. package/dist/assets/index-legacy-DFUJlpQR.js.map +1 -0
  172. package/dist/assets/index-legacy-DNPnYZJW.js +2 -0
  173. package/dist/assets/index-legacy-DNPnYZJW.js.map +1 -0
  174. package/dist/assets/index-legacy-DaUa56O-.js +2 -0
  175. package/dist/assets/index-legacy-DaUa56O-.js.map +1 -0
  176. package/dist/assets/index-legacy-DqfRlqrq.js +2 -0
  177. package/dist/assets/index-legacy-DqfRlqrq.js.map +1 -0
  178. package/dist/assets/index-legacy-DyJmAPRK.js +2 -0
  179. package/dist/assets/index-legacy-DyJmAPRK.js.map +1 -0
  180. package/dist/assets/index-legacy-DziFQjpX.js +2 -0
  181. package/dist/assets/index-legacy-DziFQjpX.js.map +1 -0
  182. package/dist/assets/index-legacy-N9COO-uZ.js +2 -0
  183. package/dist/assets/index-legacy-N9COO-uZ.js.map +1 -0
  184. package/dist/assets/index-legacy-P9gt2mpu.js +2 -0
  185. package/dist/assets/index-legacy-P9gt2mpu.js.map +1 -0
  186. package/dist/assets/index-legacy-c8lop5xr.js +2 -0
  187. package/dist/assets/index-legacy-c8lop5xr.js.map +1 -0
  188. package/dist/assets/index-legacy-npRizjoU.js +2 -0
  189. package/dist/assets/index-legacy-npRizjoU.js.map +1 -0
  190. package/dist/assets/index-legacy-xL9mLEDR.js +2 -0
  191. package/dist/assets/index-legacy-xL9mLEDR.js.map +1 -0
  192. package/dist/assets/index-mtfctTgx.css +1 -0
  193. package/dist/assets/index-oKiyEdt0.js +2 -0
  194. package/dist/assets/index-oKiyEdt0.js.map +1 -0
  195. package/dist/assets/linkDialog-D30VnNS0.js +2 -0
  196. package/dist/assets/linkDialog-D30VnNS0.js.map +1 -0
  197. package/dist/assets/linkDialog-Dida934t.css +1 -0
  198. package/dist/assets/linkDialog-legacy-CCHpjX0B.js +2 -0
  199. package/dist/assets/linkDialog-legacy-CCHpjX0B.js.map +1 -0
  200. package/dist/assets/other-BiIe9Z0L.js +2 -0
  201. package/dist/assets/other-BiIe9Z0L.js.map +1 -0
  202. package/dist/assets/other-legacy-Bfm4KL87.js +2 -0
  203. package/dist/assets/other-legacy-Bfm4KL87.js.map +1 -0
  204. package/dist/assets/polyfills-legacy-DqO_DCwg.js +1 -0
  205. package/dist/assets/{refresh-DPuuDO9h.js → refresh-Cccf8YoS.js} +2 -2
  206. package/dist/assets/refresh-Cccf8YoS.js.map +1 -0
  207. package/dist/assets/{refresh-legacy-DOts-8Wc.js → refresh-legacy-BwFA7z7t.js} +2 -2
  208. package/dist/assets/refresh-legacy-BwFA7z7t.js.map +1 -0
  209. package/dist/assets/tip-Nu5QmDDd.js +2 -0
  210. package/dist/assets/tip-Nu5QmDDd.js.map +1 -0
  211. package/dist/assets/tip-legacy-D_0YSCxT.js +2 -0
  212. package/dist/assets/tip-legacy-D_0YSCxT.js.map +1 -0
  213. package/dist/assets/tipInfo-BPHCIpRm.css +1 -0
  214. package/dist/assets/tipInfo-D75KJpWg.js +2 -0
  215. package/dist/assets/tipInfo-D75KJpWg.js.map +1 -0
  216. package/dist/assets/tipInfo-legacy-CV235bKZ.js +2 -0
  217. package/dist/assets/tipInfo-legacy-CV235bKZ.js.map +1 -0
  218. package/dist/index.html +105 -128
  219. package/package.json +13 -34
  220. package/README.md +0 -86
  221. package/dist/assets/data-analysis-Bnq_VWU8.js.map +0 -1
  222. package/dist/assets/data-analysis-legacy-_KcR253K.js.map +0 -1
  223. package/dist/assets/data-board-L3s5ouKd.js.map +0 -1
  224. package/dist/assets/data-board-legacy-BFxWeFnQ.js.map +0 -1
  225. package/dist/assets/el-date-picker-legacy-Uk9x97L5.js +0 -2
  226. package/dist/assets/el-date-picker-legacy-Uk9x97L5.js.map +0 -1
  227. package/dist/assets/el-date-picker-mhY2RJMG.js +0 -2
  228. package/dist/assets/el-date-picker-mhY2RJMG.js.map +0 -1
  229. package/dist/assets/el-dialog-Cu2jwelC.css +0 -1
  230. package/dist/assets/el-dialog-PRccau6N.js +0 -2
  231. package/dist/assets/el-dialog-PRccau6N.js.map +0 -1
  232. package/dist/assets/el-dialog-legacy-BRLM43ZY.js +0 -2
  233. package/dist/assets/el-dialog-legacy-BRLM43ZY.js.map +0 -1
  234. package/dist/assets/el-dropdown-item-Cr71teRg.js +0 -2
  235. package/dist/assets/el-dropdown-item-Cr71teRg.js.map +0 -1
  236. package/dist/assets/el-dropdown-item-legacy-B0ufpHvy.js +0 -2
  237. package/dist/assets/el-dropdown-item-legacy-B0ufpHvy.js.map +0 -1
  238. package/dist/assets/el-form-item-Cc9R0dZ1.css +0 -1
  239. package/dist/assets/el-form-item-DOwM4Mv8.js +0 -2
  240. package/dist/assets/el-form-item-DOwM4Mv8.js.map +0 -1
  241. package/dist/assets/el-form-item-legacy-CvQy7syv.js +0 -2
  242. package/dist/assets/el-form-item-legacy-CvQy7syv.js.map +0 -1
  243. package/dist/assets/el-loading-DNzUD85e.js.map +0 -1
  244. package/dist/assets/el-loading-legacy-B3RLcjwN.js +0 -2
  245. package/dist/assets/el-loading-legacy-B3RLcjwN.js.map +0 -1
  246. package/dist/assets/el-pagination-iCicJonH.js +0 -2
  247. package/dist/assets/el-pagination-iCicJonH.js.map +0 -1
  248. package/dist/assets/el-pagination-legacy-Bf-Bzx7n.js +0 -2
  249. package/dist/assets/el-pagination-legacy-Bf-Bzx7n.js.map +0 -1
  250. package/dist/assets/el-progress-1hLO5hs0.js +0 -2
  251. package/dist/assets/el-progress-1hLO5hs0.js.map +0 -1
  252. package/dist/assets/el-progress-legacy-QmxDezwR.js +0 -2
  253. package/dist/assets/el-progress-legacy-QmxDezwR.js.map +0 -1
  254. package/dist/assets/el-progress-njCW9-w4.css +0 -1
  255. package/dist/assets/el-select-BSO0hXRI.css +0 -1
  256. package/dist/assets/el-select-CVjQdC39.js +0 -2
  257. package/dist/assets/el-select-CVjQdC39.js.map +0 -1
  258. package/dist/assets/el-select-legacy-DSGgSQYX.js +0 -2
  259. package/dist/assets/el-select-legacy-DSGgSQYX.js.map +0 -1
  260. package/dist/assets/el-switch-B76QvbJN.js +0 -2
  261. package/dist/assets/el-switch-B76QvbJN.js.map +0 -1
  262. package/dist/assets/el-switch-legacy-CHkEgavQ.js +0 -2
  263. package/dist/assets/el-switch-legacy-CHkEgavQ.js.map +0 -1
  264. package/dist/assets/el-tab-pane-BhVByOfe.js +0 -2
  265. package/dist/assets/el-tab-pane-BhVByOfe.js.map +0 -1
  266. package/dist/assets/el-tab-pane-legacy-DMdhUCHY.js.map +0 -1
  267. package/dist/assets/el-table-column-legacy-N_oU_-0P.js +0 -24
  268. package/dist/assets/el-table-column-legacy-N_oU_-0P.js.map +0 -1
  269. package/dist/assets/el-table-column-tkbtgrcD.js.map +0 -1
  270. package/dist/assets/index-3yen43So.js +0 -2
  271. package/dist/assets/index-3yen43So.js.map +0 -1
  272. package/dist/assets/index-5sS3uHi0.css +0 -1
  273. package/dist/assets/index-9zuSLjpa.js +0 -2
  274. package/dist/assets/index-9zuSLjpa.js.map +0 -1
  275. package/dist/assets/index-B-6zRvEX.js +0 -2
  276. package/dist/assets/index-B-6zRvEX.js.map +0 -1
  277. package/dist/assets/index-B5tZv3FB.css +0 -1
  278. package/dist/assets/index-BN1f1UM3.js +0 -2
  279. package/dist/assets/index-BN1f1UM3.js.map +0 -1
  280. package/dist/assets/index-BUmkgniE.js +0 -2
  281. package/dist/assets/index-BUmkgniE.js.map +0 -1
  282. package/dist/assets/index-BbfnoqK6.js +0 -2
  283. package/dist/assets/index-BbfnoqK6.js.map +0 -1
  284. package/dist/assets/index-BghihfR3.css +0 -1
  285. package/dist/assets/index-C3IckGNL.js +0 -2
  286. package/dist/assets/index-C3IckGNL.js.map +0 -1
  287. package/dist/assets/index-CYAf_OTx.js +0 -40
  288. package/dist/assets/index-CYAf_OTx.js.map +0 -1
  289. package/dist/assets/index-Cb6-p2hG.js +0 -2
  290. package/dist/assets/index-Cb6-p2hG.js.map +0 -1
  291. package/dist/assets/index-CbkKWoQA.css +0 -1
  292. package/dist/assets/index-CeWnhlkq.css +0 -1
  293. package/dist/assets/index-Cfg2jkVw.css +0 -1
  294. package/dist/assets/index-CkMvb3wF.css +0 -1
  295. package/dist/assets/index-Cl4G6EQO.js +0 -2
  296. package/dist/assets/index-Cl4G6EQO.js.map +0 -1
  297. package/dist/assets/index-CnbFxlpi.css +0 -1
  298. package/dist/assets/index-Cyb1OjRN.js +0 -2
  299. package/dist/assets/index-Cyb1OjRN.js.map +0 -1
  300. package/dist/assets/index-D2p3cWtM.css +0 -1
  301. package/dist/assets/index-D7aZxhM6.js +0 -2
  302. package/dist/assets/index-D7aZxhM6.js.map +0 -1
  303. package/dist/assets/index-DI41wbky.js +0 -2
  304. package/dist/assets/index-DI41wbky.js.map +0 -1
  305. package/dist/assets/index-DaSb9EV4.css +0 -1
  306. package/dist/assets/index-DcOjlpKI.js +0 -2
  307. package/dist/assets/index-DcOjlpKI.js.map +0 -1
  308. package/dist/assets/index-DjO-nUIS.js +0 -2
  309. package/dist/assets/index-DjO-nUIS.js.map +0 -1
  310. package/dist/assets/index-DnxF29eG.css +0 -1
  311. package/dist/assets/index-DrKX0cCg.js +0 -2
  312. package/dist/assets/index-DrKX0cCg.js.map +0 -1
  313. package/dist/assets/index-F3S0vKOW.js +0 -2
  314. package/dist/assets/index-F3S0vKOW.js.map +0 -1
  315. package/dist/assets/index-I78Ur1Md.js +0 -2
  316. package/dist/assets/index-I78Ur1Md.js.map +0 -1
  317. package/dist/assets/index-L0LtrfyP.js +0 -2
  318. package/dist/assets/index-L0LtrfyP.js.map +0 -1
  319. package/dist/assets/index-XNFQHmLL.css +0 -1
  320. package/dist/assets/index-dEAnfrhp.css +0 -1
  321. package/dist/assets/index-hhTdfxnD.css +0 -1
  322. package/dist/assets/index-lTmxAqnX.js +0 -2
  323. package/dist/assets/index-lTmxAqnX.js.map +0 -1
  324. package/dist/assets/index-legacy-BJNK4MqF.js +0 -2
  325. package/dist/assets/index-legacy-BJNK4MqF.js.map +0 -1
  326. package/dist/assets/index-legacy-BLlk8iq-.js +0 -42
  327. package/dist/assets/index-legacy-BLlk8iq-.js.map +0 -1
  328. package/dist/assets/index-legacy-BmWYm3m_.js +0 -2
  329. package/dist/assets/index-legacy-BmWYm3m_.js.map +0 -1
  330. package/dist/assets/index-legacy-Bnp7569A.js +0 -2
  331. package/dist/assets/index-legacy-Bnp7569A.js.map +0 -1
  332. package/dist/assets/index-legacy-CQ24Si-w.js +0 -2
  333. package/dist/assets/index-legacy-CQ24Si-w.js.map +0 -1
  334. package/dist/assets/index-legacy-CT1nF7s9.js +0 -2
  335. package/dist/assets/index-legacy-CT1nF7s9.js.map +0 -1
  336. package/dist/assets/index-legacy-CeVzo60P.js +0 -2
  337. package/dist/assets/index-legacy-CeVzo60P.js.map +0 -1
  338. package/dist/assets/index-legacy-Cf0w_PNA.js +0 -2
  339. package/dist/assets/index-legacy-Cf0w_PNA.js.map +0 -1
  340. package/dist/assets/index-legacy-DZSQUiaj.js +0 -2
  341. package/dist/assets/index-legacy-DZSQUiaj.js.map +0 -1
  342. package/dist/assets/index-legacy-D_K0eXFb.js +0 -2
  343. package/dist/assets/index-legacy-D_K0eXFb.js.map +0 -1
  344. package/dist/assets/index-legacy-Da3YyHW_.js +0 -2
  345. package/dist/assets/index-legacy-Da3YyHW_.js.map +0 -1
  346. package/dist/assets/index-legacy-Da4s_D85.js +0 -2
  347. package/dist/assets/index-legacy-Da4s_D85.js.map +0 -1
  348. package/dist/assets/index-legacy-DhNaKknk.js +0 -2
  349. package/dist/assets/index-legacy-DhNaKknk.js.map +0 -1
  350. package/dist/assets/index-legacy-Dm1CXog1.js +0 -2
  351. package/dist/assets/index-legacy-Dm1CXog1.js.map +0 -1
  352. package/dist/assets/index-legacy-DpNNn-Dy.js +0 -2
  353. package/dist/assets/index-legacy-DpNNn-Dy.js.map +0 -1
  354. package/dist/assets/index-legacy-PkF4cKK9.js +0 -2
  355. package/dist/assets/index-legacy-PkF4cKK9.js.map +0 -1
  356. package/dist/assets/index-legacy-QHDmYAB8.js +0 -2
  357. package/dist/assets/index-legacy-QHDmYAB8.js.map +0 -1
  358. package/dist/assets/index-legacy-_M1-0586.js +0 -2
  359. package/dist/assets/index-legacy-_M1-0586.js.map +0 -1
  360. package/dist/assets/index-legacy-m0dvnwGi.js +0 -2
  361. package/dist/assets/index-legacy-m0dvnwGi.js.map +0 -1
  362. package/dist/assets/index-legacy-vRS79jKS.js +0 -2
  363. package/dist/assets/index-legacy-vRS79jKS.js.map +0 -1
  364. package/dist/assets/index-ypHH_Z_A.css +0 -1
  365. package/dist/assets/isEqual-BHpVKj_X.js +0 -2
  366. package/dist/assets/isEqual-BHpVKj_X.js.map +0 -1
  367. package/dist/assets/isEqual-legacy-BWUPR8bV.js +0 -2
  368. package/dist/assets/isEqual-legacy-BWUPR8bV.js.map +0 -1
  369. package/dist/assets/other-legacy-DjiCmSH4.js +0 -2
  370. package/dist/assets/other-legacy-DjiCmSH4.js.map +0 -1
  371. package/dist/assets/other-yMAyytYx.js +0 -2
  372. package/dist/assets/other-yMAyytYx.js.map +0 -1
  373. package/dist/assets/polyfills-legacy-CPmsgIAF.js +0 -4
  374. package/dist/assets/refresh-DPuuDO9h.js.map +0 -1
  375. package/dist/assets/refresh-legacy-DOts-8Wc.js.map +0 -1
  376. package/dist/assets/tip-CH7nBVXc.js +0 -2
  377. package/dist/assets/tip-CH7nBVXc.js.map +0 -1
  378. package/dist/assets/tip-legacy-DiCk_qP1.js +0 -2
  379. package/dist/assets/tip-legacy-DiCk_qP1.js.map +0 -1
  380. package/dist/assets/validator-BMr-jeUB.js +0 -2
  381. package/dist/assets/validator-BMr-jeUB.js.map +0 -1
  382. package/dist/assets/validator-legacy-CacjPWoF.js +0 -2
  383. package/dist/assets/validator-legacy-CacjPWoF.js.map +0 -1
  384. /package/dist/assets/{el-date-picker-NjWHL2Br.css → el-date-picker-C36c2CGO.css} +0 -0
  385. /package/dist/assets/{el-dropdown-item-CUgTpiu6.css → el-dropdown-item-5b6bMUQF.css} +0 -0
  386. /package/dist/assets/{el-loading-Uv12lkco.css → el-loading-BPl8mdQ3.css} +0 -0
  387. /package/dist/assets/{el-pagination-MvCAleW2.css → el-pagination-DMHBWKFj.css} +0 -0
  388. /package/dist/assets/{el-switch-D6dVIPlw.css → el-switch-CH9HekZJ.css} +0 -0
  389. /package/dist/assets/{el-tab-pane-kUw7IczA.css → el-tab-pane-CO1C5qCV.css} +0 -0
  390. /package/dist/assets/{el-table-column-DMXHP8sd.css → el-table-column-x3grTP_N.css} +0 -0
  391. /package/dist/assets/{tip-ovQu2XSt.css → tip-rRSL6nZ2.css} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tipInfo-D75KJpWg.js","sources":["../../../../node_modules/.pnpm/@element-plus+icons-vue@1.1.4_vue@3.5.12_typescript@4.9.5_/node_modules/@element-plus/icons-vue/dist/es/plus.mjs","../../src/pages/dashboard/tasks/public.ts","../../src/pages/dashboard/tasks/components/infoPanel/ddl.vue","../../src/pages/dashboard/tasks/components/infoPanel/file.vue","../../src/pages/dashboard/tasks/components/infoPanel/info.vue","../../src/pages/dashboard/tasks/components/infoPanel/people.vue","../../src/pages/dashboard/tasks/components/infoPanel/template.vue","../../src/pages/dashboard/tasks/components/infoPanel/tipInfo.vue"],"sourcesContent":["import { defineComponent, openBlock, createElementBlock, createElementVNode } from 'vue';\nimport _export_sfc from './_virtual/plugin-vue_export-helper.mjs';\n\nconst _sfc_main = defineComponent({\n name: \"Plus\"\n});\nconst _hoisted_1 = {\n viewBox: \"0 0 1024 1024\",\n xmlns: \"http://www.w3.org/2000/svg\"\n};\nconst _hoisted_2 = /* @__PURE__ */ createElementVNode(\"path\", {\n fill: \"currentColor\",\n d: \"M480 480V128a32 32 0 0 1 64 0v352h352a32 32 0 1 1 0 64H544v352a32 32 0 1 1-64 0V544H128a32 32 0 0 1 0-64h352z\"\n}, null, -1);\nconst _hoisted_3 = [\n _hoisted_2\n];\nfunction _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {\n return openBlock(), createElementBlock(\"svg\", _hoisted_1, _hoisted_3);\n}\nvar plus = /* @__PURE__ */ _export_sfc(_sfc_main, [[\"render\", _sfc_render]]);\n\nexport { plus as default };\n","import { ElMessage } from 'element-plus'\nimport { TaskApi } from '@/apis'\nimport { debounce } from '@/utils/other'\n\nexport const updateTaskInfo: (\n key: string,\n options: TaskApiTypes.TaskInfo,\n successInfo?: boolean,\n) => void = debounce(\n (key, options, successInfo = true) => {\n if (key) {\n TaskApi.updateTaskMoreInfo(key, options)\n .then(() => {\n if (successInfo) {\n ElMessage.success({\n message: '设置成功',\n zIndex: 4000,\n duration: 1000,\n })\n }\n })\n .catch(() => {\n ElMessage.error({\n message: '设置失败',\n zIndex: 4000,\n })\n })\n }\n },\n 1000,\n true,\n)\n","<script lang=\"ts\" setup>\nimport { computed, onMounted, ref, watchEffect } from 'vue'\nimport { formatDate } from '@/utils/stringUtil'\nimport { updateTaskInfo } from '../../public'\nimport Tip from './tip.vue'\n\nconst props = defineProps({\n ddl: {\n type: String,\n default: '',\n required: false,\n },\n k: {\n type: String,\n default: '',\n },\n})\n\nconst newDate = ref()\nwatchEffect(() => {\n if (props.ddl) {\n newDate.value = new Date(props.ddl)\n }\n else {\n newDate.value = null\n }\n})\n// 更新DDL\nfunction updateDDL() {\n if (newDate.value) {\n const ddl = formatDate(\n new Date(newDate.value.getTime() - 1000 * 60 * 60 * 8),\n )\n updateTaskInfo(props.k, { ddl })\n }\n}\n// 关闭DDL\nfunction closeDDL() {\n newDate.value = null\n updateTaskInfo(props.k, { ddl: null })\n}\n\nconst waitTime = ref(0)\nconst isOver = computed(() => waitTime.value <= 0)\nconst waitTimeStr = computed(() => {\n let seconds = ~~(waitTime.value / 1000)\n let hour = ~~(seconds / (60 * 60))\n const day = ~~(hour / 24)\n hour %= 24\n const minute = ~~((seconds % 3600) / 60)\n seconds %= 60\n return `剩余${day}天${hour}时${minute}分${seconds}秒`\n})\n\nfunction refreshWaitTime(loop = true) {\n if (newDate.value) {\n waitTime.value = newDate.value.getTime() - Date.now()\n }\n else {\n waitTime.value = 0\n }\n if (loop) {\n setTimeout(() => {\n refreshWaitTime()\n }, 1000)\n }\n}\n\nonMounted(() => {\n refreshWaitTime()\n})\n</script>\n\n<template>\n <div class=\"config-panel ddl-panel\">\n <div class=\"panel-tip\">\n <div>\n <h4>提交截止时间</h4>\n <p>设置后,超过截止时间用户将不能继续提交文件。</p>\n </div>\n <Tip\n :imgs=\"[\n 'https://img.cdn.sugarat.top/mdImg/MTY0OTE0OTI4NjU5Nw==649149286597',\n 'https://img.cdn.sugarat.top/mdImg/MTY0OTE0OTMxMDEyOQ==649149310129',\n 'https://img.cdn.sugarat.top/mdImg/MTY0OTE0OTM3MzgxOA==649149373818',\n ]\"\n >\n 查看示例\n </Tip>\n </div>\n\n <div class=\"setting-card\">\n <div class=\"setting-main\">\n <div>\n <h5>截止日期</h5>\n <p>选择具体日期和时间后会自动保存。</p>\n </div>\n <el-date-picker\n v-model=\"newDate\"\n :editable=\"false\"\n type=\"datetime\"\n placeholder=\"点击设置新截止日期\"\n :default-time=\"new Date(ddl)\"\n @change=\"updateDDL\"\n />\n </div>\n <div class=\"setting-footer\">\n <el-tag v-if=\"newDate\" :type=\"isOver ? 'danger' : 'success'\" effect=\"light\">\n {{ isOver ? '已经截止' : waitTimeStr }}\n </el-tag>\n <span v-else class=\"muted\">暂未设置截止时间</span>\n <el-button v-if=\"newDate\" type=\"danger\" plain @click=\"closeDDL\">\n 取消截止时间\n </el-button>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.panel-tip,\n.setting-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.panel-tip {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n background: #f8fbff;\n\n h4 {\n margin: 0;\n font-size: 16px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.setting-main,\n.setting-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.setting-main {\n h5 {\n margin: 0;\n font-size: 15px;\n color: #303133;\n }\n\n p {\n margin: 6px 0 0;\n font-size: 13px;\n color: #909399;\n }\n}\n\n.setting-footer {\n margin-top: 18px;\n padding-top: 16px;\n border-top: 1px solid #edf2f7;\n}\n\n.muted {\n color: #909399;\n}\n\n@media screen and (max-width: 700px) {\n .panel-tip,\n .setting-main,\n .setting-footer {\n align-items: stretch;\n flex-direction: column;\n }\n\n .ddl-panel :deep(.el-date-editor) {\n width: 100%;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { ElMessage } from 'element-plus'\nimport { reactive, ref, watchEffect } from 'vue'\nimport {\n copyRes,\n formatSize,\n getDefaultFormat,\n parseFileFormat,\n} from '@/utils/stringUtil'\nimport { updateTaskInfo } from '../../public'\n\nconst props = defineProps({\n format: {\n type: String,\n default: '',\n required: false,\n },\n k: {\n type: String,\n default: '',\n },\n})\n\nconst formatData = reactive(getDefaultFormat())\nconst typeName = ref('')\nfunction updateInfo() {\n updateTaskInfo(props.k, {\n format: JSON.stringify(formatData),\n })\n}\nfunction handleChange(v: boolean) {\n formatData.status = !!v\n updateInfo()\n}\n\nfunction handleAddType() {\n const inputValue = typeName.value\n .split(',')\n // 转为小写\n .map(v => v.trim().toLowerCase())\n for (const v of inputValue) {\n if (formatData.format.includes(v)) {\n ElMessage.error(`${v} 已存在`)\n return\n }\n }\n\n formatData.format.push(...inputValue)\n updateInfo()\n\n typeName.value = ''\n}\nfunction handleDelType(idx) {\n formatData.format.splice(idx, 1)\n updateInfo()\n}\nfunction handleCopyType() {\n copyRes(formatData.format.join(','))\n}\n\nfunction handleChangeLimit(limit: number) {\n formatData.limit = limit\n updateInfo()\n}\n\nconst inputSize = ref(0)\nconst unitList = reactive(['B', 'KB', 'MB', 'GB'])\nfunction handleChangeUnit() {\n const idx = unitList.findIndex(v => v === formatData.sizeUnit)\n formatData.size = inputSize.value * 1024 ** idx\n updateInfo()\n}\nfunction handleLimitSize(limit: number) {\n inputSize.value = limit\n const idx = unitList.findIndex(v => v === formatData.sizeUnit)\n formatData.size = inputSize.value * 1024 ** idx\n updateInfo()\n}\n\nwatchEffect(() => {\n if (props.format !== null) {\n Object.assign(formatData, parseFileFormat(props.format))\n }\n})\n</script>\n\n<template>\n <div class=\"config-panel\">\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>文件类型限制</h4>\n <p>通过文件名后缀限制可提交的文件类型,不区分大小写。</p>\n </div>\n <el-switch\n active-text=\"限制\"\n inactive-text=\"不限\"\n :model-value=\"formatData.status\"\n style=\"--el-switch-on-color: #13ce66; --el-switch-off-color: #dcdfe6\"\n @change=\"v => handleChange(Boolean(v))\"\n />\n </div>\n <div v-show=\"formatData.status\" class=\"type-editor\">\n <el-input v-model=\"typeName\" placeholder=\"例如:txt,png,jpeg,webp\">\n <template #append>\n <el-button @click=\"handleAddType\">\n 添加\n </el-button>\n </template>\n </el-input>\n <div class=\"tag-list\">\n <el-tag\n v-for=\"(tag, idx) in formatData.format\"\n :key=\"idx\"\n class=\"type\"\n closable\n :disable-transitions=\"false\"\n @close=\"handleDelType(idx)\"\n >\n {{ tag }}\n </el-tag>\n <span v-if=\"!formatData.format.length\" class=\"empty-text\">暂未添加文件类型</span>\n </div>\n <el-button\n v-show=\"formatData.format.length\"\n type=\"primary\"\n text\n size=\"small\"\n @click=\"handleCopyType\"\n >\n 复制类型列表\n </el-button>\n </div>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>提交数量</h4>\n <p>限制单次最多可以上传的文件数量,范围 1-16。</p>\n </div>\n <el-input-number\n :model-value=\"formatData.limit\"\n :min=\"1\"\n :max=\"16\"\n @change=\"handleChangeLimit\"\n />\n </div>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>文件大小</h4>\n <p>设置单个文件大小上限,填 0 表示不限制。</p>\n </div>\n <div class=\"size-editor\">\n <el-input-number\n :model-value=\"inputSize\"\n :min=\"0\"\n :max=\"1024\"\n @change=\"handleLimitSize\"\n />\n <el-select\n v-model=\"formatData.sizeUnit\"\n placeholder=\"单位\"\n @change=\"handleChangeUnit\"\n >\n <el-option v-for=\"v in unitList\" :key=\"v\" :label=\"v\" :value=\"v\" />\n </el-select>\n </div>\n </div>\n <div class=\"result-tip\" :class=\"{ danger: formatData.size !== 0 }\">\n {{\n formatData.size === 0\n ? '当前不限制文件大小'\n : `当前限制为不超过 ${formatSize(formatData.size)}`\n }}\n </div>\n </section>\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.setting-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.setting-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n\n h4 {\n margin: 0;\n font-size: 16px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.type-editor {\n display: grid;\n gap: 12px;\n max-width: 520px;\n margin-top: 18px;\n}\n\n.tag-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.type {\n margin: 0;\n}\n\n.empty-text {\n font-size: 13px;\n color: #c0c4cc;\n}\n\n.size-editor {\n display: flex;\n gap: 10px;\n\n .el-select {\n width: 100px;\n }\n}\n\n.result-tip {\n margin-top: 16px;\n padding: 10px 12px;\n color: #606266;\n background-color: #f5f7fa;\n border-radius: 10px;\n\n &.danger {\n color: #f56c6c;\n background-color: #fef0f0;\n }\n}\n\n@media screen and (max-width: 700px) {\n .setting-header,\n .size-editor {\n align-items: stretch;\n flex-direction: column;\n }\n\n .size-editor .el-select {\n width: 100%;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { ElMessage, ElMessageBox } from 'element-plus'\nimport { computed, reactive, ref, watch, watchEffect } from 'vue'\nimport { TaskApi } from '@/apis'\nimport InfosForm from '@/components/InfosForm/index.vue'\nimport { useIsMobile, useSiteConfig } from '@/composables'\nimport {\n getDefaultFormat,\n parseFileFormat,\n parseInfo,\n} from '@/utils/stringUtil'\nimport { updateTaskInfo } from '../../public'\nimport Tip from './tip.vue'\n\nconst props = defineProps({\n rewrite: {\n type: Number,\n default: 0,\n },\n info: {\n typs: String,\n default: '[]',\n },\n k: {\n type: String,\n default: '',\n },\n format: {\n type: String,\n default: '',\n required: false,\n },\n})\nconst emit = defineEmits<{\n 'update:format': [value: string]\n 'update:info': [value: string]\n 'update:rewrite': [value: number]\n}>()\nconst formatData = reactive(getDefaultFormat())\nconst openPreview = ref(false)\nconst infoTypeList = reactive<{ label: string, value: InfoItemType }[]>([\n {\n label: '输入框',\n value: 'input',\n },\n {\n label: '固定内容',\n value: 'text',\n },\n {\n label: '单选框',\n value: 'radio',\n },\n {\n label: '下拉选择',\n value: 'select',\n },\n])\nconst selectType = ref<InfoItemType>('input')\n\nconst { value: siteConfig } = useSiteConfig()\nconst maxInputLength = computed(() => siteConfig.value.maxInputLength)\n\nconst autoRewrite = ref(false)\nconst infos = reactive<InfoItem[]>([])\nconst needSave = ref(false)\n\nconst showAddInfo = computed(() => infos.length < siteConfig.value.formLength && !openPreview.value)\n// 负责清空&更新\nwatch(\n () => props.info,\n () => {\n infos.splice(0, infos.length)\n selectType.value = 'input'\n openPreview.value = false\n infos.push(...parseInfo(props.info))\n needSave.value = false\n },\n {\n immediate: true,\n },\n)\n\n// 预计格式\nconst resFormat = computed(\n () => `${infos.map(v => v.text).join(formatData.splitChar)}.后缀`,\n)\nwatchEffect(() => {\n autoRewrite.value = !!props.rewrite\n})\nfunction handleChange(v: boolean) {\n const rewrite = +v\n emit('update:rewrite', rewrite)\n updateTaskInfo(props.k, {\n rewrite,\n })\n}\n\nfunction addInfo(infoList?: InfoItem[], type?: InfoItemType) {\n const list = infoList || infos\n const t = type || selectType.value\n const item: InfoItem = { text: `标题${list.length + 1}`, type: t, value: '' }\n if (t === 'radio' || t === 'select') {\n item.children = [{ text: '选项1' }, { text: '选项2' }]\n }\n list.push(item)\n needSave.value = true\n}\nfunction deleteInfo(idx: number, infoList?: InfoItem[], minLen = 1) {\n const list = infoList || infos\n if (list.length <= minLen) {\n return\n }\n list.splice(idx, 1)\n needSave.value = true\n}\nfunction judgeInfoForm(items: InfoItem[]) {\n return items.every(v => v.text.trim() && judgeInfoForm(v.children || []))\n}\nfunction saveInfo() {\n if (!judgeInfoForm(infos)) {\n ElMessage.error('请完整填写表单信息')\n setTimeout(() => {\n ElMessage.warning('不能有空项')\n }, 100)\n return\n }\n const nextInfo = JSON.stringify(\n infos.map((v) => {\n // 特殊处理固定值的内容\n if (v.type === 'text') {\n v.value = v.text\n }\n return v\n }),\n )\n emit('update:info', nextInfo)\n updateTaskInfo(props.k, { info: nextInfo })\n needSave.value = false\n}\n\nfunction markInfoChanged() {\n needSave.value = true\n}\n\nfunction moveInfoUp(idx: number) {\n if (idx === 0)\n return\n const temp = infos[idx - 1]\n infos.splice(idx - 1, 1)\n infos.splice(idx, 0, temp)\n markInfoChanged()\n}\n\nfunction handleChangeInfoType(item: InfoItem, type: string) {\n const nextType = type as InfoItemType\n item.type = nextType\n if (nextType === 'radio' || nextType === 'select') {\n item.children = item.children?.length\n ? item.children\n : [{ text: '选项1' }, { text: '选项2' }]\n }\n else {\n delete item.children\n }\n markInfoChanged()\n}\n\nconst importPanelInfo = reactive({ taskList: [], taskValue: '' })\nconst showImportPanel = ref(false)\nasync function openImportPanel() {\n const taskKey = props.k\n // 通过任务Key获取可用任务列表,与概况信息\n const { data } = await TaskApi.getUsefulTemplate(taskKey)\n importPanelInfo.taskList = data\n importPanelInfo.taskValue = data[0]?.taskKey || ''\n showImportPanel.value = true\n}\n\nfunction handleSaveImportInfo() {\n const usefulInfo = importPanelInfo.taskList.find(\n v => v.taskKey === importPanelInfo.taskValue,\n ).info\n infos.splice(0, infos.length)\n infos.push(...parseInfo(usefulInfo))\n showImportPanel.value = false\n needSave.value = true\n}\n\nconst isMobile = useIsMobile()\nconst importPanelFlexStyle = computed(() => (isMobile.value ? '0 0 auto' : 0.5))\n\nfunction showHelp() {\n ElMessageBox.alert(\n '<p>固定内容主要用于重命名中,固定的部分,如“活动名”,“班级名”</p><p>如要设置注意事项,请使用 <strong>批注</strong> 功能</p>',\n '注意事项',\n { dangerouslyUseHTMLString: true },\n )\n}\n\nfunction handleChangeSplitChar() {\n const format = JSON.stringify(formatData)\n emit('update:format', format)\n updateTaskInfo(props.k, { format })\n}\nconst splitCharList = reactive(['-', '+', '_'])\nwatchEffect(() => {\n if (props.format !== null) {\n Object.assign(formatData, parseFileFormat(props.format))\n }\n})\n</script>\n\n<template>\n <div class=\"config-panel\">\n <el-alert\n title=\"配置用户提交文件时需要填写的表单字段。开启自动重命名后,字段顺序会影响最终文件名。\"\n type=\"info\"\n show-icon\n :closable=\"false\"\n />\n\n <section class=\"feature-grid\">\n <div class=\"feature-card\" :class=\"{ active: autoRewrite }\">\n <div class=\"feature-copy\">\n <el-tag :type=\"autoRewrite ? 'success' : 'info'\" effect=\"light\">\n {{ autoRewrite ? '已开启' : '未开启' }}\n </el-tag>\n <h4>文件自动重命名</h4>\n <p>开启后会根据表单字段生成文件名,建议保存后先预览效果。</p>\n </div>\n <el-switch\n v-model=\"autoRewrite\"\n size=\"large\"\n active-text=\"开\"\n inactive-text=\"关\"\n @change=\"handleChange\"\n />\n <div v-if=\"autoRewrite\" class=\"format-preview\">\n <div class=\"format-preview-main\">\n <span>预期格式</span>\n <strong>{{ resFormat }}</strong>\n </div>\n <label class=\"split-char-field\">\n <span>分隔符</span>\n <el-select\n v-model=\"formatData.splitChar\"\n placeholder=\"分隔符\"\n size=\"small\"\n @change=\"handleChangeSplitChar\"\n >\n <el-option v-for=\"v in splitCharList\" :key=\"v\" :label=\"v\" :value=\"v\" />\n </el-select>\n </label>\n </div>\n </div>\n\n <div class=\"feature-card\" :class=\"{ active: openPreview }\">\n <div class=\"feature-copy\">\n <el-tag :type=\"openPreview ? 'primary' : 'info'\" effect=\"light\">\n {{ openPreview ? '预览中' : '编辑中' }}\n </el-tag>\n <h4>编辑 / 预览</h4>\n <p>编辑模式维护字段,预览模式查看用户侧填写效果。</p>\n </div>\n <el-radio-group\n v-model=\"openPreview\"\n class=\"mode-switch\"\n size=\"large\"\n >\n <el-radio-button :label=\"false\">\n 编辑\n </el-radio-button>\n <el-radio-button :label=\"true\">\n 预览\n </el-radio-button>\n </el-radio-group>\n </div>\n </section>\n\n <section class=\"builder-card\">\n <div class=\"builder-header\">\n <div>\n <h4>字段列表</h4>\n <p>按问卷题目方式维护字段:标题、类型、选项和排序都在题目卡片内完成。</p>\n </div>\n <el-button text type=\"primary\" @click=\"showHelp\">\n 字段说明\n </el-button>\n </div>\n\n <div class=\"form-wrapper\">\n <InfosForm v-if=\"openPreview\" :infos=\"infos\" :disabled=\"openPreview\" />\n <div v-else class=\"field-list\">\n <div v-for=\"(item, idx) in infos\" :key=\"idx\" class=\"field-card\">\n <div class=\"question-head\">\n <div class=\"question-title\">\n <span class=\"field-index\">Q{{ idx + 1 }}</span>\n <strong>{{ item.text || '未命名字段' }}</strong>\n </div>\n <el-select\n :model-value=\"item.type\"\n class=\"question-type\"\n @change=\"v => handleChangeInfoType(item, v)\"\n >\n <el-option\n v-for=\"type in infoTypeList\"\n :key=\"type.value\"\n :label=\"type.label\"\n :value=\"type.value\"\n />\n </el-select>\n </div>\n\n <div class=\"question-body\">\n <label class=\"field-label\">字段标题</label>\n <el-input\n v-model=\"item.text\"\n placeholder=\"请输入展示给用户的字段标题\"\n :maxlength=\"maxInputLength\"\n clearable\n show-word-limit\n @input=\"markInfoChanged\"\n />\n\n <div\n v-if=\"item.type === 'radio' || item.type === 'select'\"\n class=\"option-list\"\n >\n <div class=\"option-title\">\n <span>选项列表</span>\n <el-button\n size=\"small\"\n text\n type=\"primary\"\n @click=\"addInfo(item.children, item.type)\"\n >\n 添加选项\n </el-button>\n </div>\n <div\n v-for=\"(v, idx2) in item.children\"\n :key=\"idx2\"\n class=\"option-item\"\n >\n <span>{{ idx2 + 1 }}</span>\n <el-input\n v-model=\"v.text\"\n size=\"small\"\n placeholder=\"输入选项内容\"\n :maxlength=\"maxInputLength\"\n clearable\n show-word-limit\n @input=\"markInfoChanged\"\n />\n <el-button\n size=\"small\"\n text\n type=\"danger\"\n :disabled=\"item.children.length <= 2\"\n @click=\"deleteInfo(idx2, item.children, 2)\"\n >\n 删除\n </el-button>\n </div>\n </div>\n </div>\n\n <div class=\"field-actions\">\n <el-button\n v-if=\"idx > 0\"\n size=\"small\"\n text\n type=\"primary\"\n @click=\"moveInfoUp(idx)\"\n >\n 上移\n </el-button>\n <el-button\n size=\"small\"\n text\n type=\"danger\"\n :disabled=\"infos.length <= 1\"\n @click=\"deleteInfo(idx)\"\n >\n 删除\n </el-button>\n </div>\n </div>\n </div>\n </div>\n\n <el-alert\n v-if=\"!openPreview\"\n class=\"builder-alert\"\n title=\"单选框和下拉选择至少保留 2 个选项;固定内容会作为文件名的一部分,不建议用于普通提示。\"\n type=\"info\"\n show-icon\n :closable=\"false\"\n />\n\n <div class=\"builder-toolbar\">\n <div v-if=\"showAddInfo\" class=\"add-actions\">\n <el-select\n v-model=\"selectType\"\n size=\"default\"\n placeholder=\"选择字段类型\"\n >\n <el-option\n v-for=\"(v, idx) in infoTypeList\"\n :key=\"idx\"\n :label=\"v.label\"\n :value=\"v.value\"\n />\n </el-select>\n <el-button type=\"primary\" @click=\"addInfo()\">\n 添加字段\n </el-button>\n </div>\n <div class=\"save-actions\">\n <el-button type=\"warning\" plain @click=\"openImportPanel\">\n 从其它任务导入\n </el-button>\n <el-button type=\"success\" @click=\"saveInfo\">\n 保存表单\n </el-button>\n </div>\n </div>\n <el-alert\n v-if=\"needSave\"\n class=\"save-alert\"\n title=\"表单信息有变动,请记得保存\"\n type=\"warning\"\n show-icon\n :closable=\"false\"\n />\n </section>\n\n <div class=\"info-panel\">\n <el-dialog\n v-model=\"showImportPanel\"\n :fullscreen=\"isMobile\"\n title=\"表单信息导入\"\n >\n <el-form\n :model=\"importPanelInfo\"\n label-width=\"100px\"\n label-position=\"right\"\n >\n <el-form-item label=\"任务\">\n <el-select\n v-model=\"importPanelInfo.taskValue\"\n filterable\n placeholder=\"请选择\"\n no-data-text=\"无可用任务\"\n >\n <el-option\n v-for=\"t in importPanelInfo.taskList\"\n :key=\"t.taskKey\"\n :label=\"t.name\"\n :value=\"t.taskKey\"\n />\n </el-select>\n </el-form-item>\n <Tip>{{ importPanelInfo.taskValue ? '' : '无可用任务' }}</Tip>\n </el-form>\n <template #footer>\n <span class=\"dialog-footer\">\n <el-button @click=\"showImportPanel = false\">取 消</el-button>\n <el-button\n :disabled=\"!importPanelInfo.taskValue\"\n type=\"primary\"\n @click=\"handleSaveImportInfo\"\n >确 定\n </el-button>\n </span>\n </template>\n </el-dialog>\n </div>\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.feature-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 16px;\n}\n\n.feature-card,\n.builder-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.feature-card {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n flex-wrap: wrap;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease;\n\n &.active {\n border-color: #b3d8ff;\n box-shadow: 0 10px 24px rgba(64, 158, 255, 0.08);\n }\n}\n\n.feature-copy {\n min-width: 0;\n flex: 1;\n\n h4 {\n margin: 12px 0 0;\n font-size: 17px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.format-preview {\n display: grid;\n gap: 10px;\n flex: 0 0 100%;\n padding: 12px;\n background-color: #f8fbff;\n border-radius: 12px;\n}\n\n.format-preview-main,\n.split-char-field {\n display: flex;\n align-items: center;\n gap: 12px;\n\n span {\n flex: 0 0 auto;\n color: #909399;\n }\n}\n\n.format-preview-main {\n strong {\n flex: 1;\n min-width: 0;\n color: #409eff;\n word-break: break-all;\n }\n}\n\n.split-char-field {\n margin: 0;\n\n .el-select {\n width: 90px;\n }\n}\n\n.mode-switch {\n white-space: nowrap;\n}\n\n.info-panel :deep(.el-form-item__label) {\n flex: v-bind(importPanelFlexStyle);\n justify-content: flex-end;\n}\n\n.builder-card {\n padding: 0;\n overflow: hidden;\n}\n\n.builder-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n padding: 18px 20px;\n background: linear-gradient(180deg, #ffffff 0%, #fafcff 100%);\n border-bottom: 1px solid #edf2f7;\n\n h4 {\n margin: 0;\n font-size: 17px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.form-wrapper {\n padding: 18px 20px 0;\n}\n\n.field-list {\n display: grid;\n gap: 14px;\n}\n\n.field-card {\n overflow: hidden;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n box-shadow: 0 8px 20px rgba(31, 45, 61, 0.04);\n}\n\n.question-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 14px;\n padding: 14px 16px;\n background-color: #fafcff;\n border-bottom: 1px solid #edf2f7;\n}\n\n.question-title {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n\n strong {\n overflow: hidden;\n color: #303133;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n}\n\n.field-index {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 36px;\n height: 30px;\n padding: 0 10px;\n color: #409eff;\n font-weight: 600;\n background-color: #ecf5ff;\n border-radius: 999px;\n}\n\n.question-type {\n width: 140px;\n flex: 0 0 auto;\n}\n\n.question-body {\n display: grid;\n gap: 10px;\n padding: 16px;\n}\n\n.field-label,\n.option-title {\n font-size: 13px;\n font-weight: 600;\n color: #606266;\n}\n\n.option-list {\n display: grid;\n gap: 10px;\n margin-top: 8px;\n padding: 12px;\n background-color: #fafcff;\n border: 1px dashed #dcdfe6;\n border-radius: 12px;\n}\n\n.option-title,\n.option-item {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.option-title {\n justify-content: space-between;\n}\n\n.option-item > span {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n color: #909399;\n background-color: #fff;\n border-radius: 50%;\n}\n\n.field-actions,\n.builder-toolbar,\n.add-actions,\n.save-actions {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.field-actions {\n justify-content: flex-end;\n padding: 12px 16px;\n border-top: 1px solid #edf2f7;\n}\n\n.builder-alert {\n margin: 16px 20px 0;\n}\n\n.builder-toolbar {\n justify-content: space-between;\n flex-wrap: wrap;\n margin: 18px 20px 0;\n padding: 16px 0 18px;\n border-top: 1px solid #edf2f7;\n}\n\n.add-actions .el-select {\n width: 150px;\n}\n\n.save-alert {\n margin: 14px 20px 18px;\n}\n\n@media screen and (max-width: 700px) {\n .feature-grid {\n grid-template-columns: 1fr;\n }\n\n .feature-card,\n .builder-header,\n .question-head,\n .option-title,\n .option-item,\n .builder-toolbar,\n .add-actions,\n .save-actions {\n align-items: stretch;\n flex-direction: column;\n }\n\n .format-preview {\n flex: none;\n width: auto;\n }\n\n .format-preview-main,\n .split-char-field {\n align-items: stretch;\n flex-direction: column;\n gap: 6px;\n }\n\n .mode-switch {\n width: 100%;\n }\n\n .mode-switch :deep(.el-radio-button) {\n width: 50%;\n }\n\n .mode-switch :deep(.el-radio-button__inner) {\n width: 100%;\n }\n\n .question-type,\n .split-char-field .el-select {\n width: 100%;\n }\n\n .form-wrapper {\n padding: 14px 12px 0;\n }\n\n .builder-alert,\n .builder-toolbar,\n .save-alert {\n margin-right: 12px;\n margin-left: 12px;\n }\n\n .add-actions .el-select,\n .save-actions .el-button {\n width: 100%;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport type { UploadUserFile } from 'element-plus'\nimport { ElMessage, ElMessageBox } from 'element-plus'\nimport { computed, reactive, ref, watch, watchEffect } from 'vue'\nimport { PeopleApi, TaskApi } from '@/apis'\nimport { useIsMobile } from '@/composables'\nimport { tableToExcel, uploadFile } from '@/utils/networkUtil'\nimport { formatDate } from '@/utils/stringUtil'\nimport { updateTaskInfo } from '../../public'\nimport Tip from './tip.vue'\n\nconst props = defineProps({\n value: {\n type: Number,\n defalut: 0,\n },\n k: {\n type: String,\n default: '',\n },\n name: {\n type: String,\n default: '',\n },\n field: {\n type: String,\n default: '姓名',\n },\n})\n\nconst activeTab = ref('手动添加')\nconst userInputName = ref('')\nconst importStatus = ref(false)\n\nfunction handAddName() {\n if (!userInputName.value) {\n return\n }\n importStatus.value = true\n PeopleApi.addPeopleByUser(userInputName.value, props.k)\n .then(() => {\n ElMessage.success(`添加 ${userInputName.value} 成功`)\n })\n .catch(() => {\n ElMessage.error(`${userInputName.value} 已存在`)\n })\n .finally(() => {\n importStatus.value = false\n userInputName.value = ''\n })\n}\nconst checkMore = ref(false)\n\nconst people = ref(0)\nwatchEffect(() => {\n people.value = props.value as number\n})\n// 限制提交人员\nfunction updateLimitPeople(limit: boolean) {\n updateTaskInfo(props.k, {\n people: +limit,\n })\n people.value = +limit\n}\n\n// 查看提交情况\nconst showPeopleList = ref(false)\nconst peopleList: any = reactive([])\nconst selectSubmitStatus = ref('all')\nconst searchName = ref('')\nconst filterPeopleBySearchWord = computed(() => {\n if (!searchName.value) {\n return peopleList\n }\n return peopleList.filter(v => v.name.includes(searchName.value))\n})\nconst peopleSubmitData = computed(() => {\n if (selectSubmitStatus.value === 'all') {\n return filterPeopleBySearchWord.value\n }\n return filterPeopleBySearchWord.value.filter(\n p => p.status === selectSubmitStatus.value,\n )\n})\nconst isLoadingPeopleData = ref(false)\nfunction refreshSubmitData() {\n isLoadingPeopleData.value = true\n PeopleApi.getPeople(props.k, `${+checkMore.value}`).then((res) => {\n peopleList.splice(0, peopleList.length)\n peopleList.push(...res.data.people)\n peopleList.forEach((p) => {\n if (!p.status && p.count === 0) {\n p.lastDate = '暂无记录'\n }\n else {\n p.lastDate = formatDate(new Date(p.lastDate), 'yyyy-MM-dd hh:mm:ss')\n }\n })\n isLoadingPeopleData.value = false\n })\n}\nfunction handleCheckMore() {\n checkMore.value = !checkMore.value\n if (checkMore.value) {\n refreshSubmitData()\n }\n}\nfunction checkPeople() {\n showPeopleList.value = true\n // 默认不展示提交数量\n checkMore.value = false\n refreshSubmitData()\n}\nfunction handleDeletePeople(item: any) {\n ElMessageBox.confirm('确认删除此人员吗', '数据无价,请谨慎操作')\n .then(() => {\n PeopleApi.deletePeople(props.k, item.id).then(() => {\n ElMessage.success('删除成功')\n peopleList.splice(\n peopleList.findIndex(v => v.id === item.id),\n 1,\n )\n })\n })\n .catch(() => {\n ElMessage.info('取消删除')\n })\n}\n// 文件上传\nconst peopleFileList = ref<UploadUserFile[]>([])\nconst peopleUpload = ref()\n// 超出选择的文件个数\nfunction handleExceedFile() {\n ElMessage.error('只能选择一个文件,可删除后重新选择')\n}\n// 清空文件\nfunction clearFiles() {\n peopleFileList.value.splice(0, peopleFileList.value.length)\n peopleUpload.value.clearFiles()\n}\n// 开始上传\nfunction submitUploadPeople() {\n peopleFileList.value.forEach((file) => {\n uploadFile(\n file.raw,\n `${import.meta.env.VITE_APP_AXIOS_BASE_URL}public/upload`,\n {\n success: (e: any) => {\n const { name, type } = e.data\n PeopleApi.importPeople(props.k, name, type).then((res) => {\n const { success, fail } = res.data\n ElMessage.success(`导入完成:${success}成功,${fail.length}失败`)\n if (fail.length > 0) {\n setTimeout(() => {\n ElMessage.info('自动开始下载未成功导入名单')\n tableToExcel(\n ['未成功导入名单'],\n fail.map((v: string) => [v]),\n `${props.name}_导入失败名单_${formatDate(\n new Date(),\n 'yyyy年MM月dd日hh时mm分ss秒',\n )}.xlsx`,\n )\n }, 1000)\n }\n clearFiles()\n })\n },\n },\n )\n })\n}\n// 添加文件\nfunction handleChangeFile(file: any) {\n if (file.raw.type !== 'text/plain') {\n ElMessage.warning({\n message: '只支持txt文件',\n zIndex: 4000,\n })\n clearFiles()\n }\n}\nfunction handleExportExcel() {\n if (peopleSubmitData.value.length === 0) {\n ElMessage.warning('表格中没有可导出数据')\n return\n }\n const headers = [\n '姓名',\n '提交状态',\n '提交数量',\n '最后操作时间',\n ...(checkMore.value ? ['现存数量', '提交次数'] : []),\n ]\n const body = peopleSubmitData.value.map((v) => {\n const { name, status, lastDate, submitCount, fileCount, count } = v\n return [\n name,\n status ? '✔' : 'x',\n submitCount,\n status ? formatDate(new Date(lastDate)) : '',\n ...(checkMore.value ? [fileCount, count] : []),\n ]\n })\n tableToExcel(\n headers,\n body,\n `${props.name}_提交情况_${formatDate(\n new Date(),\n 'yyyy年MM月dd日hh时mm分ss秒',\n )}.xlsx`,\n )\n ElMessage.success('导出成功')\n}\n\nconst isMobile = useIsMobile()\nconst importPanelInfo = reactive({\n taskList: [],\n type: 'override',\n taskValue: '',\n})\nconst showImportPanel = ref(false)\nasync function openImportPanel() {\n const taskKey = props.k\n // 通过任务Key获取可用任务列表,与概况信息\n const { data } = await PeopleApi.getUsefulTemplate(taskKey)\n importPanelInfo.taskList = data\n importPanelInfo.taskValue = data[0]?.taskKey || ''\n showImportPanel.value = true\n}\nconst ImportTaskTipMsg = computed(() => {\n const { taskList, taskValue } = importPanelInfo\n const task = taskList.find(v => v.taskKey === taskValue)\n if (!task) {\n return '无可用任务'\n }\n return `${task.count} 条数据`\n})\nfunction handleSaveImportInfo() {\n PeopleApi.importPeopleFromTpl(\n props.k,\n importPanelInfo.taskValue,\n importPanelInfo.type,\n ).then((res) => {\n showImportPanel.value = false\n const { success, fail } = res.data\n ElMessage.success(`导入成功${success}条,失败${fail.length}条`)\n\n if (fail.length > 0) {\n setTimeout(() => {\n ElMessage.info('自动开始下载未成功导入名单')\n tableToExcel(\n ['未成功导入名单'],\n fail.map((v: string) => [v]),\n `${props.name}_导入失败名单_${formatDate(\n new Date(),\n 'yyyy年MM月dd日hh时mm分ss秒',\n )}.xlsx`,\n )\n }, 1000)\n }\n })\n}\n\nconst importPanelFlexStyle = computed(() => (isMobile.value ? '0 0 auto' : 0.5))\n\nconst bindField = ref('姓名')\nwatch(\n () => props.field,\n (v) => {\n bindField.value = v\n },\n {\n immediate: true,\n },\n)\nfunction handleSureBind() {\n // 空值校验\n if (!bindField.value.trim().length) {\n ElMessage.warning('绑定的表单项不能为空')\n return\n }\n\n // 提交保存\n TaskApi.updateTaskMoreInfo(props.k, {\n bindField: bindField.value,\n }).then(() => {\n ElMessage.success('保存成功')\n })\n}\n</script>\n\n<template>\n <div class=\"config-panel info-panel\">\n <section class=\"panel-tip\">\n <div>\n <h4>限制名单</h4>\n <p>开启后,只有名单中的成员才可以提交文件,可通过文件、其它任务或手动方式维护名单。</p>\n </div>\n <Tip\n :imgs=\"[\n 'https://img.cdn.sugarat.top/mdImg/MTY1MDE4MzEwOTEzOQ==650183109139',\n 'https://img.cdn.sugarat.top/mdImg/MTY1MTQ5NjY3MTUyMw==651496671523',\n ]\"\n >\n 查看示例\n </Tip>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>名单校验</h4>\n <p>{{ people ? '当前已开启名单限制。' : '当前未开启名单限制,所有用户都可以提交。' }}</p>\n </div>\n <div class=\"header-actions\">\n <el-switch\n :model-value=\"Boolean(people)\"\n active-text=\"开启\"\n inactive-text=\"关闭\"\n @change=\"v => updateLimitPeople(Boolean(v))\"\n />\n <el-button v-if=\"people\" type=\"primary\" plain @click=\"checkPeople\">\n 查看提交情况\n </el-button>\n </div>\n </div>\n </section>\n\n <template v-if=\"people\">\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>名单导入</h4>\n <p>推荐大量名单使用文件导入,少量人员可直接手动添加。</p>\n </div>\n </div>\n <el-radio-group v-model=\"activeTab\" class=\"import-tabs\">\n <el-radio-button label=\"文件导入\" />\n <el-radio-button label=\"任务导入\" />\n <el-radio-button label=\"手动添加\" />\n </el-radio-group>\n\n <div class=\"import-people-wrapper\">\n <div v-show=\"activeTab === '文件导入'\" class=\"import-card\">\n <el-upload\n ref=\"peopleUpload\"\n v-model:file-list=\"peopleFileList\"\n accept=\"text/plain\"\n action=\"\"\n class=\"upload-demo\"\n :on-change=\"handleChangeFile\"\n :on-exceed=\"handleExceedFile\"\n :on-remove=\"clearFiles\"\n :auto-upload=\"false\"\n :limit=\"1\"\n >\n <template #trigger>\n <el-button type=\"primary\" plain>\n 选择文件\n </el-button>\n </template>\n <el-button\n class=\"upload-action\"\n type=\"success\"\n :disabled=\"!peopleFileList.length\"\n @click=\"submitUploadPeople\"\n >\n 确定上传\n </el-button>\n <template #tip>\n <div class=\"el-upload__tip\">\n <Tip\n :imgs=\"[\n 'https://img.cdn.sugarat.top/mdImg/MTY1MDE4Mjk2NjUxMA==650182966510',\n ]\"\n >\n 只能上传 .txt 文本文件,每行一个名字\n </Tip>\n <Tip>如名字有特殊字符,建议去除</Tip>\n <Tip>上传文件导入的方式,为追加导入,不会覆盖已存在数据</Tip>\n </div>\n </template>\n </el-upload>\n </div>\n <div v-show=\"activeTab === '任务导入'\" class=\"import-card\">\n <p>从已有任务中导入限制名单,可选择覆盖或追加。</p>\n <el-button type=\"success\" @click=\"openImportPanel\">\n 选择任务\n </el-button>\n </div>\n <div v-show=\"activeTab === '手动添加'\" class=\"import-card\">\n <el-input\n v-model=\"userInputName\"\n :disabled=\"importStatus\"\n placeholder=\"请输入姓名\"\n >\n <template #append>\n <el-button @click=\"handAddName\">\n 添加\n </el-button>\n </template>\n </el-input>\n <p>会自动判重,不会重复添加。大量名单优先推荐使用文件导入。</p>\n </div>\n </div>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>绑定表单项</h4>\n <p>与必填信息中的字段同名时,可避免用户重复填写。</p>\n </div>\n </div>\n <el-form class=\"bind-form\" label-width=\"100px\">\n <el-form-item label=\"字段名称\">\n <el-input v-model=\"bindField\" size=\"small\" clearable>\n <template #append>\n <el-button @click=\"handleSureBind\">\n 确定\n </el-button>\n </template>\n </el-input>\n </el-form-item>\n </el-form>\n </section>\n </template>\n\n <el-dialog v-model=\"showPeopleList\" :fullscreen=\"isMobile\" title=\"提交情况\">\n <!-- 上部分的筛选菜单 -->\n <div class=\"nav\">\n <div class=\"item\">\n <el-button\n :disabled=\"peopleList.length === 0\"\n type=\"success\"\n size=\"default\"\n @click=\"handleExportExcel\"\n >\n 导出记录\n </el-button>\n </div>\n <div class=\"item\">\n <el-select\n v-model=\"selectSubmitStatus\"\n size=\"default\"\n placeholder=\"状态筛选\"\n >\n <el-option label=\"全部\" value=\"all\" />\n <el-option label=\"已提交\" :value=\"1\" />\n <el-option label=\"未提交\" :value=\"0\" />\n </el-select>\n </div>\n <div class=\"item\">\n <el-input\n v-model=\"searchName\"\n size=\"default\"\n placeholder=\"输入要查询的姓名\"\n />\n </div>\n <div class=\"item\">\n <el-button type=\"primary\" size=\"default\" @click=\"handleCheckMore\">\n {{ checkMore ? '隐藏' : '显示' }}详细提交情况\n </el-button>\n </div>\n </div>\n <!-- 概况信息 -->\n <div class=\"tc p10\">\n <span>共: {{ peopleSubmitData.length }} 条数据</span>,\n <span>已提交: {{ peopleSubmitData.filter((v) => v.status).length }}</span>,\n <span>未提交: {{ peopleSubmitData.filter((v) => !v.status).length }}</span>\n </div>\n <div class=\"tc p10\">\n <Tip>\"提交次数\" 用户实际的提交次数</Tip>\n <Tip>\"现存数量\" 还存在于服务器上的文件数 (不包含删除) --- 慢查询</Tip>\n <Tip>\"提交数量\" 用户实际提交的文件数 (不包含撤回) --- 慢查询</Tip>\n </div>\n <!-- 数据部分 -->\n <el-table\n v-loading=\"isLoadingPeopleData\"\n element-loading-text=\"Loading...\"\n stripe\n border\n :data=\"peopleSubmitData\"\n height=\"460px\"\n >\n <el-table-column label=\"序号\" width=\"60\">\n <template #default=\"scope\">\n <div style=\"text-align: center\">\n {{ scope.$index + 1 }}\n </div>\n </template>\n </el-table-column>\n <el-table-column property=\"name\" label=\"姓名\" />\n <el-table-column label=\"提交状态\" width=\"100\">\n <template #default=\"scope\">\n <span v-if=\"scope.row.status\" class=\"submit-ok\">已提交</span>\n <span v-else class=\"submit-fail\">未提交</span>\n </template>\n </el-table-column>\n <el-table-column\n property=\"count\"\n label=\"提交次数\"\n width=\"94\"\n />\n <el-table-column\n sortable\n property=\"lastDate\"\n label=\"最后操作时间\"\n width=\"120\"\n />\n <template v-if=\"checkMore\">\n <el-table-column\n property=\"fileCount\"\n label=\"现存数量\"\n width=\"94\"\n />\n <el-table-column\n sortable\n property=\"submitCount\"\n label=\"提交数量\"\n width=\"120\"\n />\n </template>\n <el-table-column label=\"操作\" width=\"100\">\n <template #default=\"scope\">\n <el-button\n type=\"primary\"\n text\n size=\"small\"\n @click=\"handleDeletePeople(scope.row)\"\n >\n 删除\n </el-button>\n </template>\n </el-table-column>\n </el-table>\n </el-dialog>\n <el-dialog\n v-model=\"showImportPanel\"\n :fullscreen=\"isMobile\"\n title=\"人员列表导入\"\n >\n <el-form\n :model=\"importPanelInfo\"\n label-width=\"100px\"\n label-position=\"right\"\n >\n <el-form-item label=\"任务\">\n <el-select\n v-model=\"importPanelInfo.taskValue\"\n filterable\n placeholder=\"请选择\"\n no-data-text=\"无可用任务\"\n >\n <el-option\n v-for=\"t in importPanelInfo.taskList\"\n :key=\"t.taskKey\"\n :label=\"t.name\"\n :value=\"t.taskKey\"\n />\n </el-select>\n </el-form-item>\n <Tip>{{ ImportTaskTipMsg }}</Tip>\n <el-form-item label=\"任务\">\n <el-radio-group v-model=\"importPanelInfo.type\">\n <el-radio label=\"override\">\n 覆盖导入\n </el-radio>\n <el-radio label=\"add\">\n 追加导入\n </el-radio>\n </el-radio-group>\n </el-form-item>\n <Tip>\n {{\n importPanelInfo.type === 'override'\n ? '“覆盖导入” 将会覆盖原来的数据'\n : '“追加导入” 将只会导入不存在数据'\n }}\n </Tip>\n </el-form>\n <template #footer>\n <span class=\"dialog-footer\">\n <el-button @click=\"showImportPanel = false\">取 消</el-button>\n <el-button\n :disabled=\"!importPanelInfo.taskValue\"\n type=\"primary\"\n @click=\"handleSaveImportInfo\"\n >确 定</el-button>\n </span>\n </template>\n </el-dialog>\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.panel-tip,\n.setting-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.panel-tip,\n.setting-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n\n h4 {\n margin: 0;\n font-size: 16px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.panel-tip {\n background-color: #f8fbff;\n}\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.import-tabs {\n margin-top: 16px;\n}\n\n.import-people-wrapper {\n margin-top: 16px;\n}\n\n.import-card {\n padding: 16px;\n background-color: #fafcff;\n border: 1px solid #edf2f7;\n border-radius: 12px;\n\n p {\n margin: 0 0 12px;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.upload-action {\n margin-left: 10px;\n}\n\n.bind-form {\n max-width: 420px;\n margin-top: 16px;\n}\n\n.submit-ok {\n color: #67c23a;\n}\n\n.submit-fail {\n color: #f56c6c;\n}\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n padding-bottom: 5px;\n}\n\n.nav .item {\n margin-left: 10px;\n margin-top: 5px;\n}\n\n.info-panel :deep(.el-form-item__label) {\n flex: v-bind(importPanelFlexStyle);\n}\n\n.info-panel :deep(.el-upload-list__item-name) {\n justify-content: flex-start;\n}\n\n@media screen and (max-width: 700px) {\n .panel-tip,\n .setting-header,\n .header-actions {\n align-items: stretch;\n flex-direction: column;\n }\n\n .import-tabs {\n width: 100%;\n overflow-x: auto;\n }\n\n .upload-action {\n display: block;\n width: 100%;\n margin: 10px 0 0;\n }\n}\n</style>\n","<script lang=\"ts\">\nimport type { UploadUserFile } from 'element-plus'\nimport { ElMessage } from 'element-plus'\nimport { defineComponent, ref, watchEffect } from 'vue'\nimport { FileApi } from '@/apis'\nimport { qiniuUpload } from '@/utils/networkUtil'\nimport { updateTaskInfo } from '../../public'\nimport Tip from './tip.vue'\n\nexport default defineComponent({\n name: 'TemplatePanel',\n components: { Tip },\n props: {\n value: {\n type: String,\n default: '',\n },\n k: {\n type: String,\n default: '',\n },\n },\n setup(props) {\n const template = ref()\n watchEffect(() => {\n if (props.value) {\n template.value = props.value\n }\n else {\n template.value = ''\n }\n })\n const percentage = ref(0)\n // 删除模板\n const deleteTemplate = () => {\n if (template.value) {\n // 移除文件,避免空间被长时间占用\n updateTaskInfo(props.k, { template: '' })\n template.value = ''\n percentage.value = 0\n }\n }\n // 文件上传\n const fileList = ref<UploadUserFile[]>([])\n const elUpload = ref()\n // 超出选择的文件个数\n const handleExceedFile = () => {\n ElMessage.error('只能选择一个文件,可删除后重新选择')\n }\n // 清空文件\n const clearFiles = () => {\n elUpload.value.clearFiles()\n }\n // 开始上传\n const submitUploadPeople = () => {\n fileList.value.forEach((file) => {\n if (!props.k) {\n return\n }\n const { name } = file\n const key = `easypicker2/${props.k}_template/${name}`\n if (file.status === 'ready') {\n file.status = 'uploading'\n // qiniu上传\n FileApi.getUploadToken().then((res) => {\n qiniuUpload(res.data.token, file.raw, key, {\n success() {\n ElMessage.success('上传成功')\n updateTaskInfo(props.k, { template: name })\n // 清理上传完成的\n clearFiles()\n template.value = name\n file.status = 'success'\n // hash,key\n // console.log(data)\n },\n process(per: number) {\n file.percentage = ~~per\n },\n })\n })\n }\n })\n }\n return {\n template,\n deleteTemplate,\n fileList,\n handleExceedFile,\n clearFiles,\n submitUploadPeople,\n elUpload,\n percentage,\n }\n },\n})\n</script>\n\n<template>\n <div class=\"config-panel info-panel\">\n <section class=\"panel-tip\">\n <div>\n <h4>模板文件</h4>\n <p>上传后,用户可以在提交页下载模板文件,再按模板要求填写或提交。</p>\n </div>\n <Tip\n :imgs=\"[\n 'https://img.cdn.sugarat.top/mdImg/MTY1MDE4MjY3MjUxNw==650182672517',\n ]\"\n >\n 查看示例\n </Tip>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>当前模板</h4>\n <p>{{ template ? '模板文件已生效,可在提交页下载。' : '尚未设置模板文件。' }}</p>\n </div>\n <el-button\n v-if=\"template\"\n :disabled=\"!template\"\n type=\"danger\"\n plain\n @click=\"deleteTemplate\"\n >\n 删除模板\n </el-button>\n </div>\n <div class=\"template-file\" :class=\"{ empty: !template }\">\n {{ template || '暂无模板文件' }}\n </div>\n </section>\n\n <section v-if=\"!template\" class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>上传模板</h4>\n <p>选择一个文件后点击“设为模板”,同一任务仅保留一个模板文件。</p>\n </div>\n </div>\n <el-upload\n ref=\"elUpload\"\n v-model:file-list=\"fileList\"\n action=\"\"\n class=\"upload-file\"\n :on-exceed=\"handleExceedFile\"\n :on-remove=\"clearFiles\"\n :auto-upload=\"false\"\n :limit=\"1\"\n >\n <template #trigger>\n <el-button type=\"primary\" plain>\n 选取文件\n </el-button>\n </template>\n <el-button\n class=\"upload-action\"\n type=\"success\"\n :disabled=\"!fileList.length\"\n @click=\"submitUploadPeople\"\n >\n 设为模板\n </el-button>\n <template #tip>\n <div class=\"el-upload__tip\">\n 选择模板文件,然后点击设为模板。\n </div>\n </template>\n </el-upload>\n </section>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.panel-tip,\n.setting-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.panel-tip,\n.setting-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n\n h4 {\n margin: 0;\n font-size: 16px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.panel-tip {\n background-color: #f8fbff;\n}\n\n.template-file {\n margin-top: 16px;\n padding: 12px 14px;\n color: #303133;\n background-color: #f5f7fa;\n border-radius: 10px;\n word-break: break-all;\n\n &.empty {\n color: #c0c4cc;\n }\n}\n\n.upload-file {\n margin-top: 16px;\n}\n\n.upload-action {\n margin-left: 10px;\n}\n\n.info-panel :deep(.el-upload-list__item-name) {\n justify-content: flex-start;\n}\n\n@media screen and (max-width: 700px) {\n .panel-tip,\n .setting-header {\n align-items: stretch;\n flex-direction: column;\n }\n\n .upload-action {\n display: block;\n width: 100%;\n margin: 10px 0 0;\n }\n}\n</style>\n","<!-- eslint-disable ts/ban-ts-comment -->\n<script lang=\"ts\" setup>\nimport type { UploadProps, UploadUserFile } from 'element-plus'\nimport { Plus } from '@element-plus/icons-vue'\nimport { ElMessage } from 'element-plus'\nimport { computed, reactive, ref, watch } from 'vue'\nimport { FileApi, PublicApi, TaskApi } from '@/apis'\nimport { qiniuUpload } from '@/utils/networkUtil'\nimport { getTipImageKey } from '@/utils/stringUtil'\nimport { updateTaskInfo } from '../../public'\nimport Tip from './tip.vue'\n\nconst props = defineProps({\n tip: {\n type: String,\n default: '',\n required: false,\n },\n k: {\n type: String,\n default: '',\n },\n})\nconst textValue = ref('')\n\nconst tipData = reactive<{\n text: string\n imgs: {\n uid: number\n name: string\n }[]\n}>({\n text: '',\n imgs: [],\n})\nconst MaxImgCount = ref(3)\nconst imageList = ref<UploadUserFile[]>([])\nconst previewList = computed(() => {\n // @ts-expect-error\n return imageList.value.map(v => v!.preview || v.url)\n})\nconst previewIdx = ref(0)\n\nwatch(\n () => props.tip,\n () => {\n // 初始化\n try {\n const parseData = JSON.parse(props.tip)\n tipData.imgs = parseData.imgs\n tipData.text = parseData.text || ''\n imageList.value = tipData.imgs.map((v) => {\n return {\n ...v,\n url: 'https://img.cdn.sugarat.top/mdImg/MTY3NzkxMDI1NTU1Nw==20140524124237518.gif',\n }\n })\n if (imageList.value.length) {\n // 异步填充url\n PublicApi.getTipImageUrl(\n props.k,\n imageList.value.map(v => ({\n uid: v.uid,\n name: v.name,\n })),\n ).then((v) => {\n v.data.forEach((url, idx) => {\n imageList.value[idx].url = url.cover\n Object.assign(imageList.value[idx], {\n preview: url.preview,\n })\n })\n })\n }\n }\n catch {\n tipData.text = props.tip || ''\n tipData.imgs = []\n imageList.value = []\n }\n\n // 外部变动\n if (tipData.text) {\n textValue.value = tipData.text\n }\n else {\n textValue.value = ''\n }\n },\n {\n immediate: true,\n },\n)\nconst needSave = computed(() => tipData.text !== textValue.value)\n\n// 更新批注信息\nfunction updateTip(notify = true) {\n if (tipData.text !== textValue.value) {\n tipData.text = textValue.value\n }\n updateTaskInfo(props.k, { tip: JSON.stringify(tipData) }, notify)\n}\n\nconst imageViewerVisible = ref(false)\nfunction handleChangeFile(file: UploadUserFile) {\n if (!props.k) {\n return\n }\n const { name, uid } = file\n const key = getTipImageKey(props.k, name, uid)\n if (file.status === 'ready') {\n file.status = 'success'\n // qiniu上传\n FileApi.getUploadToken().then((res) => {\n qiniuUpload(res.data.token, file.raw, key, {\n success() {\n tipData.imgs.push({\n uid,\n name,\n })\n updateTip()\n },\n })\n })\n }\n}\nconst handleRemove: UploadProps['onRemove'] = (file) => {\n const { uid, name } = file\n const idx = tipData.imgs.findIndex(v => v.uid === uid)\n tipData.imgs.splice(idx, 1)\n updateTip()\n TaskApi.delTipImage(props.k, uid, name)\n}\n\nfunction handlePictureCardPreview(file) {\n imageViewerVisible.value = true\n const idx = imageList.value.findIndex(v => v.uid === file.uid)\n previewIdx.value = idx\n}\n// 超出选择的文件个数\nfunction handleExceedFile() {\n ElMessage.error(`只能选择${MaxImgCount.value}个图片,可删除后重新选择`)\n}\n</script>\n\n<template>\n <div class=\"config-panel\">\n <section class=\"panel-tip\">\n <div>\n <h4>提交页批注</h4>\n <p>用于在提交页展示说明、注意事项和图片提示,保存后建议打开预览确认展示效果。</p>\n </div>\n <Tip\n :imgs=\"[\n 'https://img.cdn.sugarat.top/mdImg/MTY1MTQ5NjI2OTI0MQ==651496269241',\n ]\"\n >\n 查看示例\n </Tip>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>文字说明</h4>\n <p>建议控制换行和字数,避免在移动端展示过长。</p>\n </div>\n <el-tag v-if=\"needSave\" type=\"warning\" effect=\"light\">\n 待保存\n </el-tag>\n </div>\n <el-input\n v-model=\"textValue\"\n class=\"tip-textarea\"\n :rows=\"7\"\n clearable\n :max=\"500\"\n show-word-limit\n type=\"textarea\"\n placeholder=\"请输入要展示的批注信息\"\n />\n <div class=\"actions\">\n <el-button type=\"success\" @click=\"updateTip\">\n 保存批注\n </el-button>\n <el-button type=\"danger\" plain @click=\"textValue = ''\">\n 清空\n </el-button>\n </div>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>图片说明</h4>\n <p>最多上传 3 张图片,适合补充截图、流程图或填写示例。</p>\n </div>\n <el-tag type=\"info\" effect=\"plain\">\n {{ imageList.length }}/{{ MaxImgCount }}\n </el-tag>\n </div>\n <el-upload\n v-model:file-list=\"imageList\"\n class=\"image-upload\"\n accept=\"image/*\"\n :limit=\"MaxImgCount\"\n action=\"\"\n list-type=\"picture-card\"\n :on-change=\"handleChangeFile\"\n :on-exceed=\"handleExceedFile\"\n :on-preview=\"handlePictureCardPreview\"\n :on-remove=\"handleRemove\"\n :auto-upload=\"false\"\n >\n <el-icon><Plus /></el-icon>\n </el-upload>\n </section>\n <ElImageViewer\n v-if=\"imageViewerVisible\"\n hide-on-click-modal\n :initial-index=\"previewIdx\"\n :url-list=\"previewList\"\n teleported\n @close=\"imageViewerVisible = false\"\n />\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.panel-tip,\n.setting-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.panel-tip,\n.setting-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n\n h4 {\n margin: 0;\n font-size: 16px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.panel-tip {\n background-color: #f8fbff;\n}\n\n.tip-textarea,\n.image-upload {\n margin-top: 16px;\n}\n\n.actions {\n display: flex;\n gap: 10px;\n justify-content: flex-end;\n margin-top: 16px;\n}\n\n@media screen and (max-width: 700px) {\n .panel-tip,\n .setting-header,\n .actions {\n align-items: stretch;\n flex-direction: column;\n }\n}\n</style>\n"],"names":["_sfc_main","defineComponent","_hoisted_1","_hoisted_2","createElementVNode","_hoisted_3","_sfc_render","_ctx","_cache","$props","$setup","$data","$options","openBlock","createElementBlock","plus","_export_sfc","updateTaskInfo","debounce","key","options","successInfo","TaskApi","ElMessage","props","__props","newDate","ref","watchEffect","updateDDL","ddl","formatDate","closeDDL","waitTime","isOver","computed","waitTimeStr","seconds","hour","day","minute","refreshWaitTime","loop","onMounted","formatData","reactive","getDefaultFormat","typeName","updateInfo","handleChange","v","handleAddType","inputValue","handleDelType","idx","handleCopyType","copyRes","handleChangeLimit","limit","inputSize","unitList","handleChangeUnit","handleLimitSize","parseFileFormat","emit","__emit","openPreview","infoTypeList","selectType","siteConfig","useSiteConfig","maxInputLength","autoRewrite","infos","needSave","showAddInfo","watch","parseInfo","resFormat","rewrite","addInfo","infoList","type","list","t","item","deleteInfo","minLen","judgeInfoForm","items","saveInfo","nextInfo","markInfoChanged","moveInfoUp","temp","handleChangeInfoType","nextType","_a","importPanelInfo","showImportPanel","openImportPanel","taskKey","data","handleSaveImportInfo","usefulInfo","isMobile","useIsMobile","importPanelFlexStyle","showHelp","ElMessageBox","handleChangeSplitChar","format","splitCharList","activeTab","userInputName","importStatus","handAddName","PeopleApi","checkMore","people","updateLimitPeople","showPeopleList","peopleList","selectSubmitStatus","searchName","filterPeopleBySearchWord","peopleSubmitData","p","isLoadingPeopleData","refreshSubmitData","res","handleCheckMore","checkPeople","handleDeletePeople","peopleFileList","peopleUpload","handleExceedFile","clearFiles","submitUploadPeople","file","uploadFile","e","name","success","fail","tableToExcel","handleChangeFile","handleExportExcel","headers","body","status","lastDate","submitCount","fileCount","count","ImportTaskTipMsg","taskList","taskValue","task","bindField","handleSureBind","_sfc_main$1","Tip","template","percentage","deleteTemplate","fileList","elUpload","FileApi","qiniuUpload","per","_hoisted_4","_hoisted_5","_component_el_upload","__unplugin_components_1","_createElementVNode","_createVNode","_component_Tip","_withCtx","_createTextVNode","_toDisplayString","_openBlock","_component_el_button","_createCommentVNode","_createElementBlock","$event","textValue","tipData","MaxImgCount","imageList","previewList","previewIdx","parseData","PublicApi","url","updateTip","notify","imageViewerVisible","uid","getTipImageKey","handleRemove","handlePictureCardPreview"],"mappings":"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","x_google_ignoreList":[0]}
@@ -0,0 +1,2 @@
1
+ System.register(["./index-legacy-BsWj1xV2.js","./el-tag-legacy-DxOZcEw1.js","./el-date-picker-legacy-iQW0501V.js","./el-scrollbar-legacy-CLEobATW.js","./tip-legacy-D_0YSCxT.js","./el-select-legacy-Cvxrwg7z.js","./el-input-number-legacy-CaZROy3J.js","./el-switch-legacy-DCF_46l4.js","./index-legacy-DFUJlpQR.js","./index-legacy-BUrH0Ubh.js","./el-loading-legacy-BpxkUp1m.js","./el-table-column-legacy-D1aU2dQP.js","./el-upload-legacy-D8KH6HBU.js","./other-legacy-Bfm4KL87.js"],(function(e,a){"use strict";var l,t,i,d,n,o,r,s,c,u,p,f,v,m,g,b,x,h,y,k,_,w,V,z,C,j,U,T,M,I,$,E,D,L,S,O,q,N,Y,P,B,F,K,Q,J,A,H,G,Z,X,R,W,ee,ae,le,te,ie,de,ne,oe,re,se,ce,ue,pe,fe,ve,me;return{setters:[e=>{l=e.f,t=e.d,i=e.a,d=e.c,n=e.b,o=e.aY,r=e.E,s=e.r,c=e.a7,u=e.M,p=e.o,f=e.i,v=e.w,m=e.e,g=e.B,b=e.t,x=e.Q,h=e.n,y=e.s,k=e._,_=e.X,w=e.aZ,V=e.a8,z=e.a9,C=e.F,j=e.A,U=e.D,T=e.j,M=e.a5,I=e.ab,$=e.q,E=e.a_,D=e.a$,L=e.a6,S=e.Y,O=e.Z,q=e.ad,N=e.aU,Y=e.ag,P=e.ah,B=e.a0,F=e.b0,K=e.b1,Q=e.aj,J=e.ac,A=e.b2,H=e.h,G=e.b3,Z=e.G,X=e.P},e=>{R=e.E},e=>{W=e.E},null,e=>{ee=e.T,ae=e.a},e=>{le=e.a,te=e.E},e=>{ie=e.E},e=>{de=e.E},e=>{ne=e.I,oe=e.a,re=e.b,se=e.c},e=>{ce=e.E},e=>{ue=e.v},e=>{pe=e.E,fe=e.a},e=>{ve=e.E},e=>{me=e.d}],execute:function(){var a=document.createElement("style");a.textContent=".config-panel[data-v-d740ac9f]{display:grid;gap:16px}.panel-tip[data-v-d740ac9f],.setting-card[data-v-d740ac9f]{padding:18px;background-color:#fff;border:1px solid #edf2f7;border-radius:14px}.panel-tip[data-v-d740ac9f]{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;background:#f8fbff}.panel-tip h4[data-v-d740ac9f]{margin:0;font-size:16px;color:#1f2d3d}.panel-tip p[data-v-d740ac9f]{margin:8px 0 0;color:#909399;line-height:1.6}.setting-main[data-v-d740ac9f],.setting-footer[data-v-d740ac9f]{display:flex;align-items:center;justify-content:space-between;gap:16px}.setting-main h5[data-v-d740ac9f]{margin:0;font-size:15px;color:#303133}.setting-main p[data-v-d740ac9f]{margin:6px 0 0;font-size:13px;color:#909399}.setting-footer[data-v-d740ac9f]{margin-top:18px;padding-top:16px;border-top:1px solid #edf2f7}.muted[data-v-d740ac9f]{color:#909399}@media screen and (max-width: 700px){.panel-tip[data-v-d740ac9f],.setting-main[data-v-d740ac9f],.setting-footer[data-v-d740ac9f]{align-items:stretch;flex-direction:column}.ddl-panel[data-v-d740ac9f] .el-date-editor{width:100%}}.config-panel[data-v-d5f004e0]{display:grid;gap:16px}.setting-card[data-v-d5f004e0]{padding:18px;background-color:#fff;border:1px solid #edf2f7;border-radius:14px}.setting-header[data-v-d5f004e0]{display:flex;align-items:center;justify-content:space-between;gap:16px}.setting-header h4[data-v-d5f004e0]{margin:0;font-size:16px;color:#1f2d3d}.setting-header p[data-v-d5f004e0]{margin:8px 0 0;font-size:13px;color:#909399;line-height:1.6}.type-editor[data-v-d5f004e0]{display:grid;gap:12px;max-width:520px;margin-top:18px}.tag-list[data-v-d5f004e0]{display:flex;flex-wrap:wrap;gap:8px;min-height:32px}.type[data-v-d5f004e0]{margin:0}.empty-text[data-v-d5f004e0]{font-size:13px;color:#c0c4cc}.size-editor[data-v-d5f004e0]{display:flex;gap:10px}.size-editor .el-select[data-v-d5f004e0]{width:100px}.result-tip[data-v-d5f004e0]{margin-top:16px;padding:10px 12px;color:#606266;background-color:#f5f7fa;border-radius:10px}.result-tip.danger[data-v-d5f004e0]{color:#f56c6c;background-color:#fef0f0}@media screen and (max-width: 700px){.setting-header[data-v-d5f004e0],.size-editor[data-v-d5f004e0]{align-items:stretch;flex-direction:column}.size-editor .el-select[data-v-d5f004e0]{width:100%}}.el-radio-button{--el-radio-button-checked-bg-color:var(--el-color-primary);--el-radio-button-checked-text-color:var(--el-color-white);--el-radio-button-checked-border-color:var(--el-color-primary);--el-radio-button-disabled-checked-fill:var(--el-border-color-extra-light)}.el-radio-button{position:relative;display:inline-block;outline:0}.el-radio-button__inner{display:inline-block;line-height:1;white-space:nowrap;vertical-align:middle;background:var(--el-button-bg-color,var(--el-fill-color-blank));border:var(--el-border);font-weight:var(--el-button-font-weight,var(--el-font-weight-primary));border-left:0;color:var(--el-button-text-color,var(--el-text-color-regular));-webkit-appearance:none;text-align:center;box-sizing:border-box;outline:0;margin:0;position:relative;cursor:pointer;transition:var(--el-transition-all);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:8px 15px;font-size:var(--el-font-size-base);border-radius:0}.el-radio-button__inner.is-round{padding:8px 15px}.el-radio-button__inner:hover{color:var(--el-color-primary)}.el-radio-button__inner [class*=el-icon-]{line-height:.9}.el-radio-button__inner [class*=el-icon-]+span{margin-left:5px}.el-radio-button:first-child .el-radio-button__inner{border-left:var(--el-border);border-radius:var(--el-border-radius-base) 0 0 var(--el-border-radius-base);box-shadow:none!important}.el-radio-button__original-radio{opacity:0;outline:0;position:absolute;z-index:-1}.el-radio-button__original-radio:checked+.el-radio-button__inner{color:var(--el-radio-button-checked-text-color,var(--el-color-white));background-color:var(--el-radio-button-checked-bg-color,var(--el-color-primary));border-color:var(--el-radio-button-checked-border-color,var(--el-color-primary));box-shadow:-1px 0 0 0 var(--el-radio-button-checked-border-color,var(--el-color-primary))}.el-radio-button__original-radio:focus-visible+.el-radio-button__inner{border-left:var(--el-border);border-left-color:var(--el-radio-button-checked-border-color,var(--el-color-primary));outline:2px solid var(--el-radio-button-checked-border-color);outline-offset:1px;z-index:2;border-radius:var(--el-border-radius-base);box-shadow:none}.el-radio-button__original-radio:disabled+.el-radio-button__inner{color:var(--el-disabled-text-color);cursor:not-allowed;background-image:none;background-color:var(--el-button-disabled-bg-color,var(--el-fill-color-blank));border-color:var(--el-button-disabled-border-color,var(--el-border-color-light));box-shadow:none}.el-radio-button__original-radio:disabled:checked+.el-radio-button__inner{background-color:var(--el-radio-button-disabled-checked-fill)}.el-radio-button:last-child .el-radio-button__inner{border-radius:0 var(--el-border-radius-base) var(--el-border-radius-base) 0}.el-radio-button:first-child:last-child .el-radio-button__inner{border-radius:var(--el-border-radius-base)}.el-radio-button--large .el-radio-button__inner{padding:12px 19px;font-size:var(--el-font-size-base);border-radius:0}.el-radio-button--large .el-radio-button__inner.is-round{padding:12px 19px}.el-radio-button--small .el-radio-button__inner{padding:5px 11px;font-size:12px;border-radius:0}.el-radio-button--small .el-radio-button__inner.is-round{padding:5px 11px}.config-panel[data-v-ef3c8c92]{display:grid;gap:16px}.feature-grid[data-v-ef3c8c92]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}.feature-card[data-v-ef3c8c92],.builder-card[data-v-ef3c8c92]{padding:18px;background-color:#fff;border:1px solid #edf2f7;border-radius:14px}.feature-card[data-v-ef3c8c92]{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap;transition:border-color .2s ease,box-shadow .2s ease}.feature-card.active[data-v-ef3c8c92]{border-color:#b3d8ff;box-shadow:0 10px 24px rgba(64,158,255,.08)}.feature-copy[data-v-ef3c8c92]{min-width:0;flex:1}.feature-copy h4[data-v-ef3c8c92]{margin:12px 0 0;font-size:17px;color:#1f2d3d}.feature-copy p[data-v-ef3c8c92]{margin:8px 0 0;font-size:13px;color:#909399;line-height:1.6}.format-preview[data-v-ef3c8c92]{display:grid;gap:10px;flex:0 0 100%;padding:12px;background-color:#f8fbff;border-radius:12px}.format-preview-main[data-v-ef3c8c92],.split-char-field[data-v-ef3c8c92]{display:flex;align-items:center;gap:12px}.format-preview-main span[data-v-ef3c8c92],.split-char-field span[data-v-ef3c8c92]{flex:0 0 auto;color:#909399}.format-preview-main strong[data-v-ef3c8c92]{flex:1;min-width:0;color:#409eff;word-break:break-all}.split-char-field[data-v-ef3c8c92]{margin:0}.split-char-field .el-select[data-v-ef3c8c92]{width:90px}.mode-switch[data-v-ef3c8c92]{white-space:nowrap}.info-panel[data-v-ef3c8c92] .el-form-item__label{flex:var(--3e7131f8);justify-content:flex-end}.builder-card[data-v-ef3c8c92]{padding:0;overflow:hidden}.builder-header[data-v-ef3c8c92]{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:18px 20px;background:linear-gradient(180deg,#fff,#fafcff);border-bottom:1px solid #edf2f7}.builder-header h4[data-v-ef3c8c92]{margin:0;font-size:17px;color:#1f2d3d}.builder-header p[data-v-ef3c8c92]{margin:8px 0 0;font-size:13px;color:#909399;line-height:1.6}.form-wrapper[data-v-ef3c8c92]{padding:18px 20px 0}.field-list[data-v-ef3c8c92]{display:grid;gap:14px}.field-card[data-v-ef3c8c92]{overflow:hidden;background-color:#fff;border:1px solid #edf2f7;border-radius:14px;box-shadow:0 8px 20px rgba(31,45,61,.04)}.question-head[data-v-ef3c8c92]{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:14px 16px;background-color:#fafcff;border-bottom:1px solid #edf2f7}.question-title[data-v-ef3c8c92]{display:flex;align-items:center;gap:10px;min-width:0}.question-title strong[data-v-ef3c8c92]{overflow:hidden;color:#303133;text-overflow:ellipsis;white-space:nowrap}.field-index[data-v-ef3c8c92]{display:inline-flex;align-items:center;justify-content:center;min-width:36px;height:30px;padding:0 10px;color:#409eff;font-weight:600;background-color:#ecf5ff;border-radius:999px}.question-type[data-v-ef3c8c92]{width:140px;flex:0 0 auto}.question-body[data-v-ef3c8c92]{display:grid;gap:10px;padding:16px}.field-label[data-v-ef3c8c92],.option-title[data-v-ef3c8c92]{font-size:13px;font-weight:600;color:#606266}.option-list[data-v-ef3c8c92]{display:grid;gap:10px;margin-top:8px;padding:12px;background-color:#fafcff;border:1px dashed #dcdfe6;border-radius:12px}.option-title[data-v-ef3c8c92],.option-item[data-v-ef3c8c92]{display:flex;align-items:center;gap:10px}.option-title[data-v-ef3c8c92]{justify-content:space-between}.option-item>span[data-v-ef3c8c92]{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;color:#909399;background-color:#fff;border-radius:50%}.field-actions[data-v-ef3c8c92],.builder-toolbar[data-v-ef3c8c92],.add-actions[data-v-ef3c8c92],.save-actions[data-v-ef3c8c92]{display:flex;align-items:center;gap:10px}.field-actions[data-v-ef3c8c92]{justify-content:flex-end;padding:12px 16px;border-top:1px solid #edf2f7}.builder-alert[data-v-ef3c8c92]{margin:16px 20px 0}.builder-toolbar[data-v-ef3c8c92]{justify-content:space-between;flex-wrap:wrap;margin:18px 20px 0;padding:16px 0 18px;border-top:1px solid #edf2f7}.add-actions .el-select[data-v-ef3c8c92]{width:150px}.save-alert[data-v-ef3c8c92]{margin:14px 20px 18px}@media screen and (max-width: 700px){.feature-grid[data-v-ef3c8c92]{grid-template-columns:1fr}.feature-card[data-v-ef3c8c92],.builder-header[data-v-ef3c8c92],.question-head[data-v-ef3c8c92],.option-title[data-v-ef3c8c92],.option-item[data-v-ef3c8c92],.builder-toolbar[data-v-ef3c8c92],.add-actions[data-v-ef3c8c92],.save-actions[data-v-ef3c8c92]{align-items:stretch;flex-direction:column}.format-preview[data-v-ef3c8c92]{flex:none;width:auto}.format-preview-main[data-v-ef3c8c92],.split-char-field[data-v-ef3c8c92]{align-items:stretch;flex-direction:column;gap:6px}.mode-switch[data-v-ef3c8c92]{width:100%}.mode-switch[data-v-ef3c8c92] .el-radio-button{width:50%}.mode-switch[data-v-ef3c8c92] .el-radio-button__inner,.question-type[data-v-ef3c8c92],.split-char-field .el-select[data-v-ef3c8c92]{width:100%}.form-wrapper[data-v-ef3c8c92]{padding:14px 12px 0}.builder-alert[data-v-ef3c8c92],.builder-toolbar[data-v-ef3c8c92],.save-alert[data-v-ef3c8c92]{margin-right:12px;margin-left:12px}.add-actions .el-select[data-v-ef3c8c92],.save-actions .el-button[data-v-ef3c8c92]{width:100%}}.config-panel[data-v-5e872bda]{display:grid;gap:16px}.panel-tip[data-v-5e872bda],.setting-card[data-v-5e872bda]{padding:18px;background-color:#fff;border:1px solid #edf2f7;border-radius:14px}.panel-tip[data-v-5e872bda],.setting-header[data-v-5e872bda]{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}.panel-tip h4[data-v-5e872bda],.setting-header h4[data-v-5e872bda]{margin:0;font-size:16px;color:#1f2d3d}.panel-tip p[data-v-5e872bda],.setting-header p[data-v-5e872bda]{margin:8px 0 0;font-size:13px;color:#909399;line-height:1.6}.panel-tip[data-v-5e872bda]{background-color:#f8fbff}.header-actions[data-v-5e872bda]{display:flex;align-items:center;gap:12px}.import-tabs[data-v-5e872bda],.import-people-wrapper[data-v-5e872bda]{margin-top:16px}.import-card[data-v-5e872bda]{padding:16px;background-color:#fafcff;border:1px solid #edf2f7;border-radius:12px}.import-card p[data-v-5e872bda]{margin:0 0 12px;font-size:13px;color:#909399;line-height:1.6}.upload-action[data-v-5e872bda]{margin-left:10px}.bind-form[data-v-5e872bda]{max-width:420px;margin-top:16px}.submit-ok[data-v-5e872bda]{color:#67c23a}.submit-fail[data-v-5e872bda]{color:#f56c6c}.nav[data-v-5e872bda]{display:flex;flex-wrap:wrap;justify-content:center;padding-bottom:5px}.nav .item[data-v-5e872bda]{margin-left:10px;margin-top:5px}.info-panel[data-v-5e872bda] .el-form-item__label{flex:var(--f0f25e6a)}.info-panel[data-v-5e872bda] .el-upload-list__item-name{justify-content:flex-start}@media screen and (max-width: 700px){.panel-tip[data-v-5e872bda],.setting-header[data-v-5e872bda],.header-actions[data-v-5e872bda]{align-items:stretch;flex-direction:column}.import-tabs[data-v-5e872bda]{width:100%;overflow-x:auto}.upload-action[data-v-5e872bda]{display:block;width:100%;margin:10px 0 0}}.config-panel[data-v-07111923]{display:grid;gap:16px}.panel-tip[data-v-07111923],.setting-card[data-v-07111923]{padding:18px;background-color:#fff;border:1px solid #edf2f7;border-radius:14px}.panel-tip[data-v-07111923],.setting-header[data-v-07111923]{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}.panel-tip h4[data-v-07111923],.setting-header h4[data-v-07111923]{margin:0;font-size:16px;color:#1f2d3d}.panel-tip p[data-v-07111923],.setting-header p[data-v-07111923]{margin:8px 0 0;font-size:13px;color:#909399;line-height:1.6}.panel-tip[data-v-07111923]{background-color:#f8fbff}.template-file[data-v-07111923]{margin-top:16px;padding:12px 14px;color:#303133;background-color:#f5f7fa;border-radius:10px;word-break:break-all}.template-file.empty[data-v-07111923]{color:#c0c4cc}.upload-file[data-v-07111923]{margin-top:16px}.upload-action[data-v-07111923]{margin-left:10px}.info-panel[data-v-07111923] .el-upload-list__item-name{justify-content:flex-start}@media screen and (max-width: 700px){.panel-tip[data-v-07111923],.setting-header[data-v-07111923]{align-items:stretch;flex-direction:column}.upload-action[data-v-07111923]{display:block;width:100%;margin:10px 0 0}}.config-panel[data-v-1e9e399b]{display:grid;gap:16px}.panel-tip[data-v-1e9e399b],.setting-card[data-v-1e9e399b]{padding:18px;background-color:#fff;border:1px solid #edf2f7;border-radius:14px}.panel-tip[data-v-1e9e399b],.setting-header[data-v-1e9e399b]{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}.panel-tip h4[data-v-1e9e399b],.setting-header h4[data-v-1e9e399b]{margin:0;font-size:16px;color:#1f2d3d}.panel-tip p[data-v-1e9e399b],.setting-header p[data-v-1e9e399b]{margin:8px 0 0;font-size:13px;color:#909399;line-height:1.6}.panel-tip[data-v-1e9e399b]{background-color:#f8fbff}.tip-textarea[data-v-1e9e399b],.image-upload[data-v-1e9e399b]{margin-top:16px}.actions[data-v-1e9e399b]{display:flex;gap:10px;justify-content:flex-end;margin-top:16px}@media screen and (max-width: 700px){.panel-tip[data-v-1e9e399b],.setting-header[data-v-1e9e399b],.actions[data-v-1e9e399b]{align-items:stretch;flex-direction:column}}\n/*$vite$:1*/",document.head.appendChild(a);const ge=t({name:"Plus"}),be={viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg"},xe=[n("path",{fill:"currentColor",d:"M480 480V128a32 32 0 0 1 64 0v352h352a32 32 0 1 1 0 64H544v352a32 32 0 1 1-64 0V544H128a32 32 0 0 1 0-64h352z"},null,-1)];var he=l(ge,[["render",function(e,a,l,t,n,o){return i(),d("svg",be,xe)}]]);const ye=me(((e,a,l=!0)=>{e&&o.updateTaskMoreInfo(e,a).then((()=>{l&&r.success({message:"设置成功",zIndex:4e3,duration:1e3})})).catch((()=>{r.error({message:"设置失败",zIndex:4e3})}))}),1e3,!0),ke={class:"config-panel ddl-panel"},_e={class:"panel-tip"},we={class:"setting-card"},Ve={class:"setting-main"},ze={class:"setting-footer"},Ce={key:1,class:"muted"},je=(e("D",k(t({__name:"ddl",props:{ddl:{type:String,default:"",required:!1},k:{type:String,default:""}},setup(e){const a=e,l=s();function t(){if(l.value){const e=h(new Date(l.value.getTime()-288e5));ye(a.k,{ddl:e})}}function o(){l.value=null,ye(a.k,{ddl:null})}c((()=>{a.ddl?l.value=new Date(a.ddl):l.value=null}));const r=s(0),k=u((()=>r.value<=0)),_=u((()=>{let e=~~(r.value/1e3),a=~~(e/3600);const l=~~(a/24);a%=24;const t=~~(e%3600/60);return e%=60,`剩余${l}天${a}时${t}分${e}秒`}));function w(e=!0){l.value?r.value=l.value.getTime()-Date.now():r.value=0,e&&setTimeout((()=>{w()}),1e3)}return p((()=>{w()})),(a,r)=>{const s=W,c=R,u=y;return i(),d("div",ke,[n("div",_e,[r[2]||(r[2]=n("div",null,[n("h4",null,"提交截止时间"),n("p",null,"设置后,超过截止时间用户将不能继续提交文件。")],-1)),f(ee,{imgs:["https://img.cdn.sugarat.top/mdImg/MTY0OTE0OTI4NjU5Nw==649149286597","https://img.cdn.sugarat.top/mdImg/MTY0OTE0OTMxMDEyOQ==649149310129","https://img.cdn.sugarat.top/mdImg/MTY0OTE0OTM3MzgxOA==649149373818"]},{default:v((()=>r[1]||(r[1]=[m(" 查看示例 ")]))),_:1})]),n("div",we,[n("div",Ve,[r[3]||(r[3]=n("div",null,[n("h5",null,"截止日期"),n("p",null,"选择具体日期和时间后会自动保存。")],-1)),f(s,{modelValue:l.value,"onUpdate:modelValue":r[0]||(r[0]=e=>l.value=e),editable:!1,type:"datetime",placeholder:"点击设置新截止日期","default-time":new Date(e.ddl),onChange:t},null,8,["modelValue","default-time"])]),n("div",ze,[l.value?(i(),g(c,{key:0,type:k.value?"danger":"success",effect:"light"},{default:v((()=>[m(b(k.value?"已经截止":_.value),1)])),_:1},8,["type"])):(i(),d("span",Ce,"暂未设置截止时间")),l.value?(i(),g(u,{key:2,type:"danger",plain:"",onClick:o},{default:v((()=>r[4]||(r[4]=[m(" 取消截止时间 ")]))),_:1})):x("",!0)])])])}}}),[["__scopeId","data-v-d740ac9f"]])),{class:"config-panel"}),Ue={class:"setting-card"},Te={class:"setting-header"},Me={class:"type-editor"},Ie={class:"tag-list"},$e={key:0,class:"empty-text"},Ee={class:"setting-card"},De={class:"setting-header"},Le={class:"setting-card"},Se={class:"setting-header"},Oe={class:"size-editor"},qe=(e("F",k(t({__name:"file",props:{format:{type:String,default:"",required:!1},k:{type:String,default:""}},setup(e){const a=e,l=_(w()),t=s("");function o(){ye(a.k,{format:JSON.stringify(l)})}function u(){const e=t.value.split(",").map((e=>e.trim().toLowerCase()));for(const a of e)if(l.format.includes(a))return void r.error(`${a} 已存在`);l.format.push(...e),o(),t.value=""}function p(){I(l.format.join(","))}function h(e){l.limit=e,o()}const k=s(0),D=_(["B","KB","MB","GB"]);function L(){const e=D.findIndex((e=>e===l.sizeUnit));l.size=k.value*1024**e,o()}function S(e){k.value=e;const a=D.findIndex((e=>e===l.sizeUnit));l.size=k.value*1024**a,o()}return c((()=>{null!==a.format&&Object.assign(l,E(a.format))})),(e,a)=>{const r=de,s=y,c=$,_=R,w=ie,I=te,E=le;return i(),d("div",je,[n("section",Ue,[n("div",Te,[a[3]||(a[3]=n("div",null,[n("h4",null,"文件类型限制"),n("p",null,"通过文件名后缀限制可提交的文件类型,不区分大小写。")],-1)),f(r,{"active-text":"限制","inactive-text":"不限","model-value":l.status,style:{"--el-switch-on-color":"#13ce66","--el-switch-off-color":"#dcdfe6"},onChange:a[0]||(a[0]=e=>function(e){l.status=!!e,o()}(Boolean(e)))},null,8,["model-value"])]),V(n("div",Me,[f(c,{modelValue:t.value,"onUpdate:modelValue":a[1]||(a[1]=e=>t.value=e),placeholder:"例如:txt,png,jpeg,webp"},{append:v((()=>[f(s,{onClick:u},{default:v((()=>a[4]||(a[4]=[m(" 添加 ")]))),_:1})])),_:1},8,["modelValue"]),n("div",Ie,[(i(!0),d(C,null,j(l.format,((e,a)=>(i(),g(_,{key:a,class:"type",closable:"","disable-transitions":!1,onClose:e=>function(e){l.format.splice(e,1),o()}(a)},{default:v((()=>[m(b(e),1)])),_:2},1032,["onClose"])))),128)),l.format.length?x("",!0):(i(),d("span",$e,"暂未添加文件类型"))]),V(f(s,{type:"primary",text:"",size:"small",onClick:p},{default:v((()=>a[5]||(a[5]=[m(" 复制类型列表 ")]))),_:1},512),[[z,l.format.length]])],512),[[z,l.status]])]),n("section",Ee,[n("div",De,[a[6]||(a[6]=n("div",null,[n("h4",null,"提交数量"),n("p",null,"限制单次最多可以上传的文件数量,范围 1-16。")],-1)),f(w,{"model-value":l.limit,min:1,max:16,onChange:h},null,8,["model-value"])])]),n("section",Le,[n("div",Se,[a[7]||(a[7]=n("div",null,[n("h4",null,"文件大小"),n("p",null,"设置单个文件大小上限,填 0 表示不限制。")],-1)),n("div",Oe,[f(w,{"model-value":k.value,min:0,max:1024,onChange:S},null,8,["model-value"]),f(E,{modelValue:l.sizeUnit,"onUpdate:modelValue":a[2]||(a[2]=e=>l.sizeUnit=e),placeholder:"单位",onChange:L},{default:v((()=>[(i(!0),d(C,null,j(D,(e=>(i(),g(I,{key:e,label:e,value:e},null,8,["label","value"])))),128))])),_:1},8,["modelValue"])])]),n("div",{class:U(["result-tip",{danger:0!==l.size}])},b(0===l.size?"当前不限制文件大小":`当前限制为不超过 ${T(M)(l.size)}`),3)])])}}}),[["__scopeId","data-v-d5f004e0"]])),{class:"config-panel"}),Ne={class:"feature-grid"},Ye={class:"feature-copy"},Pe={key:0,class:"format-preview"},Be={class:"format-preview-main"},Fe={class:"split-char-field"},Ke={class:"feature-copy"},Qe={class:"builder-card"},Je={class:"builder-header"},Ae={class:"form-wrapper"},He={key:1,class:"field-list"},Ge={class:"question-head"},Ze={class:"question-title"},Xe={class:"field-index"},Re={class:"question-body"},We={key:0,class:"option-list"},ea={class:"option-title"},aa={class:"field-actions"},la={class:"builder-toolbar"},ta={key:0,class:"add-actions"},ia={class:"save-actions"},da={class:"info-panel"},na={class:"dialog-footer"},oa=(e("I",k(t({__name:"info",props:{rewrite:{type:Number,default:0},info:{typs:String,default:"[]"},k:{type:String,default:""},format:{type:String,default:"",required:!1}},emits:["update:format","update:info","update:rewrite"],setup(e,{emit:a}){D((e=>({"3e7131f8":fe.value})));const l=e,t=a,p=_(w()),h=s(!1),k=_([{label:"输入框",value:"input"},{label:"固定内容",value:"text"},{label:"单选框",value:"radio"},{label:"下拉选择",value:"select"}]),V=s("input"),{value:z}=L(),M=u((()=>z.value.maxInputLength)),I=s(!1),F=_([]),K=s(!1),Q=u((()=>F.length<z.value.formLength&&!h.value));S((()=>l.info),(()=>{F.splice(0,F.length),V.value="input",h.value=!1,F.push(...q(l.info)),K.value=!1}),{immediate:!0});const J=u((()=>`${F.map((e=>e.text)).join(p.splitChar)}.后缀`));function A(e){const a=+e;t("update:rewrite",a),ye(l.k,{rewrite:a})}function H(e,a){const l=e||F,t=a||V.value,i={text:`标题${l.length+1}`,type:t,value:""};"radio"!==t&&"select"!==t||(i.children=[{text:"选项1"},{text:"选项2"}]),l.push(i),K.value=!0}function G(e,a,l=1){const t=a||F;t.length<=l||(t.splice(e,1),K.value=!0)}function Z(e){return e.every((e=>e.text.trim()&&Z(e.children||[])))}function X(){if(!Z(F))return r.error("请完整填写表单信息"),void setTimeout((()=>{r.warning("不能有空项")}),100);const e=JSON.stringify(F.map((e=>("text"===e.type&&(e.value=e.text),e))));t("update:info",e),ye(l.k,{info:e}),K.value=!1}function W(){K.value=!0}c((()=>{I.value=!!l.rewrite}));const ae=_({taskList:[],taskValue:""}),ie=s(!1);async function se(){const e=l.k,{data:a}=await o.getUsefulTemplate(e);ae.taskList=a,ae.taskValue=a[0]?.taskKey||"",ie.value=!0}function ue(){const e=ae.taskList.find((e=>e.taskKey===ae.taskValue)).info;F.splice(0,F.length),F.push(...q(e)),ie.value=!1,K.value=!0}const pe=O(),fe=u((()=>pe.value?"0 0 auto":.5));function ve(){ce.alert("<p>固定内容主要用于重命名中,固定的部分,如“活动名”,“班级名”</p><p>如要设置注意事项,请使用 <strong>批注</strong> 功能</p>","注意事项",{dangerouslyUseHTMLString:!0})}function me(){const e=JSON.stringify(p);t("update:format",e),ye(l.k,{format:e})}const ge=_(["-","+","_"]);return c((()=>{null!==l.format&&Object.assign(p,E(l.format))})),(e,a)=>{const l=N,t=R,o=de,r=te,s=le,c=oe,u=re,_=y,w=$,z=Y,E=P,D=B;return i(),d("div",qe,[f(l,{title:"配置用户提交文件时需要填写的表单字段。开启自动重命名后,字段顺序会影响最终文件名。",type:"info","show-icon":"",closable:!1}),n("section",Ne,[n("div",{class:U(["feature-card",{active:I.value}])},[n("div",Ye,[f(t,{type:I.value?"success":"info",effect:"light"},{default:v((()=>[m(b(I.value?"已开启":"未开启"),1)])),_:1},8,["type"]),a[8]||(a[8]=n("h4",null,"文件自动重命名",-1)),a[9]||(a[9]=n("p",null,"开启后会根据表单字段生成文件名,建议保存后先预览效果。",-1))]),f(o,{modelValue:I.value,"onUpdate:modelValue":a[0]||(a[0]=e=>I.value=e),size:"large","active-text":"开","inactive-text":"关",onChange:A},null,8,["modelValue"]),I.value?(i(),d("div",Pe,[n("div",Be,[a[10]||(a[10]=n("span",null,"预期格式",-1)),n("strong",null,b(J.value),1)]),n("label",Fe,[a[11]||(a[11]=n("span",null,"分隔符",-1)),f(s,{modelValue:p.splitChar,"onUpdate:modelValue":a[1]||(a[1]=e=>p.splitChar=e),placeholder:"分隔符",size:"small",onChange:me},{default:v((()=>[(i(!0),d(C,null,j(ge,(e=>(i(),g(r,{key:e,label:e,value:e},null,8,["label","value"])))),128))])),_:1},8,["modelValue"])])])):x("",!0)],2),n("div",{class:U(["feature-card",{active:h.value}])},[n("div",Ke,[f(t,{type:h.value?"primary":"info",effect:"light"},{default:v((()=>[m(b(h.value?"预览中":"编辑中"),1)])),_:1},8,["type"]),a[12]||(a[12]=n("h4",null,"编辑 / 预览",-1)),a[13]||(a[13]=n("p",null,"编辑模式维护字段,预览模式查看用户侧填写效果。",-1))]),f(u,{modelValue:h.value,"onUpdate:modelValue":a[2]||(a[2]=e=>h.value=e),class:"mode-switch",size:"large"},{default:v((()=>[f(c,{label:!1},{default:v((()=>a[14]||(a[14]=[m(" 编辑 ")]))),_:1}),f(c,{label:!0},{default:v((()=>a[15]||(a[15]=[m(" 预览 ")]))),_:1})])),_:1},8,["modelValue"])],2)]),n("section",Qe,[n("div",Je,[a[17]||(a[17]=n("div",null,[n("h4",null,"字段列表"),n("p",null,"按问卷题目方式维护字段:标题、类型、选项和排序都在题目卡片内完成。")],-1)),f(_,{text:"",type:"primary",onClick:ve},{default:v((()=>a[16]||(a[16]=[m(" 字段说明 ")]))),_:1})]),n("div",Ae,[h.value?(i(),g(ne,{key:0,infos:F,disabled:h.value},null,8,["infos","disabled"])):(i(),d("div",He,[(i(!0),d(C,null,j(F,((e,l)=>(i(),d("div",{key:l,class:"field-card"},[n("div",Ge,[n("div",Ze,[n("span",Xe,"Q"+b(l+1),1),n("strong",null,b(e.text||"未命名字段"),1)]),f(s,{"model-value":e.type,class:"question-type",onChange:a=>function(e,a){const l=a;e.type=l,"radio"===l||"select"===l?e.children=e.children?.length?e.children:[{text:"选项1"},{text:"选项2"}]:delete e.children,W()}(e,a)},{default:v((()=>[(i(!0),d(C,null,j(k,(e=>(i(),g(r,{key:e.value,label:e.label,value:e.value},null,8,["label","value"])))),128))])),_:2},1032,["model-value","onChange"])]),n("div",Re,[a[21]||(a[21]=n("label",{class:"field-label"},"字段标题",-1)),f(w,{modelValue:e.text,"onUpdate:modelValue":a=>e.text=a,placeholder:"请输入展示给用户的字段标题",maxlength:M.value,clearable:"","show-word-limit":"",onInput:W},null,8,["modelValue","onUpdate:modelValue","maxlength"]),"radio"===e.type||"select"===e.type?(i(),d("div",We,[n("div",ea,[a[19]||(a[19]=n("span",null,"选项列表",-1)),f(_,{size:"small",text:"",type:"primary",onClick:a=>H(e.children,e.type)},{default:v((()=>a[18]||(a[18]=[m(" 添加选项 ")]))),_:2},1032,["onClick"])]),(i(!0),d(C,null,j(e.children,((l,t)=>(i(),d("div",{key:t,class:"option-item"},[n("span",null,b(t+1),1),f(w,{modelValue:l.text,"onUpdate:modelValue":e=>l.text=e,size:"small",placeholder:"输入选项内容",maxlength:M.value,clearable:"","show-word-limit":"",onInput:W},null,8,["modelValue","onUpdate:modelValue","maxlength"]),f(_,{size:"small",text:"",type:"danger",disabled:e.children.length<=2,onClick:a=>G(t,e.children,2)},{default:v((()=>a[20]||(a[20]=[m(" 删除 ")]))),_:2},1032,["disabled","onClick"])])))),128))])):x("",!0)]),n("div",aa,[l>0?(i(),g(_,{key:0,size:"small",text:"",type:"primary",onClick:e=>function(e){if(0===e)return;const a=F[e-1];F.splice(e-1,1),F.splice(e,0,a),W()}(l)},{default:v((()=>a[22]||(a[22]=[m(" 上移 ")]))),_:2},1032,["onClick"])):x("",!0),f(_,{size:"small",text:"",type:"danger",disabled:F.length<=1,onClick:e=>G(l)},{default:v((()=>a[23]||(a[23]=[m(" 删除 ")]))),_:2},1032,["disabled","onClick"])])])))),128))]))]),h.value?x("",!0):(i(),g(l,{key:0,class:"builder-alert",title:"单选框和下拉选择至少保留 2 个选项;固定内容会作为文件名的一部分,不建议用于普通提示。",type:"info","show-icon":"",closable:!1})),n("div",la,[Q.value?(i(),d("div",ta,[f(s,{modelValue:V.value,"onUpdate:modelValue":a[3]||(a[3]=e=>V.value=e),size:"default",placeholder:"选择字段类型"},{default:v((()=>[(i(!0),d(C,null,j(k,((e,a)=>(i(),g(r,{key:a,label:e.label,value:e.value},null,8,["label","value"])))),128))])),_:1},8,["modelValue"]),f(_,{type:"primary",onClick:a[4]||(a[4]=e=>H())},{default:v((()=>a[24]||(a[24]=[m(" 添加字段 ")]))),_:1})])):x("",!0),n("div",ia,[f(_,{type:"warning",plain:"",onClick:se},{default:v((()=>a[25]||(a[25]=[m(" 从其它任务导入 ")]))),_:1}),f(_,{type:"success",onClick:X},{default:v((()=>a[26]||(a[26]=[m(" 保存表单 ")]))),_:1})])]),K.value?(i(),g(l,{key:1,class:"save-alert",title:"表单信息有变动,请记得保存",type:"warning","show-icon":"",closable:!1})):x("",!0)]),n("div",da,[f(D,{modelValue:ie.value,"onUpdate:modelValue":a[7]||(a[7]=e=>ie.value=e),fullscreen:T(pe),title:"表单信息导入"},{footer:v((()=>[n("span",na,[f(_,{onClick:a[6]||(a[6]=e=>ie.value=!1)},{default:v((()=>a[27]||(a[27]=[m("取 消")]))),_:1}),f(_,{disabled:!ae.taskValue,type:"primary",onClick:ue},{default:v((()=>a[28]||(a[28]=[m("确 定 ")]))),_:1},8,["disabled"])])])),default:v((()=>[f(E,{model:ae,"label-width":"100px","label-position":"right"},{default:v((()=>[f(z,{label:"任务"},{default:v((()=>[f(s,{modelValue:ae.taskValue,"onUpdate:modelValue":a[5]||(a[5]=e=>ae.taskValue=e),filterable:"",placeholder:"请选择","no-data-text":"无可用任务"},{default:v((()=>[(i(!0),d(C,null,j(ae.taskList,(e=>(i(),g(r,{key:e.taskKey,label:e.name,value:e.taskKey},null,8,["label","value"])))),128))])),_:1},8,["modelValue"])])),_:1}),f(ee,null,{default:v((()=>[m(b(ae.taskValue?"":"无可用任务"),1)])),_:1})])),_:1},8,["model"])])),_:1},8,["modelValue","fullscreen"])])])}}}),[["__scopeId","data-v-ef3c8c92"]])),{class:"config-panel info-panel"}),ra={class:"panel-tip"},sa={class:"setting-card"},ca={class:"setting-header"},ua={class:"header-actions"},pa={class:"setting-card"},fa={class:"import-people-wrapper"},va={class:"import-card"},ma={class:"el-upload__tip"},ga={class:"import-card"},ba={class:"import-card"},xa={class:"setting-card"},ha={class:"nav"},ya={class:"item"},ka={class:"item"},_a={class:"item"},wa={class:"item"},Va={class:"tc p10"},za={class:"tc p10"},Ca={style:{"text-align":"center"}},ja={key:0,class:"submit-ok"},Ua={key:1,class:"submit-fail"},Ta={class:"dialog-footer"},Ma=(e("P",k(t({__name:"people",props:{value:{type:Number,defalut:0},k:{type:String,default:""},name:{type:String,default:""},field:{type:String,default:"姓名"}},setup(e){D((e=>({f0f25e6a:_e.value})));const a=e,l=s("手动添加"),t=s(""),p=s(!1);function k(){t.value&&(p.value=!0,F.addPeopleByUser(t.value,a.k).then((()=>{r.success(`添加 ${t.value} 成功`)})).catch((()=>{r.error(`${t.value} 已存在`)})).finally((()=>{p.value=!1,t.value=""})))}const w=s(!1),U=s(0);c((()=>{U.value=a.value}));const M=s(!1),I=_([]),E=s("all"),L=s(""),q=u((()=>L.value?I.filter((e=>e.name.includes(L.value))):I)),N=u((()=>"all"===E.value?q.value:q.value.filter((e=>e.status===E.value)))),J=s(!1);function A(){J.value=!0,F.getPeople(a.k,""+ +w.value).then((e=>{I.splice(0,I.length),I.push(...e.data.people),I.forEach((e=>{e.status||0!==e.count?e.lastDate=h(new Date(e.lastDate),"yyyy-MM-dd hh:mm:ss"):e.lastDate="暂无记录"})),J.value=!1}))}function H(){w.value=!w.value,w.value&&A()}function G(){M.value=!0,w.value=!1,A()}const Z=s([]),X=s();function R(){r.error("只能选择一个文件,可删除后重新选择")}function W(){Z.value.splice(0,Z.value.length),X.value.clearFiles()}function ae(){Z.value.forEach((e=>{K(e.raw,"/api/public/upload",{success:e=>{const{name:l,type:t}=e.data;F.importPeople(a.k,l,t).then((e=>{const{success:l,fail:t}=e.data;r.success(`导入完成:${l}成功,${t.length}失败`),t.length>0&&setTimeout((()=>{r.info("自动开始下载未成功导入名单"),Q(["未成功导入名单"],t.map((e=>[e])),`${a.name}_导入失败名单_${h(new Date,"yyyy年MM月dd日hh时mm分ss秒")}.xlsx`)}),1e3),W()}))}})}))}function ie(e){"text/plain"!==e.raw.type&&(r.warning({message:"只支持txt文件",zIndex:4e3}),W())}function ne(){if(0===N.value.length)return void r.warning("表格中没有可导出数据");const e=["姓名","提交状态","提交数量","最后操作时间",...w.value?["现存数量","提交次数"]:[]],l=N.value.map((e=>{const{name:a,status:l,lastDate:t,submitCount:i,fileCount:d,count:n}=e;return[a,l?"✔":"x",i,l?h(new Date(t)):"",...w.value?[d,n]:[]]}));Q(e,l,`${a.name}_提交情况_${h(new Date,"yyyy年MM月dd日hh时mm分ss秒")}.xlsx`),r.success("导出成功")}const me=O(),ge=_({taskList:[],type:"override",taskValue:""}),be=s(!1);async function xe(){const e=a.k,{data:l}=await F.getUsefulTemplate(e);ge.taskList=l,ge.taskValue=l[0]?.taskKey||"",be.value=!0}const he=u((()=>{const{taskList:e,taskValue:a}=ge,l=e.find((e=>e.taskKey===a));return l?`${l.count} 条数据`:"无可用任务"}));function ke(){F.importPeopleFromTpl(a.k,ge.taskValue,ge.type).then((e=>{be.value=!1;const{success:l,fail:t}=e.data;r.success(`导入成功${l}条,失败${t.length}条`),t.length>0&&setTimeout((()=>{r.info("自动开始下载未成功导入名单"),Q(["未成功导入名单"],t.map((e=>[e])),`${a.name}_导入失败名单_${h(new Date,"yyyy年MM月dd日hh时mm分ss秒")}.xlsx`)}),1e3)}))}const _e=u((()=>me.value?"0 0 auto":.5)),we=s("姓名");function Ve(){we.value.trim().length?o.updateTaskMoreInfo(a.k,{bindField:we.value}).then((()=>{r.success("保存成功")})):r.warning("绑定的表单项不能为空")}return S((()=>a.field),(e=>{we.value=e}),{immediate:!0}),(e,o)=>{const s=de,c=y,u=oe,h=re,_=ve,D=$,S=Y,O=P,q=te,K=le,Q=pe,A=fe,_e=B,ze=se,Ce=ue;return i(),d("div",oa,[n("section",ra,[o[13]||(o[13]=n("div",null,[n("h4",null,"限制名单"),n("p",null,"开启后,只有名单中的成员才可以提交文件,可通过文件、其它任务或手动方式维护名单。")],-1)),f(ee,{imgs:["https://img.cdn.sugarat.top/mdImg/MTY1MDE4MzEwOTEzOQ==650183109139","https://img.cdn.sugarat.top/mdImg/MTY1MTQ5NjY3MTUyMw==651496671523"]},{default:v((()=>o[12]||(o[12]=[m(" 查看示例 ")]))),_:1})]),n("section",sa,[n("div",ca,[n("div",null,[o[14]||(o[14]=n("h4",null,"名单校验",-1)),n("p",null,b(U.value?"当前已开启名单限制。":"当前未开启名单限制,所有用户都可以提交。"),1)]),n("div",ua,[f(s,{"model-value":Boolean(U.value),"active-text":"开启","inactive-text":"关闭",onChange:o[0]||(o[0]=e=>{return l=Boolean(e),ye(a.k,{people:+l}),void(U.value=+l);var l})},null,8,["model-value"]),U.value?(i(),g(c,{key:0,type:"primary",plain:"",onClick:G},{default:v((()=>o[15]||(o[15]=[m(" 查看提交情况 ")]))),_:1})):x("",!0)])])]),U.value?(i(),d(C,{key:0},[n("section",pa,[o[25]||(o[25]=n("div",{class:"setting-header"},[n("div",null,[n("h4",null,"名单导入"),n("p",null,"推荐大量名单使用文件导入,少量人员可直接手动添加。")])],-1)),f(h,{modelValue:l.value,"onUpdate:modelValue":o[1]||(o[1]=e=>l.value=e),class:"import-tabs"},{default:v((()=>[f(u,{label:"文件导入"}),f(u,{label:"任务导入"}),f(u,{label:"手动添加"})])),_:1},8,["modelValue"]),n("div",fa,[V(n("div",va,[f(_,{ref_key:"peopleUpload",ref:X,"file-list":Z.value,"onUpdate:fileList":o[2]||(o[2]=e=>Z.value=e),accept:"text/plain",action:"",class:"upload-demo","on-change":ie,"on-exceed":R,"on-remove":W,"auto-upload":!1,limit:1},{trigger:v((()=>[f(c,{type:"primary",plain:""},{default:v((()=>o[16]||(o[16]=[m(" 选择文件 ")]))),_:1})])),tip:v((()=>[n("div",ma,[f(ee,{imgs:["https://img.cdn.sugarat.top/mdImg/MTY1MDE4Mjk2NjUxMA==650182966510"]},{default:v((()=>o[18]||(o[18]=[m(" 只能上传 .txt 文本文件,每行一个名字 ")]))),_:1}),f(ee,null,{default:v((()=>o[19]||(o[19]=[m("如名字有特殊字符,建议去除")]))),_:1}),f(ee,null,{default:v((()=>o[20]||(o[20]=[m("上传文件导入的方式,为追加导入,不会覆盖已存在数据")]))),_:1})])])),default:v((()=>[f(c,{class:"upload-action",type:"success",disabled:!Z.value.length,onClick:ae},{default:v((()=>o[17]||(o[17]=[m(" 确定上传 ")]))),_:1},8,["disabled"])])),_:1},8,["file-list"])],512),[[z,"文件导入"===l.value]]),V(n("div",ga,[o[22]||(o[22]=n("p",null,"从已有任务中导入限制名单,可选择覆盖或追加。",-1)),f(c,{type:"success",onClick:xe},{default:v((()=>o[21]||(o[21]=[m(" 选择任务 ")]))),_:1})],512),[[z,"任务导入"===l.value]]),V(n("div",ba,[f(D,{modelValue:t.value,"onUpdate:modelValue":o[3]||(o[3]=e=>t.value=e),disabled:p.value,placeholder:"请输入姓名"},{append:v((()=>[f(c,{onClick:k},{default:v((()=>o[23]||(o[23]=[m(" 添加 ")]))),_:1})])),_:1},8,["modelValue","disabled"]),o[24]||(o[24]=n("p",null,"会自动判重,不会重复添加。大量名单优先推荐使用文件导入。",-1))],512),[[z,"手动添加"===l.value]])])]),n("section",xa,[o[27]||(o[27]=n("div",{class:"setting-header"},[n("div",null,[n("h4",null,"绑定表单项"),n("p",null,"与必填信息中的字段同名时,可避免用户重复填写。")])],-1)),f(O,{class:"bind-form","label-width":"100px"},{default:v((()=>[f(S,{label:"字段名称"},{default:v((()=>[f(D,{modelValue:we.value,"onUpdate:modelValue":o[4]||(o[4]=e=>we.value=e),size:"small",clearable:""},{append:v((()=>[f(c,{onClick:Ve},{default:v((()=>o[26]||(o[26]=[m(" 确定 ")]))),_:1})])),_:1},8,["modelValue"])])),_:1})])),_:1})])],64)):x("",!0),f(_e,{modelValue:M.value,"onUpdate:modelValue":o[7]||(o[7]=e=>M.value=e),fullscreen:T(me),title:"提交情况"},{default:v((()=>[n("div",ha,[n("div",ya,[f(c,{disabled:0===I.length,type:"success",size:"default",onClick:ne},{default:v((()=>o[28]||(o[28]=[m(" 导出记录 ")]))),_:1},8,["disabled"])]),n("div",ka,[f(K,{modelValue:E.value,"onUpdate:modelValue":o[5]||(o[5]=e=>E.value=e),size:"default",placeholder:"状态筛选"},{default:v((()=>[f(q,{label:"全部",value:"all"}),f(q,{label:"已提交",value:1}),f(q,{label:"未提交",value:0})])),_:1},8,["modelValue"])]),n("div",_a,[f(D,{modelValue:L.value,"onUpdate:modelValue":o[6]||(o[6]=e=>L.value=e),size:"default",placeholder:"输入要查询的姓名"},null,8,["modelValue"])]),n("div",wa,[f(c,{type:"primary",size:"default",onClick:H},{default:v((()=>[m(b(w.value?"隐藏":"显示")+"详细提交情况 ",1)])),_:1})])]),n("div",Va,[n("span",null,"共: "+b(N.value.length)+" 条数据",1),o[29]||(o[29]=m(", ")),n("span",null,"已提交: "+b(N.value.filter((e=>e.status)).length),1),o[30]||(o[30]=m(", ")),n("span",null,"未提交: "+b(N.value.filter((e=>!e.status)).length),1)]),n("div",za,[f(ee,null,{default:v((()=>o[31]||(o[31]=[m('"提交次数" 用户实际的提交次数')]))),_:1}),f(ee,null,{default:v((()=>o[32]||(o[32]=[m('"现存数量" 还存在于服务器上的文件数 (不包含删除) --- 慢查询')]))),_:1}),f(ee,null,{default:v((()=>o[33]||(o[33]=[m('"提交数量" 用户实际提交的文件数 (不包含撤回) --- 慢查询')]))),_:1})]),V((i(),g(A,{"element-loading-text":"Loading...",stripe:"",border:"",data:N.value,height:"460px"},{default:v((()=>[f(Q,{label:"序号",width:"60"},{default:v((e=>[n("div",Ca,b(e.$index+1),1)])),_:1}),f(Q,{property:"name",label:"姓名"}),f(Q,{label:"提交状态",width:"100"},{default:v((e=>[e.row.status?(i(),d("span",ja,"已提交")):(i(),d("span",Ua,"未提交"))])),_:1}),f(Q,{property:"count",label:"提交次数",width:"94"}),f(Q,{sortable:"",property:"lastDate",label:"最后操作时间",width:"120"}),w.value?(i(),d(C,{key:0},[f(Q,{property:"fileCount",label:"现存数量",width:"94"}),f(Q,{sortable:"",property:"submitCount",label:"提交数量",width:"120"})],64)):x("",!0),f(Q,{label:"操作",width:"100"},{default:v((e=>[f(c,{type:"primary",text:"",size:"small",onClick:l=>{return t=e.row,void ce.confirm("确认删除此人员吗","数据无价,请谨慎操作").then((()=>{F.deletePeople(a.k,t.id).then((()=>{r.success("删除成功"),I.splice(I.findIndex((e=>e.id===t.id)),1)}))})).catch((()=>{r.info("取消删除")}));var t}},{default:v((()=>o[34]||(o[34]=[m(" 删除 ")]))),_:2},1032,["onClick"])])),_:1})])),_:1},8,["data"])),[[Ce,J.value]])])),_:1},8,["modelValue","fullscreen"]),f(_e,{modelValue:be.value,"onUpdate:modelValue":o[11]||(o[11]=e=>be.value=e),fullscreen:T(me),title:"人员列表导入"},{footer:v((()=>[n("span",Ta,[f(c,{onClick:o[10]||(o[10]=e=>be.value=!1)},{default:v((()=>o[37]||(o[37]=[m("取 消")]))),_:1}),f(c,{disabled:!ge.taskValue,type:"primary",onClick:ke},{default:v((()=>o[38]||(o[38]=[m("确 定")]))),_:1},8,["disabled"])])])),default:v((()=>[f(O,{model:ge,"label-width":"100px","label-position":"right"},{default:v((()=>[f(S,{label:"任务"},{default:v((()=>[f(K,{modelValue:ge.taskValue,"onUpdate:modelValue":o[8]||(o[8]=e=>ge.taskValue=e),filterable:"",placeholder:"请选择","no-data-text":"无可用任务"},{default:v((()=>[(i(!0),d(C,null,j(ge.taskList,(e=>(i(),g(q,{key:e.taskKey,label:e.name,value:e.taskKey},null,8,["label","value"])))),128))])),_:1},8,["modelValue"])])),_:1}),f(ee,null,{default:v((()=>[m(b(he.value),1)])),_:1}),f(S,{label:"任务"},{default:v((()=>[f(h,{modelValue:ge.type,"onUpdate:modelValue":o[9]||(o[9]=e=>ge.type=e)},{default:v((()=>[f(ze,{label:"override"},{default:v((()=>o[35]||(o[35]=[m(" 覆盖导入 ")]))),_:1}),f(ze,{label:"add"},{default:v((()=>o[36]||(o[36]=[m(" 追加导入 ")]))),_:1})])),_:1},8,["modelValue"])])),_:1}),f(ee,null,{default:v((()=>[m(b("override"===ge.type?"“覆盖导入” 将会覆盖原来的数据":"“追加导入” 将只会导入不存在数据"),1)])),_:1})])),_:1},8,["model"])])),_:1},8,["modelValue","fullscreen"])])}}}),[["__scopeId","data-v-5e872bda"]])),t({name:"TemplatePanel",components:{Tip:ee},props:{value:{type:String,default:""},k:{type:String,default:""}},setup(e){const a=s();c((()=>{e.value?a.value=e.value:a.value=""}));const l=s(0),t=s([]),i=s(),d=()=>{i.value.clearFiles()};return{template:a,deleteTemplate:()=>{a.value&&(ye(e.k,{template:""}),a.value="",l.value=0)},fileList:t,handleExceedFile:()=>{r.error("只能选择一个文件,可删除后重新选择")},clearFiles:d,submitUploadPeople:()=>{t.value.forEach((l=>{if(!e.k)return;const{name:t}=l,i=`easypicker2/${e.k}_template/${t}`;"ready"===l.status&&(l.status="uploading",J.getUploadToken().then((n=>{A(n.data.token,l.raw,i,{success(){r.success("上传成功"),ye(e.k,{template:t}),d(),a.value=t,l.status="success"},process(e){l.percentage=~~e}})})))}))},elUpload:i,percentage:l}}})),Ia={class:"config-panel info-panel"},$a={class:"panel-tip"},Ea={class:"setting-card"},Da={class:"setting-header"},La={key:0,class:"setting-card"};e("a",k(Ma,[["render",function(e,a,l,t,o,r){const s=H("Tip"),c=y,u=ve;return i(),d("div",Ia,[n("section",$a,[a[2]||(a[2]=n("div",null,[n("h4",null,"模板文件"),n("p",null,"上传后,用户可以在提交页下载模板文件,再按模板要求填写或提交。")],-1)),f(s,{imgs:["https://img.cdn.sugarat.top/mdImg/MTY1MDE4MjY3MjUxNw==650182672517"]},{default:v((()=>a[1]||(a[1]=[m(" 查看示例 ")]))),_:1})]),n("section",Ea,[n("div",Da,[n("div",null,[a[3]||(a[3]=n("h4",null,"当前模板",-1)),n("p",null,b(e.template?"模板文件已生效,可在提交页下载。":"尚未设置模板文件。"),1)]),e.template?(i(),g(c,{key:0,disabled:!e.template,type:"danger",plain:"",onClick:e.deleteTemplate},{default:v((()=>a[4]||(a[4]=[m(" 删除模板 ")]))),_:1},8,["disabled","onClick"])):x("",!0)]),n("div",{class:U(["template-file",{empty:!e.template}])},b(e.template||"暂无模板文件"),3)]),e.template?x("",!0):(i(),d("section",La,[a[8]||(a[8]=n("div",{class:"setting-header"},[n("div",null,[n("h4",null,"上传模板"),n("p",null,"选择一个文件后点击“设为模板”,同一任务仅保留一个模板文件。")])],-1)),f(u,{ref:"elUpload","file-list":e.fileList,"onUpdate:fileList":a[0]||(a[0]=a=>e.fileList=a),action:"",class:"upload-file","on-exceed":e.handleExceedFile,"on-remove":e.clearFiles,"auto-upload":!1,limit:1},{trigger:v((()=>[f(c,{type:"primary",plain:""},{default:v((()=>a[5]||(a[5]=[m(" 选取文件 ")]))),_:1})])),tip:v((()=>a[7]||(a[7]=[n("div",{class:"el-upload__tip"}," 选择模板文件,然后点击设为模板。 ",-1)]))),default:v((()=>[f(c,{class:"upload-action",type:"success",disabled:!e.fileList.length,onClick:e.submitUploadPeople},{default:v((()=>a[6]||(a[6]=[m(" 设为模板 ")]))),_:1},8,["disabled","onClick"])])),_:1},8,["file-list","on-exceed","on-remove"])]))])}],["__scopeId","data-v-07111923"]]));const Sa={class:"config-panel"},Oa={class:"panel-tip"},qa={class:"setting-card"},Na={class:"setting-header"},Ya={class:"actions"},Pa={class:"setting-card"},Ba={class:"setting-header"};e("T",k(t({__name:"tipInfo",props:{tip:{type:String,default:"",required:!1},k:{type:String,default:""}},setup(e){const a=e,l=s(""),t=_({text:"",imgs:[]}),c=s(3),p=s([]),h=u((()=>p.value.map((e=>e.preview||e.url)))),k=s(0);S((()=>a.tip),(()=>{try{const e=JSON.parse(a.tip);t.imgs=e.imgs,t.text=e.text||"",p.value=t.imgs.map((e=>({...e,url:"https://img.cdn.sugarat.top/mdImg/MTY3NzkxMDI1NTU1Nw==20140524124237518.gif"}))),p.value.length&&X.getTipImageUrl(a.k,p.value.map((e=>({uid:e.uid,name:e.name})))).then((e=>{e.data.forEach(((e,a)=>{p.value[a].url=e.cover,Object.assign(p.value[a],{preview:e.preview})}))}))}catch{t.text=a.tip||"",t.imgs=[],p.value=[]}t.text?l.value=t.text:l.value=""}),{immediate:!0});const w=u((()=>t.text!==l.value));function V(e=!0){t.text!==l.value&&(t.text=l.value),ye(a.k,{tip:JSON.stringify(t)},e)}const z=s(!1);function C(e){if(!a.k)return;const{name:l,uid:i}=e,d=G(a.k,l,i);"ready"===e.status&&(e.status="success",J.getUploadToken().then((a=>{A(a.data.token,e.raw,d,{success(){t.imgs.push({uid:i,name:l}),V()}})})))}const j=e=>{const{uid:l,name:i}=e,d=t.imgs.findIndex((e=>e.uid===l));t.imgs.splice(d,1),V(),o.delTipImage(a.k,l,i)};function U(e){z.value=!0;const a=p.value.findIndex((a=>a.uid===e.uid));k.value=a}function M(){r.error(`只能选择${c.value}个图片,可删除后重新选择`)}return(e,a)=>{const t=R,o=$,r=y,s=Z,u=ve,_=ae;return i(),d("div",Sa,[n("section",Oa,[a[5]||(a[5]=n("div",null,[n("h4",null,"提交页批注"),n("p",null,"用于在提交页展示说明、注意事项和图片提示,保存后建议打开预览确认展示效果。")],-1)),f(ee,{imgs:["https://img.cdn.sugarat.top/mdImg/MTY1MTQ5NjI2OTI0MQ==651496269241"]},{default:v((()=>a[4]||(a[4]=[m(" 查看示例 ")]))),_:1})]),n("section",qa,[n("div",Na,[a[7]||(a[7]=n("div",null,[n("h4",null,"文字说明"),n("p",null,"建议控制换行和字数,避免在移动端展示过长。")],-1)),w.value?(i(),g(t,{key:0,type:"warning",effect:"light"},{default:v((()=>a[6]||(a[6]=[m(" 待保存 ")]))),_:1})):x("",!0)]),f(o,{modelValue:l.value,"onUpdate:modelValue":a[0]||(a[0]=e=>l.value=e),class:"tip-textarea",rows:7,clearable:"",max:500,"show-word-limit":"",type:"textarea",placeholder:"请输入要展示的批注信息"},null,8,["modelValue"]),n("div",Ya,[f(r,{type:"success",onClick:V},{default:v((()=>a[8]||(a[8]=[m(" 保存批注 ")]))),_:1}),f(r,{type:"danger",plain:"",onClick:a[1]||(a[1]=e=>l.value="")},{default:v((()=>a[9]||(a[9]=[m(" 清空 ")]))),_:1})])]),n("section",Pa,[n("div",Ba,[a[10]||(a[10]=n("div",null,[n("h4",null,"图片说明"),n("p",null,"最多上传 3 张图片,适合补充截图、流程图或填写示例。")],-1)),f(t,{type:"info",effect:"plain"},{default:v((()=>[m(b(p.value.length)+"/"+b(c.value),1)])),_:1})]),f(u,{"file-list":p.value,"onUpdate:fileList":a[2]||(a[2]=e=>p.value=e),class:"image-upload",accept:"image/*",limit:c.value,action:"","list-type":"picture-card","on-change":C,"on-exceed":M,"on-preview":U,"on-remove":j,"auto-upload":!1},{default:v((()=>[f(s,null,{default:v((()=>[f(T(he))])),_:1})])),_:1},8,["file-list","limit"])]),z.value?(i(),g(_,{key:0,"hide-on-click-modal":"","initial-index":k.value,"url-list":h.value,teleported:"",onClose:a[3]||(a[3]=e=>z.value=!1)},null,8,["initial-index","url-list"])):x("",!0)])}}}),[["__scopeId","data-v-1e9e399b"]]))}}}));
2
+ //# sourceMappingURL=tipInfo-legacy-CV235bKZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tipInfo-legacy-CV235bKZ.js","sources":["../../../../node_modules/.pnpm/@element-plus+icons-vue@1.1.4_vue@3.5.12_typescript@4.9.5_/node_modules/@element-plus/icons-vue/dist/es/plus.mjs","../../src/pages/dashboard/tasks/public.ts","../../src/pages/dashboard/tasks/components/infoPanel/ddl.vue","../../src/pages/dashboard/tasks/components/infoPanel/file.vue","../../src/pages/dashboard/tasks/components/infoPanel/info.vue","../../src/pages/dashboard/tasks/components/infoPanel/template.vue","../../src/pages/dashboard/tasks/components/infoPanel/people.vue","../../src/pages/dashboard/tasks/components/infoPanel/tipInfo.vue"],"sourcesContent":["import { defineComponent, openBlock, createElementBlock, createElementVNode } from 'vue';\nimport _export_sfc from './_virtual/plugin-vue_export-helper.mjs';\n\nconst _sfc_main = defineComponent({\n name: \"Plus\"\n});\nconst _hoisted_1 = {\n viewBox: \"0 0 1024 1024\",\n xmlns: \"http://www.w3.org/2000/svg\"\n};\nconst _hoisted_2 = /* @__PURE__ */ createElementVNode(\"path\", {\n fill: \"currentColor\",\n d: \"M480 480V128a32 32 0 0 1 64 0v352h352a32 32 0 1 1 0 64H544v352a32 32 0 1 1-64 0V544H128a32 32 0 0 1 0-64h352z\"\n}, null, -1);\nconst _hoisted_3 = [\n _hoisted_2\n];\nfunction _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {\n return openBlock(), createElementBlock(\"svg\", _hoisted_1, _hoisted_3);\n}\nvar plus = /* @__PURE__ */ _export_sfc(_sfc_main, [[\"render\", _sfc_render]]);\n\nexport { plus as default };\n","import { ElMessage } from 'element-plus'\nimport { TaskApi } from '@/apis'\nimport { debounce } from '@/utils/other'\n\nexport const updateTaskInfo: (\n key: string,\n options: TaskApiTypes.TaskInfo,\n successInfo?: boolean,\n) => void = debounce(\n (key, options, successInfo = true) => {\n if (key) {\n TaskApi.updateTaskMoreInfo(key, options)\n .then(() => {\n if (successInfo) {\n ElMessage.success({\n message: '设置成功',\n zIndex: 4000,\n duration: 1000,\n })\n }\n })\n .catch(() => {\n ElMessage.error({\n message: '设置失败',\n zIndex: 4000,\n })\n })\n }\n },\n 1000,\n true,\n)\n","<script lang=\"ts\" setup>\nimport { computed, onMounted, ref, watchEffect } from 'vue'\nimport { formatDate } from '@/utils/stringUtil'\nimport { updateTaskInfo } from '../../public'\nimport Tip from './tip.vue'\n\nconst props = defineProps({\n ddl: {\n type: String,\n default: '',\n required: false,\n },\n k: {\n type: String,\n default: '',\n },\n})\n\nconst newDate = ref()\nwatchEffect(() => {\n if (props.ddl) {\n newDate.value = new Date(props.ddl)\n }\n else {\n newDate.value = null\n }\n})\n// 更新DDL\nfunction updateDDL() {\n if (newDate.value) {\n const ddl = formatDate(\n new Date(newDate.value.getTime() - 1000 * 60 * 60 * 8),\n )\n updateTaskInfo(props.k, { ddl })\n }\n}\n// 关闭DDL\nfunction closeDDL() {\n newDate.value = null\n updateTaskInfo(props.k, { ddl: null })\n}\n\nconst waitTime = ref(0)\nconst isOver = computed(() => waitTime.value <= 0)\nconst waitTimeStr = computed(() => {\n let seconds = ~~(waitTime.value / 1000)\n let hour = ~~(seconds / (60 * 60))\n const day = ~~(hour / 24)\n hour %= 24\n const minute = ~~((seconds % 3600) / 60)\n seconds %= 60\n return `剩余${day}天${hour}时${minute}分${seconds}秒`\n})\n\nfunction refreshWaitTime(loop = true) {\n if (newDate.value) {\n waitTime.value = newDate.value.getTime() - Date.now()\n }\n else {\n waitTime.value = 0\n }\n if (loop) {\n setTimeout(() => {\n refreshWaitTime()\n }, 1000)\n }\n}\n\nonMounted(() => {\n refreshWaitTime()\n})\n</script>\n\n<template>\n <div class=\"config-panel ddl-panel\">\n <div class=\"panel-tip\">\n <div>\n <h4>提交截止时间</h4>\n <p>设置后,超过截止时间用户将不能继续提交文件。</p>\n </div>\n <Tip\n :imgs=\"[\n 'https://img.cdn.sugarat.top/mdImg/MTY0OTE0OTI4NjU5Nw==649149286597',\n 'https://img.cdn.sugarat.top/mdImg/MTY0OTE0OTMxMDEyOQ==649149310129',\n 'https://img.cdn.sugarat.top/mdImg/MTY0OTE0OTM3MzgxOA==649149373818',\n ]\"\n >\n 查看示例\n </Tip>\n </div>\n\n <div class=\"setting-card\">\n <div class=\"setting-main\">\n <div>\n <h5>截止日期</h5>\n <p>选择具体日期和时间后会自动保存。</p>\n </div>\n <el-date-picker\n v-model=\"newDate\"\n :editable=\"false\"\n type=\"datetime\"\n placeholder=\"点击设置新截止日期\"\n :default-time=\"new Date(ddl)\"\n @change=\"updateDDL\"\n />\n </div>\n <div class=\"setting-footer\">\n <el-tag v-if=\"newDate\" :type=\"isOver ? 'danger' : 'success'\" effect=\"light\">\n {{ isOver ? '已经截止' : waitTimeStr }}\n </el-tag>\n <span v-else class=\"muted\">暂未设置截止时间</span>\n <el-button v-if=\"newDate\" type=\"danger\" plain @click=\"closeDDL\">\n 取消截止时间\n </el-button>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.panel-tip,\n.setting-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.panel-tip {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n background: #f8fbff;\n\n h4 {\n margin: 0;\n font-size: 16px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.setting-main,\n.setting-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.setting-main {\n h5 {\n margin: 0;\n font-size: 15px;\n color: #303133;\n }\n\n p {\n margin: 6px 0 0;\n font-size: 13px;\n color: #909399;\n }\n}\n\n.setting-footer {\n margin-top: 18px;\n padding-top: 16px;\n border-top: 1px solid #edf2f7;\n}\n\n.muted {\n color: #909399;\n}\n\n@media screen and (max-width: 700px) {\n .panel-tip,\n .setting-main,\n .setting-footer {\n align-items: stretch;\n flex-direction: column;\n }\n\n .ddl-panel :deep(.el-date-editor) {\n width: 100%;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { ElMessage } from 'element-plus'\nimport { reactive, ref, watchEffect } from 'vue'\nimport {\n copyRes,\n formatSize,\n getDefaultFormat,\n parseFileFormat,\n} from '@/utils/stringUtil'\nimport { updateTaskInfo } from '../../public'\n\nconst props = defineProps({\n format: {\n type: String,\n default: '',\n required: false,\n },\n k: {\n type: String,\n default: '',\n },\n})\n\nconst formatData = reactive(getDefaultFormat())\nconst typeName = ref('')\nfunction updateInfo() {\n updateTaskInfo(props.k, {\n format: JSON.stringify(formatData),\n })\n}\nfunction handleChange(v: boolean) {\n formatData.status = !!v\n updateInfo()\n}\n\nfunction handleAddType() {\n const inputValue = typeName.value\n .split(',')\n // 转为小写\n .map(v => v.trim().toLowerCase())\n for (const v of inputValue) {\n if (formatData.format.includes(v)) {\n ElMessage.error(`${v} 已存在`)\n return\n }\n }\n\n formatData.format.push(...inputValue)\n updateInfo()\n\n typeName.value = ''\n}\nfunction handleDelType(idx) {\n formatData.format.splice(idx, 1)\n updateInfo()\n}\nfunction handleCopyType() {\n copyRes(formatData.format.join(','))\n}\n\nfunction handleChangeLimit(limit: number) {\n formatData.limit = limit\n updateInfo()\n}\n\nconst inputSize = ref(0)\nconst unitList = reactive(['B', 'KB', 'MB', 'GB'])\nfunction handleChangeUnit() {\n const idx = unitList.findIndex(v => v === formatData.sizeUnit)\n formatData.size = inputSize.value * 1024 ** idx\n updateInfo()\n}\nfunction handleLimitSize(limit: number) {\n inputSize.value = limit\n const idx = unitList.findIndex(v => v === formatData.sizeUnit)\n formatData.size = inputSize.value * 1024 ** idx\n updateInfo()\n}\n\nwatchEffect(() => {\n if (props.format !== null) {\n Object.assign(formatData, parseFileFormat(props.format))\n }\n})\n</script>\n\n<template>\n <div class=\"config-panel\">\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>文件类型限制</h4>\n <p>通过文件名后缀限制可提交的文件类型,不区分大小写。</p>\n </div>\n <el-switch\n active-text=\"限制\"\n inactive-text=\"不限\"\n :model-value=\"formatData.status\"\n style=\"--el-switch-on-color: #13ce66; --el-switch-off-color: #dcdfe6\"\n @change=\"v => handleChange(Boolean(v))\"\n />\n </div>\n <div v-show=\"formatData.status\" class=\"type-editor\">\n <el-input v-model=\"typeName\" placeholder=\"例如:txt,png,jpeg,webp\">\n <template #append>\n <el-button @click=\"handleAddType\">\n 添加\n </el-button>\n </template>\n </el-input>\n <div class=\"tag-list\">\n <el-tag\n v-for=\"(tag, idx) in formatData.format\"\n :key=\"idx\"\n class=\"type\"\n closable\n :disable-transitions=\"false\"\n @close=\"handleDelType(idx)\"\n >\n {{ tag }}\n </el-tag>\n <span v-if=\"!formatData.format.length\" class=\"empty-text\">暂未添加文件类型</span>\n </div>\n <el-button\n v-show=\"formatData.format.length\"\n type=\"primary\"\n text\n size=\"small\"\n @click=\"handleCopyType\"\n >\n 复制类型列表\n </el-button>\n </div>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>提交数量</h4>\n <p>限制单次最多可以上传的文件数量,范围 1-16。</p>\n </div>\n <el-input-number\n :model-value=\"formatData.limit\"\n :min=\"1\"\n :max=\"16\"\n @change=\"handleChangeLimit\"\n />\n </div>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>文件大小</h4>\n <p>设置单个文件大小上限,填 0 表示不限制。</p>\n </div>\n <div class=\"size-editor\">\n <el-input-number\n :model-value=\"inputSize\"\n :min=\"0\"\n :max=\"1024\"\n @change=\"handleLimitSize\"\n />\n <el-select\n v-model=\"formatData.sizeUnit\"\n placeholder=\"单位\"\n @change=\"handleChangeUnit\"\n >\n <el-option v-for=\"v in unitList\" :key=\"v\" :label=\"v\" :value=\"v\" />\n </el-select>\n </div>\n </div>\n <div class=\"result-tip\" :class=\"{ danger: formatData.size !== 0 }\">\n {{\n formatData.size === 0\n ? '当前不限制文件大小'\n : `当前限制为不超过 ${formatSize(formatData.size)}`\n }}\n </div>\n </section>\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.setting-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.setting-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n\n h4 {\n margin: 0;\n font-size: 16px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.type-editor {\n display: grid;\n gap: 12px;\n max-width: 520px;\n margin-top: 18px;\n}\n\n.tag-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.type {\n margin: 0;\n}\n\n.empty-text {\n font-size: 13px;\n color: #c0c4cc;\n}\n\n.size-editor {\n display: flex;\n gap: 10px;\n\n .el-select {\n width: 100px;\n }\n}\n\n.result-tip {\n margin-top: 16px;\n padding: 10px 12px;\n color: #606266;\n background-color: #f5f7fa;\n border-radius: 10px;\n\n &.danger {\n color: #f56c6c;\n background-color: #fef0f0;\n }\n}\n\n@media screen and (max-width: 700px) {\n .setting-header,\n .size-editor {\n align-items: stretch;\n flex-direction: column;\n }\n\n .size-editor .el-select {\n width: 100%;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { ElMessage, ElMessageBox } from 'element-plus'\nimport { computed, reactive, ref, watch, watchEffect } from 'vue'\nimport { TaskApi } from '@/apis'\nimport InfosForm from '@/components/InfosForm/index.vue'\nimport { useIsMobile, useSiteConfig } from '@/composables'\nimport {\n getDefaultFormat,\n parseFileFormat,\n parseInfo,\n} from '@/utils/stringUtil'\nimport { updateTaskInfo } from '../../public'\nimport Tip from './tip.vue'\n\nconst props = defineProps({\n rewrite: {\n type: Number,\n default: 0,\n },\n info: {\n typs: String,\n default: '[]',\n },\n k: {\n type: String,\n default: '',\n },\n format: {\n type: String,\n default: '',\n required: false,\n },\n})\nconst emit = defineEmits<{\n 'update:format': [value: string]\n 'update:info': [value: string]\n 'update:rewrite': [value: number]\n}>()\nconst formatData = reactive(getDefaultFormat())\nconst openPreview = ref(false)\nconst infoTypeList = reactive<{ label: string, value: InfoItemType }[]>([\n {\n label: '输入框',\n value: 'input',\n },\n {\n label: '固定内容',\n value: 'text',\n },\n {\n label: '单选框',\n value: 'radio',\n },\n {\n label: '下拉选择',\n value: 'select',\n },\n])\nconst selectType = ref<InfoItemType>('input')\n\nconst { value: siteConfig } = useSiteConfig()\nconst maxInputLength = computed(() => siteConfig.value.maxInputLength)\n\nconst autoRewrite = ref(false)\nconst infos = reactive<InfoItem[]>([])\nconst needSave = ref(false)\n\nconst showAddInfo = computed(() => infos.length < siteConfig.value.formLength && !openPreview.value)\n// 负责清空&更新\nwatch(\n () => props.info,\n () => {\n infos.splice(0, infos.length)\n selectType.value = 'input'\n openPreview.value = false\n infos.push(...parseInfo(props.info))\n needSave.value = false\n },\n {\n immediate: true,\n },\n)\n\n// 预计格式\nconst resFormat = computed(\n () => `${infos.map(v => v.text).join(formatData.splitChar)}.后缀`,\n)\nwatchEffect(() => {\n autoRewrite.value = !!props.rewrite\n})\nfunction handleChange(v: boolean) {\n const rewrite = +v\n emit('update:rewrite', rewrite)\n updateTaskInfo(props.k, {\n rewrite,\n })\n}\n\nfunction addInfo(infoList?: InfoItem[], type?: InfoItemType) {\n const list = infoList || infos\n const t = type || selectType.value\n const item: InfoItem = { text: `标题${list.length + 1}`, type: t, value: '' }\n if (t === 'radio' || t === 'select') {\n item.children = [{ text: '选项1' }, { text: '选项2' }]\n }\n list.push(item)\n needSave.value = true\n}\nfunction deleteInfo(idx: number, infoList?: InfoItem[], minLen = 1) {\n const list = infoList || infos\n if (list.length <= minLen) {\n return\n }\n list.splice(idx, 1)\n needSave.value = true\n}\nfunction judgeInfoForm(items: InfoItem[]) {\n return items.every(v => v.text.trim() && judgeInfoForm(v.children || []))\n}\nfunction saveInfo() {\n if (!judgeInfoForm(infos)) {\n ElMessage.error('请完整填写表单信息')\n setTimeout(() => {\n ElMessage.warning('不能有空项')\n }, 100)\n return\n }\n const nextInfo = JSON.stringify(\n infos.map((v) => {\n // 特殊处理固定值的内容\n if (v.type === 'text') {\n v.value = v.text\n }\n return v\n }),\n )\n emit('update:info', nextInfo)\n updateTaskInfo(props.k, { info: nextInfo })\n needSave.value = false\n}\n\nfunction markInfoChanged() {\n needSave.value = true\n}\n\nfunction moveInfoUp(idx: number) {\n if (idx === 0)\n return\n const temp = infos[idx - 1]\n infos.splice(idx - 1, 1)\n infos.splice(idx, 0, temp)\n markInfoChanged()\n}\n\nfunction handleChangeInfoType(item: InfoItem, type: string) {\n const nextType = type as InfoItemType\n item.type = nextType\n if (nextType === 'radio' || nextType === 'select') {\n item.children = item.children?.length\n ? item.children\n : [{ text: '选项1' }, { text: '选项2' }]\n }\n else {\n delete item.children\n }\n markInfoChanged()\n}\n\nconst importPanelInfo = reactive({ taskList: [], taskValue: '' })\nconst showImportPanel = ref(false)\nasync function openImportPanel() {\n const taskKey = props.k\n // 通过任务Key获取可用任务列表,与概况信息\n const { data } = await TaskApi.getUsefulTemplate(taskKey)\n importPanelInfo.taskList = data\n importPanelInfo.taskValue = data[0]?.taskKey || ''\n showImportPanel.value = true\n}\n\nfunction handleSaveImportInfo() {\n const usefulInfo = importPanelInfo.taskList.find(\n v => v.taskKey === importPanelInfo.taskValue,\n ).info\n infos.splice(0, infos.length)\n infos.push(...parseInfo(usefulInfo))\n showImportPanel.value = false\n needSave.value = true\n}\n\nconst isMobile = useIsMobile()\nconst importPanelFlexStyle = computed(() => (isMobile.value ? '0 0 auto' : 0.5))\n\nfunction showHelp() {\n ElMessageBox.alert(\n '<p>固定内容主要用于重命名中,固定的部分,如“活动名”,“班级名”</p><p>如要设置注意事项,请使用 <strong>批注</strong> 功能</p>',\n '注意事项',\n { dangerouslyUseHTMLString: true },\n )\n}\n\nfunction handleChangeSplitChar() {\n const format = JSON.stringify(formatData)\n emit('update:format', format)\n updateTaskInfo(props.k, { format })\n}\nconst splitCharList = reactive(['-', '+', '_'])\nwatchEffect(() => {\n if (props.format !== null) {\n Object.assign(formatData, parseFileFormat(props.format))\n }\n})\n</script>\n\n<template>\n <div class=\"config-panel\">\n <el-alert\n title=\"配置用户提交文件时需要填写的表单字段。开启自动重命名后,字段顺序会影响最终文件名。\"\n type=\"info\"\n show-icon\n :closable=\"false\"\n />\n\n <section class=\"feature-grid\">\n <div class=\"feature-card\" :class=\"{ active: autoRewrite }\">\n <div class=\"feature-copy\">\n <el-tag :type=\"autoRewrite ? 'success' : 'info'\" effect=\"light\">\n {{ autoRewrite ? '已开启' : '未开启' }}\n </el-tag>\n <h4>文件自动重命名</h4>\n <p>开启后会根据表单字段生成文件名,建议保存后先预览效果。</p>\n </div>\n <el-switch\n v-model=\"autoRewrite\"\n size=\"large\"\n active-text=\"开\"\n inactive-text=\"关\"\n @change=\"handleChange\"\n />\n <div v-if=\"autoRewrite\" class=\"format-preview\">\n <div class=\"format-preview-main\">\n <span>预期格式</span>\n <strong>{{ resFormat }}</strong>\n </div>\n <label class=\"split-char-field\">\n <span>分隔符</span>\n <el-select\n v-model=\"formatData.splitChar\"\n placeholder=\"分隔符\"\n size=\"small\"\n @change=\"handleChangeSplitChar\"\n >\n <el-option v-for=\"v in splitCharList\" :key=\"v\" :label=\"v\" :value=\"v\" />\n </el-select>\n </label>\n </div>\n </div>\n\n <div class=\"feature-card\" :class=\"{ active: openPreview }\">\n <div class=\"feature-copy\">\n <el-tag :type=\"openPreview ? 'primary' : 'info'\" effect=\"light\">\n {{ openPreview ? '预览中' : '编辑中' }}\n </el-tag>\n <h4>编辑 / 预览</h4>\n <p>编辑模式维护字段,预览模式查看用户侧填写效果。</p>\n </div>\n <el-radio-group\n v-model=\"openPreview\"\n class=\"mode-switch\"\n size=\"large\"\n >\n <el-radio-button :label=\"false\">\n 编辑\n </el-radio-button>\n <el-radio-button :label=\"true\">\n 预览\n </el-radio-button>\n </el-radio-group>\n </div>\n </section>\n\n <section class=\"builder-card\">\n <div class=\"builder-header\">\n <div>\n <h4>字段列表</h4>\n <p>按问卷题目方式维护字段:标题、类型、选项和排序都在题目卡片内完成。</p>\n </div>\n <el-button text type=\"primary\" @click=\"showHelp\">\n 字段说明\n </el-button>\n </div>\n\n <div class=\"form-wrapper\">\n <InfosForm v-if=\"openPreview\" :infos=\"infos\" :disabled=\"openPreview\" />\n <div v-else class=\"field-list\">\n <div v-for=\"(item, idx) in infos\" :key=\"idx\" class=\"field-card\">\n <div class=\"question-head\">\n <div class=\"question-title\">\n <span class=\"field-index\">Q{{ idx + 1 }}</span>\n <strong>{{ item.text || '未命名字段' }}</strong>\n </div>\n <el-select\n :model-value=\"item.type\"\n class=\"question-type\"\n @change=\"v => handleChangeInfoType(item, v)\"\n >\n <el-option\n v-for=\"type in infoTypeList\"\n :key=\"type.value\"\n :label=\"type.label\"\n :value=\"type.value\"\n />\n </el-select>\n </div>\n\n <div class=\"question-body\">\n <label class=\"field-label\">字段标题</label>\n <el-input\n v-model=\"item.text\"\n placeholder=\"请输入展示给用户的字段标题\"\n :maxlength=\"maxInputLength\"\n clearable\n show-word-limit\n @input=\"markInfoChanged\"\n />\n\n <div\n v-if=\"item.type === 'radio' || item.type === 'select'\"\n class=\"option-list\"\n >\n <div class=\"option-title\">\n <span>选项列表</span>\n <el-button\n size=\"small\"\n text\n type=\"primary\"\n @click=\"addInfo(item.children, item.type)\"\n >\n 添加选项\n </el-button>\n </div>\n <div\n v-for=\"(v, idx2) in item.children\"\n :key=\"idx2\"\n class=\"option-item\"\n >\n <span>{{ idx2 + 1 }}</span>\n <el-input\n v-model=\"v.text\"\n size=\"small\"\n placeholder=\"输入选项内容\"\n :maxlength=\"maxInputLength\"\n clearable\n show-word-limit\n @input=\"markInfoChanged\"\n />\n <el-button\n size=\"small\"\n text\n type=\"danger\"\n :disabled=\"item.children.length <= 2\"\n @click=\"deleteInfo(idx2, item.children, 2)\"\n >\n 删除\n </el-button>\n </div>\n </div>\n </div>\n\n <div class=\"field-actions\">\n <el-button\n v-if=\"idx > 0\"\n size=\"small\"\n text\n type=\"primary\"\n @click=\"moveInfoUp(idx)\"\n >\n 上移\n </el-button>\n <el-button\n size=\"small\"\n text\n type=\"danger\"\n :disabled=\"infos.length <= 1\"\n @click=\"deleteInfo(idx)\"\n >\n 删除\n </el-button>\n </div>\n </div>\n </div>\n </div>\n\n <el-alert\n v-if=\"!openPreview\"\n class=\"builder-alert\"\n title=\"单选框和下拉选择至少保留 2 个选项;固定内容会作为文件名的一部分,不建议用于普通提示。\"\n type=\"info\"\n show-icon\n :closable=\"false\"\n />\n\n <div class=\"builder-toolbar\">\n <div v-if=\"showAddInfo\" class=\"add-actions\">\n <el-select\n v-model=\"selectType\"\n size=\"default\"\n placeholder=\"选择字段类型\"\n >\n <el-option\n v-for=\"(v, idx) in infoTypeList\"\n :key=\"idx\"\n :label=\"v.label\"\n :value=\"v.value\"\n />\n </el-select>\n <el-button type=\"primary\" @click=\"addInfo()\">\n 添加字段\n </el-button>\n </div>\n <div class=\"save-actions\">\n <el-button type=\"warning\" plain @click=\"openImportPanel\">\n 从其它任务导入\n </el-button>\n <el-button type=\"success\" @click=\"saveInfo\">\n 保存表单\n </el-button>\n </div>\n </div>\n <el-alert\n v-if=\"needSave\"\n class=\"save-alert\"\n title=\"表单信息有变动,请记得保存\"\n type=\"warning\"\n show-icon\n :closable=\"false\"\n />\n </section>\n\n <div class=\"info-panel\">\n <el-dialog\n v-model=\"showImportPanel\"\n :fullscreen=\"isMobile\"\n title=\"表单信息导入\"\n >\n <el-form\n :model=\"importPanelInfo\"\n label-width=\"100px\"\n label-position=\"right\"\n >\n <el-form-item label=\"任务\">\n <el-select\n v-model=\"importPanelInfo.taskValue\"\n filterable\n placeholder=\"请选择\"\n no-data-text=\"无可用任务\"\n >\n <el-option\n v-for=\"t in importPanelInfo.taskList\"\n :key=\"t.taskKey\"\n :label=\"t.name\"\n :value=\"t.taskKey\"\n />\n </el-select>\n </el-form-item>\n <Tip>{{ importPanelInfo.taskValue ? '' : '无可用任务' }}</Tip>\n </el-form>\n <template #footer>\n <span class=\"dialog-footer\">\n <el-button @click=\"showImportPanel = false\">取 消</el-button>\n <el-button\n :disabled=\"!importPanelInfo.taskValue\"\n type=\"primary\"\n @click=\"handleSaveImportInfo\"\n >确 定\n </el-button>\n </span>\n </template>\n </el-dialog>\n </div>\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.feature-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 16px;\n}\n\n.feature-card,\n.builder-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.feature-card {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n flex-wrap: wrap;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease;\n\n &.active {\n border-color: #b3d8ff;\n box-shadow: 0 10px 24px rgba(64, 158, 255, 0.08);\n }\n}\n\n.feature-copy {\n min-width: 0;\n flex: 1;\n\n h4 {\n margin: 12px 0 0;\n font-size: 17px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.format-preview {\n display: grid;\n gap: 10px;\n flex: 0 0 100%;\n padding: 12px;\n background-color: #f8fbff;\n border-radius: 12px;\n}\n\n.format-preview-main,\n.split-char-field {\n display: flex;\n align-items: center;\n gap: 12px;\n\n span {\n flex: 0 0 auto;\n color: #909399;\n }\n}\n\n.format-preview-main {\n strong {\n flex: 1;\n min-width: 0;\n color: #409eff;\n word-break: break-all;\n }\n}\n\n.split-char-field {\n margin: 0;\n\n .el-select {\n width: 90px;\n }\n}\n\n.mode-switch {\n white-space: nowrap;\n}\n\n.info-panel :deep(.el-form-item__label) {\n flex: v-bind(importPanelFlexStyle);\n justify-content: flex-end;\n}\n\n.builder-card {\n padding: 0;\n overflow: hidden;\n}\n\n.builder-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n padding: 18px 20px;\n background: linear-gradient(180deg, #ffffff 0%, #fafcff 100%);\n border-bottom: 1px solid #edf2f7;\n\n h4 {\n margin: 0;\n font-size: 17px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.form-wrapper {\n padding: 18px 20px 0;\n}\n\n.field-list {\n display: grid;\n gap: 14px;\n}\n\n.field-card {\n overflow: hidden;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n box-shadow: 0 8px 20px rgba(31, 45, 61, 0.04);\n}\n\n.question-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 14px;\n padding: 14px 16px;\n background-color: #fafcff;\n border-bottom: 1px solid #edf2f7;\n}\n\n.question-title {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n\n strong {\n overflow: hidden;\n color: #303133;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n}\n\n.field-index {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 36px;\n height: 30px;\n padding: 0 10px;\n color: #409eff;\n font-weight: 600;\n background-color: #ecf5ff;\n border-radius: 999px;\n}\n\n.question-type {\n width: 140px;\n flex: 0 0 auto;\n}\n\n.question-body {\n display: grid;\n gap: 10px;\n padding: 16px;\n}\n\n.field-label,\n.option-title {\n font-size: 13px;\n font-weight: 600;\n color: #606266;\n}\n\n.option-list {\n display: grid;\n gap: 10px;\n margin-top: 8px;\n padding: 12px;\n background-color: #fafcff;\n border: 1px dashed #dcdfe6;\n border-radius: 12px;\n}\n\n.option-title,\n.option-item {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.option-title {\n justify-content: space-between;\n}\n\n.option-item > span {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n color: #909399;\n background-color: #fff;\n border-radius: 50%;\n}\n\n.field-actions,\n.builder-toolbar,\n.add-actions,\n.save-actions {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.field-actions {\n justify-content: flex-end;\n padding: 12px 16px;\n border-top: 1px solid #edf2f7;\n}\n\n.builder-alert {\n margin: 16px 20px 0;\n}\n\n.builder-toolbar {\n justify-content: space-between;\n flex-wrap: wrap;\n margin: 18px 20px 0;\n padding: 16px 0 18px;\n border-top: 1px solid #edf2f7;\n}\n\n.add-actions .el-select {\n width: 150px;\n}\n\n.save-alert {\n margin: 14px 20px 18px;\n}\n\n@media screen and (max-width: 700px) {\n .feature-grid {\n grid-template-columns: 1fr;\n }\n\n .feature-card,\n .builder-header,\n .question-head,\n .option-title,\n .option-item,\n .builder-toolbar,\n .add-actions,\n .save-actions {\n align-items: stretch;\n flex-direction: column;\n }\n\n .format-preview {\n flex: none;\n width: auto;\n }\n\n .format-preview-main,\n .split-char-field {\n align-items: stretch;\n flex-direction: column;\n gap: 6px;\n }\n\n .mode-switch {\n width: 100%;\n }\n\n .mode-switch :deep(.el-radio-button) {\n width: 50%;\n }\n\n .mode-switch :deep(.el-radio-button__inner) {\n width: 100%;\n }\n\n .question-type,\n .split-char-field .el-select {\n width: 100%;\n }\n\n .form-wrapper {\n padding: 14px 12px 0;\n }\n\n .builder-alert,\n .builder-toolbar,\n .save-alert {\n margin-right: 12px;\n margin-left: 12px;\n }\n\n .add-actions .el-select,\n .save-actions .el-button {\n width: 100%;\n }\n}\n</style>\n","<script lang=\"ts\">\nimport type { UploadUserFile } from 'element-plus'\nimport { ElMessage } from 'element-plus'\nimport { defineComponent, ref, watchEffect } from 'vue'\nimport { FileApi } from '@/apis'\nimport { qiniuUpload } from '@/utils/networkUtil'\nimport { updateTaskInfo } from '../../public'\nimport Tip from './tip.vue'\n\nexport default defineComponent({\n name: 'TemplatePanel',\n components: { Tip },\n props: {\n value: {\n type: String,\n default: '',\n },\n k: {\n type: String,\n default: '',\n },\n },\n setup(props) {\n const template = ref()\n watchEffect(() => {\n if (props.value) {\n template.value = props.value\n }\n else {\n template.value = ''\n }\n })\n const percentage = ref(0)\n // 删除模板\n const deleteTemplate = () => {\n if (template.value) {\n // 移除文件,避免空间被长时间占用\n updateTaskInfo(props.k, { template: '' })\n template.value = ''\n percentage.value = 0\n }\n }\n // 文件上传\n const fileList = ref<UploadUserFile[]>([])\n const elUpload = ref()\n // 超出选择的文件个数\n const handleExceedFile = () => {\n ElMessage.error('只能选择一个文件,可删除后重新选择')\n }\n // 清空文件\n const clearFiles = () => {\n elUpload.value.clearFiles()\n }\n // 开始上传\n const submitUploadPeople = () => {\n fileList.value.forEach((file) => {\n if (!props.k) {\n return\n }\n const { name } = file\n const key = `easypicker2/${props.k}_template/${name}`\n if (file.status === 'ready') {\n file.status = 'uploading'\n // qiniu上传\n FileApi.getUploadToken().then((res) => {\n qiniuUpload(res.data.token, file.raw, key, {\n success() {\n ElMessage.success('上传成功')\n updateTaskInfo(props.k, { template: name })\n // 清理上传完成的\n clearFiles()\n template.value = name\n file.status = 'success'\n // hash,key\n // console.log(data)\n },\n process(per: number) {\n file.percentage = ~~per\n },\n })\n })\n }\n })\n }\n return {\n template,\n deleteTemplate,\n fileList,\n handleExceedFile,\n clearFiles,\n submitUploadPeople,\n elUpload,\n percentage,\n }\n },\n})\n</script>\n\n<template>\n <div class=\"config-panel info-panel\">\n <section class=\"panel-tip\">\n <div>\n <h4>模板文件</h4>\n <p>上传后,用户可以在提交页下载模板文件,再按模板要求填写或提交。</p>\n </div>\n <Tip\n :imgs=\"[\n 'https://img.cdn.sugarat.top/mdImg/MTY1MDE4MjY3MjUxNw==650182672517',\n ]\"\n >\n 查看示例\n </Tip>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>当前模板</h4>\n <p>{{ template ? '模板文件已生效,可在提交页下载。' : '尚未设置模板文件。' }}</p>\n </div>\n <el-button\n v-if=\"template\"\n :disabled=\"!template\"\n type=\"danger\"\n plain\n @click=\"deleteTemplate\"\n >\n 删除模板\n </el-button>\n </div>\n <div class=\"template-file\" :class=\"{ empty: !template }\">\n {{ template || '暂无模板文件' }}\n </div>\n </section>\n\n <section v-if=\"!template\" class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>上传模板</h4>\n <p>选择一个文件后点击“设为模板”,同一任务仅保留一个模板文件。</p>\n </div>\n </div>\n <el-upload\n ref=\"elUpload\"\n v-model:file-list=\"fileList\"\n action=\"\"\n class=\"upload-file\"\n :on-exceed=\"handleExceedFile\"\n :on-remove=\"clearFiles\"\n :auto-upload=\"false\"\n :limit=\"1\"\n >\n <template #trigger>\n <el-button type=\"primary\" plain>\n 选取文件\n </el-button>\n </template>\n <el-button\n class=\"upload-action\"\n type=\"success\"\n :disabled=\"!fileList.length\"\n @click=\"submitUploadPeople\"\n >\n 设为模板\n </el-button>\n <template #tip>\n <div class=\"el-upload__tip\">\n 选择模板文件,然后点击设为模板。\n </div>\n </template>\n </el-upload>\n </section>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.panel-tip,\n.setting-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.panel-tip,\n.setting-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n\n h4 {\n margin: 0;\n font-size: 16px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.panel-tip {\n background-color: #f8fbff;\n}\n\n.template-file {\n margin-top: 16px;\n padding: 12px 14px;\n color: #303133;\n background-color: #f5f7fa;\n border-radius: 10px;\n word-break: break-all;\n\n &.empty {\n color: #c0c4cc;\n }\n}\n\n.upload-file {\n margin-top: 16px;\n}\n\n.upload-action {\n margin-left: 10px;\n}\n\n.info-panel :deep(.el-upload-list__item-name) {\n justify-content: flex-start;\n}\n\n@media screen and (max-width: 700px) {\n .panel-tip,\n .setting-header {\n align-items: stretch;\n flex-direction: column;\n }\n\n .upload-action {\n display: block;\n width: 100%;\n margin: 10px 0 0;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport type { UploadUserFile } from 'element-plus'\nimport { ElMessage, ElMessageBox } from 'element-plus'\nimport { computed, reactive, ref, watch, watchEffect } from 'vue'\nimport { PeopleApi, TaskApi } from '@/apis'\nimport { useIsMobile } from '@/composables'\nimport { tableToExcel, uploadFile } from '@/utils/networkUtil'\nimport { formatDate } from '@/utils/stringUtil'\nimport { updateTaskInfo } from '../../public'\nimport Tip from './tip.vue'\n\nconst props = defineProps({\n value: {\n type: Number,\n defalut: 0,\n },\n k: {\n type: String,\n default: '',\n },\n name: {\n type: String,\n default: '',\n },\n field: {\n type: String,\n default: '姓名',\n },\n})\n\nconst activeTab = ref('手动添加')\nconst userInputName = ref('')\nconst importStatus = ref(false)\n\nfunction handAddName() {\n if (!userInputName.value) {\n return\n }\n importStatus.value = true\n PeopleApi.addPeopleByUser(userInputName.value, props.k)\n .then(() => {\n ElMessage.success(`添加 ${userInputName.value} 成功`)\n })\n .catch(() => {\n ElMessage.error(`${userInputName.value} 已存在`)\n })\n .finally(() => {\n importStatus.value = false\n userInputName.value = ''\n })\n}\nconst checkMore = ref(false)\n\nconst people = ref(0)\nwatchEffect(() => {\n people.value = props.value as number\n})\n// 限制提交人员\nfunction updateLimitPeople(limit: boolean) {\n updateTaskInfo(props.k, {\n people: +limit,\n })\n people.value = +limit\n}\n\n// 查看提交情况\nconst showPeopleList = ref(false)\nconst peopleList: any = reactive([])\nconst selectSubmitStatus = ref('all')\nconst searchName = ref('')\nconst filterPeopleBySearchWord = computed(() => {\n if (!searchName.value) {\n return peopleList\n }\n return peopleList.filter(v => v.name.includes(searchName.value))\n})\nconst peopleSubmitData = computed(() => {\n if (selectSubmitStatus.value === 'all') {\n return filterPeopleBySearchWord.value\n }\n return filterPeopleBySearchWord.value.filter(\n p => p.status === selectSubmitStatus.value,\n )\n})\nconst isLoadingPeopleData = ref(false)\nfunction refreshSubmitData() {\n isLoadingPeopleData.value = true\n PeopleApi.getPeople(props.k, `${+checkMore.value}`).then((res) => {\n peopleList.splice(0, peopleList.length)\n peopleList.push(...res.data.people)\n peopleList.forEach((p) => {\n if (!p.status && p.count === 0) {\n p.lastDate = '暂无记录'\n }\n else {\n p.lastDate = formatDate(new Date(p.lastDate), 'yyyy-MM-dd hh:mm:ss')\n }\n })\n isLoadingPeopleData.value = false\n })\n}\nfunction handleCheckMore() {\n checkMore.value = !checkMore.value\n if (checkMore.value) {\n refreshSubmitData()\n }\n}\nfunction checkPeople() {\n showPeopleList.value = true\n // 默认不展示提交数量\n checkMore.value = false\n refreshSubmitData()\n}\nfunction handleDeletePeople(item: any) {\n ElMessageBox.confirm('确认删除此人员吗', '数据无价,请谨慎操作')\n .then(() => {\n PeopleApi.deletePeople(props.k, item.id).then(() => {\n ElMessage.success('删除成功')\n peopleList.splice(\n peopleList.findIndex(v => v.id === item.id),\n 1,\n )\n })\n })\n .catch(() => {\n ElMessage.info('取消删除')\n })\n}\n// 文件上传\nconst peopleFileList = ref<UploadUserFile[]>([])\nconst peopleUpload = ref()\n// 超出选择的文件个数\nfunction handleExceedFile() {\n ElMessage.error('只能选择一个文件,可删除后重新选择')\n}\n// 清空文件\nfunction clearFiles() {\n peopleFileList.value.splice(0, peopleFileList.value.length)\n peopleUpload.value.clearFiles()\n}\n// 开始上传\nfunction submitUploadPeople() {\n peopleFileList.value.forEach((file) => {\n uploadFile(\n file.raw,\n `${import.meta.env.VITE_APP_AXIOS_BASE_URL}public/upload`,\n {\n success: (e: any) => {\n const { name, type } = e.data\n PeopleApi.importPeople(props.k, name, type).then((res) => {\n const { success, fail } = res.data\n ElMessage.success(`导入完成:${success}成功,${fail.length}失败`)\n if (fail.length > 0) {\n setTimeout(() => {\n ElMessage.info('自动开始下载未成功导入名单')\n tableToExcel(\n ['未成功导入名单'],\n fail.map((v: string) => [v]),\n `${props.name}_导入失败名单_${formatDate(\n new Date(),\n 'yyyy年MM月dd日hh时mm分ss秒',\n )}.xlsx`,\n )\n }, 1000)\n }\n clearFiles()\n })\n },\n },\n )\n })\n}\n// 添加文件\nfunction handleChangeFile(file: any) {\n if (file.raw.type !== 'text/plain') {\n ElMessage.warning({\n message: '只支持txt文件',\n zIndex: 4000,\n })\n clearFiles()\n }\n}\nfunction handleExportExcel() {\n if (peopleSubmitData.value.length === 0) {\n ElMessage.warning('表格中没有可导出数据')\n return\n }\n const headers = [\n '姓名',\n '提交状态',\n '提交数量',\n '最后操作时间',\n ...(checkMore.value ? ['现存数量', '提交次数'] : []),\n ]\n const body = peopleSubmitData.value.map((v) => {\n const { name, status, lastDate, submitCount, fileCount, count } = v\n return [\n name,\n status ? '✔' : 'x',\n submitCount,\n status ? formatDate(new Date(lastDate)) : '',\n ...(checkMore.value ? [fileCount, count] : []),\n ]\n })\n tableToExcel(\n headers,\n body,\n `${props.name}_提交情况_${formatDate(\n new Date(),\n 'yyyy年MM月dd日hh时mm分ss秒',\n )}.xlsx`,\n )\n ElMessage.success('导出成功')\n}\n\nconst isMobile = useIsMobile()\nconst importPanelInfo = reactive({\n taskList: [],\n type: 'override',\n taskValue: '',\n})\nconst showImportPanel = ref(false)\nasync function openImportPanel() {\n const taskKey = props.k\n // 通过任务Key获取可用任务列表,与概况信息\n const { data } = await PeopleApi.getUsefulTemplate(taskKey)\n importPanelInfo.taskList = data\n importPanelInfo.taskValue = data[0]?.taskKey || ''\n showImportPanel.value = true\n}\nconst ImportTaskTipMsg = computed(() => {\n const { taskList, taskValue } = importPanelInfo\n const task = taskList.find(v => v.taskKey === taskValue)\n if (!task) {\n return '无可用任务'\n }\n return `${task.count} 条数据`\n})\nfunction handleSaveImportInfo() {\n PeopleApi.importPeopleFromTpl(\n props.k,\n importPanelInfo.taskValue,\n importPanelInfo.type,\n ).then((res) => {\n showImportPanel.value = false\n const { success, fail } = res.data\n ElMessage.success(`导入成功${success}条,失败${fail.length}条`)\n\n if (fail.length > 0) {\n setTimeout(() => {\n ElMessage.info('自动开始下载未成功导入名单')\n tableToExcel(\n ['未成功导入名单'],\n fail.map((v: string) => [v]),\n `${props.name}_导入失败名单_${formatDate(\n new Date(),\n 'yyyy年MM月dd日hh时mm分ss秒',\n )}.xlsx`,\n )\n }, 1000)\n }\n })\n}\n\nconst importPanelFlexStyle = computed(() => (isMobile.value ? '0 0 auto' : 0.5))\n\nconst bindField = ref('姓名')\nwatch(\n () => props.field,\n (v) => {\n bindField.value = v\n },\n {\n immediate: true,\n },\n)\nfunction handleSureBind() {\n // 空值校验\n if (!bindField.value.trim().length) {\n ElMessage.warning('绑定的表单项不能为空')\n return\n }\n\n // 提交保存\n TaskApi.updateTaskMoreInfo(props.k, {\n bindField: bindField.value,\n }).then(() => {\n ElMessage.success('保存成功')\n })\n}\n</script>\n\n<template>\n <div class=\"config-panel info-panel\">\n <section class=\"panel-tip\">\n <div>\n <h4>限制名单</h4>\n <p>开启后,只有名单中的成员才可以提交文件,可通过文件、其它任务或手动方式维护名单。</p>\n </div>\n <Tip\n :imgs=\"[\n 'https://img.cdn.sugarat.top/mdImg/MTY1MDE4MzEwOTEzOQ==650183109139',\n 'https://img.cdn.sugarat.top/mdImg/MTY1MTQ5NjY3MTUyMw==651496671523',\n ]\"\n >\n 查看示例\n </Tip>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>名单校验</h4>\n <p>{{ people ? '当前已开启名单限制。' : '当前未开启名单限制,所有用户都可以提交。' }}</p>\n </div>\n <div class=\"header-actions\">\n <el-switch\n :model-value=\"Boolean(people)\"\n active-text=\"开启\"\n inactive-text=\"关闭\"\n @change=\"v => updateLimitPeople(Boolean(v))\"\n />\n <el-button v-if=\"people\" type=\"primary\" plain @click=\"checkPeople\">\n 查看提交情况\n </el-button>\n </div>\n </div>\n </section>\n\n <template v-if=\"people\">\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>名单导入</h4>\n <p>推荐大量名单使用文件导入,少量人员可直接手动添加。</p>\n </div>\n </div>\n <el-radio-group v-model=\"activeTab\" class=\"import-tabs\">\n <el-radio-button label=\"文件导入\" />\n <el-radio-button label=\"任务导入\" />\n <el-radio-button label=\"手动添加\" />\n </el-radio-group>\n\n <div class=\"import-people-wrapper\">\n <div v-show=\"activeTab === '文件导入'\" class=\"import-card\">\n <el-upload\n ref=\"peopleUpload\"\n v-model:file-list=\"peopleFileList\"\n accept=\"text/plain\"\n action=\"\"\n class=\"upload-demo\"\n :on-change=\"handleChangeFile\"\n :on-exceed=\"handleExceedFile\"\n :on-remove=\"clearFiles\"\n :auto-upload=\"false\"\n :limit=\"1\"\n >\n <template #trigger>\n <el-button type=\"primary\" plain>\n 选择文件\n </el-button>\n </template>\n <el-button\n class=\"upload-action\"\n type=\"success\"\n :disabled=\"!peopleFileList.length\"\n @click=\"submitUploadPeople\"\n >\n 确定上传\n </el-button>\n <template #tip>\n <div class=\"el-upload__tip\">\n <Tip\n :imgs=\"[\n 'https://img.cdn.sugarat.top/mdImg/MTY1MDE4Mjk2NjUxMA==650182966510',\n ]\"\n >\n 只能上传 .txt 文本文件,每行一个名字\n </Tip>\n <Tip>如名字有特殊字符,建议去除</Tip>\n <Tip>上传文件导入的方式,为追加导入,不会覆盖已存在数据</Tip>\n </div>\n </template>\n </el-upload>\n </div>\n <div v-show=\"activeTab === '任务导入'\" class=\"import-card\">\n <p>从已有任务中导入限制名单,可选择覆盖或追加。</p>\n <el-button type=\"success\" @click=\"openImportPanel\">\n 选择任务\n </el-button>\n </div>\n <div v-show=\"activeTab === '手动添加'\" class=\"import-card\">\n <el-input\n v-model=\"userInputName\"\n :disabled=\"importStatus\"\n placeholder=\"请输入姓名\"\n >\n <template #append>\n <el-button @click=\"handAddName\">\n 添加\n </el-button>\n </template>\n </el-input>\n <p>会自动判重,不会重复添加。大量名单优先推荐使用文件导入。</p>\n </div>\n </div>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>绑定表单项</h4>\n <p>与必填信息中的字段同名时,可避免用户重复填写。</p>\n </div>\n </div>\n <el-form class=\"bind-form\" label-width=\"100px\">\n <el-form-item label=\"字段名称\">\n <el-input v-model=\"bindField\" size=\"small\" clearable>\n <template #append>\n <el-button @click=\"handleSureBind\">\n 确定\n </el-button>\n </template>\n </el-input>\n </el-form-item>\n </el-form>\n </section>\n </template>\n\n <el-dialog v-model=\"showPeopleList\" :fullscreen=\"isMobile\" title=\"提交情况\">\n <!-- 上部分的筛选菜单 -->\n <div class=\"nav\">\n <div class=\"item\">\n <el-button\n :disabled=\"peopleList.length === 0\"\n type=\"success\"\n size=\"default\"\n @click=\"handleExportExcel\"\n >\n 导出记录\n </el-button>\n </div>\n <div class=\"item\">\n <el-select\n v-model=\"selectSubmitStatus\"\n size=\"default\"\n placeholder=\"状态筛选\"\n >\n <el-option label=\"全部\" value=\"all\" />\n <el-option label=\"已提交\" :value=\"1\" />\n <el-option label=\"未提交\" :value=\"0\" />\n </el-select>\n </div>\n <div class=\"item\">\n <el-input\n v-model=\"searchName\"\n size=\"default\"\n placeholder=\"输入要查询的姓名\"\n />\n </div>\n <div class=\"item\">\n <el-button type=\"primary\" size=\"default\" @click=\"handleCheckMore\">\n {{ checkMore ? '隐藏' : '显示' }}详细提交情况\n </el-button>\n </div>\n </div>\n <!-- 概况信息 -->\n <div class=\"tc p10\">\n <span>共: {{ peopleSubmitData.length }} 条数据</span>,\n <span>已提交: {{ peopleSubmitData.filter((v) => v.status).length }}</span>,\n <span>未提交: {{ peopleSubmitData.filter((v) => !v.status).length }}</span>\n </div>\n <div class=\"tc p10\">\n <Tip>\"提交次数\" 用户实际的提交次数</Tip>\n <Tip>\"现存数量\" 还存在于服务器上的文件数 (不包含删除) --- 慢查询</Tip>\n <Tip>\"提交数量\" 用户实际提交的文件数 (不包含撤回) --- 慢查询</Tip>\n </div>\n <!-- 数据部分 -->\n <el-table\n v-loading=\"isLoadingPeopleData\"\n element-loading-text=\"Loading...\"\n stripe\n border\n :data=\"peopleSubmitData\"\n height=\"460px\"\n >\n <el-table-column label=\"序号\" width=\"60\">\n <template #default=\"scope\">\n <div style=\"text-align: center\">\n {{ scope.$index + 1 }}\n </div>\n </template>\n </el-table-column>\n <el-table-column property=\"name\" label=\"姓名\" />\n <el-table-column label=\"提交状态\" width=\"100\">\n <template #default=\"scope\">\n <span v-if=\"scope.row.status\" class=\"submit-ok\">已提交</span>\n <span v-else class=\"submit-fail\">未提交</span>\n </template>\n </el-table-column>\n <el-table-column\n property=\"count\"\n label=\"提交次数\"\n width=\"94\"\n />\n <el-table-column\n sortable\n property=\"lastDate\"\n label=\"最后操作时间\"\n width=\"120\"\n />\n <template v-if=\"checkMore\">\n <el-table-column\n property=\"fileCount\"\n label=\"现存数量\"\n width=\"94\"\n />\n <el-table-column\n sortable\n property=\"submitCount\"\n label=\"提交数量\"\n width=\"120\"\n />\n </template>\n <el-table-column label=\"操作\" width=\"100\">\n <template #default=\"scope\">\n <el-button\n type=\"primary\"\n text\n size=\"small\"\n @click=\"handleDeletePeople(scope.row)\"\n >\n 删除\n </el-button>\n </template>\n </el-table-column>\n </el-table>\n </el-dialog>\n <el-dialog\n v-model=\"showImportPanel\"\n :fullscreen=\"isMobile\"\n title=\"人员列表导入\"\n >\n <el-form\n :model=\"importPanelInfo\"\n label-width=\"100px\"\n label-position=\"right\"\n >\n <el-form-item label=\"任务\">\n <el-select\n v-model=\"importPanelInfo.taskValue\"\n filterable\n placeholder=\"请选择\"\n no-data-text=\"无可用任务\"\n >\n <el-option\n v-for=\"t in importPanelInfo.taskList\"\n :key=\"t.taskKey\"\n :label=\"t.name\"\n :value=\"t.taskKey\"\n />\n </el-select>\n </el-form-item>\n <Tip>{{ ImportTaskTipMsg }}</Tip>\n <el-form-item label=\"任务\">\n <el-radio-group v-model=\"importPanelInfo.type\">\n <el-radio label=\"override\">\n 覆盖导入\n </el-radio>\n <el-radio label=\"add\">\n 追加导入\n </el-radio>\n </el-radio-group>\n </el-form-item>\n <Tip>\n {{\n importPanelInfo.type === 'override'\n ? '“覆盖导入” 将会覆盖原来的数据'\n : '“追加导入” 将只会导入不存在数据'\n }}\n </Tip>\n </el-form>\n <template #footer>\n <span class=\"dialog-footer\">\n <el-button @click=\"showImportPanel = false\">取 消</el-button>\n <el-button\n :disabled=\"!importPanelInfo.taskValue\"\n type=\"primary\"\n @click=\"handleSaveImportInfo\"\n >确 定</el-button>\n </span>\n </template>\n </el-dialog>\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.panel-tip,\n.setting-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.panel-tip,\n.setting-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n\n h4 {\n margin: 0;\n font-size: 16px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.panel-tip {\n background-color: #f8fbff;\n}\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.import-tabs {\n margin-top: 16px;\n}\n\n.import-people-wrapper {\n margin-top: 16px;\n}\n\n.import-card {\n padding: 16px;\n background-color: #fafcff;\n border: 1px solid #edf2f7;\n border-radius: 12px;\n\n p {\n margin: 0 0 12px;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.upload-action {\n margin-left: 10px;\n}\n\n.bind-form {\n max-width: 420px;\n margin-top: 16px;\n}\n\n.submit-ok {\n color: #67c23a;\n}\n\n.submit-fail {\n color: #f56c6c;\n}\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n padding-bottom: 5px;\n}\n\n.nav .item {\n margin-left: 10px;\n margin-top: 5px;\n}\n\n.info-panel :deep(.el-form-item__label) {\n flex: v-bind(importPanelFlexStyle);\n}\n\n.info-panel :deep(.el-upload-list__item-name) {\n justify-content: flex-start;\n}\n\n@media screen and (max-width: 700px) {\n .panel-tip,\n .setting-header,\n .header-actions {\n align-items: stretch;\n flex-direction: column;\n }\n\n .import-tabs {\n width: 100%;\n overflow-x: auto;\n }\n\n .upload-action {\n display: block;\n width: 100%;\n margin: 10px 0 0;\n }\n}\n</style>\n","<!-- eslint-disable ts/ban-ts-comment -->\n<script lang=\"ts\" setup>\nimport type { UploadProps, UploadUserFile } from 'element-plus'\nimport { Plus } from '@element-plus/icons-vue'\nimport { ElMessage } from 'element-plus'\nimport { computed, reactive, ref, watch } from 'vue'\nimport { FileApi, PublicApi, TaskApi } from '@/apis'\nimport { qiniuUpload } from '@/utils/networkUtil'\nimport { getTipImageKey } from '@/utils/stringUtil'\nimport { updateTaskInfo } from '../../public'\nimport Tip from './tip.vue'\n\nconst props = defineProps({\n tip: {\n type: String,\n default: '',\n required: false,\n },\n k: {\n type: String,\n default: '',\n },\n})\nconst textValue = ref('')\n\nconst tipData = reactive<{\n text: string\n imgs: {\n uid: number\n name: string\n }[]\n}>({\n text: '',\n imgs: [],\n})\nconst MaxImgCount = ref(3)\nconst imageList = ref<UploadUserFile[]>([])\nconst previewList = computed(() => {\n // @ts-expect-error\n return imageList.value.map(v => v!.preview || v.url)\n})\nconst previewIdx = ref(0)\n\nwatch(\n () => props.tip,\n () => {\n // 初始化\n try {\n const parseData = JSON.parse(props.tip)\n tipData.imgs = parseData.imgs\n tipData.text = parseData.text || ''\n imageList.value = tipData.imgs.map((v) => {\n return {\n ...v,\n url: 'https://img.cdn.sugarat.top/mdImg/MTY3NzkxMDI1NTU1Nw==20140524124237518.gif',\n }\n })\n if (imageList.value.length) {\n // 异步填充url\n PublicApi.getTipImageUrl(\n props.k,\n imageList.value.map(v => ({\n uid: v.uid,\n name: v.name,\n })),\n ).then((v) => {\n v.data.forEach((url, idx) => {\n imageList.value[idx].url = url.cover\n Object.assign(imageList.value[idx], {\n preview: url.preview,\n })\n })\n })\n }\n }\n catch {\n tipData.text = props.tip || ''\n tipData.imgs = []\n imageList.value = []\n }\n\n // 外部变动\n if (tipData.text) {\n textValue.value = tipData.text\n }\n else {\n textValue.value = ''\n }\n },\n {\n immediate: true,\n },\n)\nconst needSave = computed(() => tipData.text !== textValue.value)\n\n// 更新批注信息\nfunction updateTip(notify = true) {\n if (tipData.text !== textValue.value) {\n tipData.text = textValue.value\n }\n updateTaskInfo(props.k, { tip: JSON.stringify(tipData) }, notify)\n}\n\nconst imageViewerVisible = ref(false)\nfunction handleChangeFile(file: UploadUserFile) {\n if (!props.k) {\n return\n }\n const { name, uid } = file\n const key = getTipImageKey(props.k, name, uid)\n if (file.status === 'ready') {\n file.status = 'success'\n // qiniu上传\n FileApi.getUploadToken().then((res) => {\n qiniuUpload(res.data.token, file.raw, key, {\n success() {\n tipData.imgs.push({\n uid,\n name,\n })\n updateTip()\n },\n })\n })\n }\n}\nconst handleRemove: UploadProps['onRemove'] = (file) => {\n const { uid, name } = file\n const idx = tipData.imgs.findIndex(v => v.uid === uid)\n tipData.imgs.splice(idx, 1)\n updateTip()\n TaskApi.delTipImage(props.k, uid, name)\n}\n\nfunction handlePictureCardPreview(file) {\n imageViewerVisible.value = true\n const idx = imageList.value.findIndex(v => v.uid === file.uid)\n previewIdx.value = idx\n}\n// 超出选择的文件个数\nfunction handleExceedFile() {\n ElMessage.error(`只能选择${MaxImgCount.value}个图片,可删除后重新选择`)\n}\n</script>\n\n<template>\n <div class=\"config-panel\">\n <section class=\"panel-tip\">\n <div>\n <h4>提交页批注</h4>\n <p>用于在提交页展示说明、注意事项和图片提示,保存后建议打开预览确认展示效果。</p>\n </div>\n <Tip\n :imgs=\"[\n 'https://img.cdn.sugarat.top/mdImg/MTY1MTQ5NjI2OTI0MQ==651496269241',\n ]\"\n >\n 查看示例\n </Tip>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>文字说明</h4>\n <p>建议控制换行和字数,避免在移动端展示过长。</p>\n </div>\n <el-tag v-if=\"needSave\" type=\"warning\" effect=\"light\">\n 待保存\n </el-tag>\n </div>\n <el-input\n v-model=\"textValue\"\n class=\"tip-textarea\"\n :rows=\"7\"\n clearable\n :max=\"500\"\n show-word-limit\n type=\"textarea\"\n placeholder=\"请输入要展示的批注信息\"\n />\n <div class=\"actions\">\n <el-button type=\"success\" @click=\"updateTip\">\n 保存批注\n </el-button>\n <el-button type=\"danger\" plain @click=\"textValue = ''\">\n 清空\n </el-button>\n </div>\n </section>\n\n <section class=\"setting-card\">\n <div class=\"setting-header\">\n <div>\n <h4>图片说明</h4>\n <p>最多上传 3 张图片,适合补充截图、流程图或填写示例。</p>\n </div>\n <el-tag type=\"info\" effect=\"plain\">\n {{ imageList.length }}/{{ MaxImgCount }}\n </el-tag>\n </div>\n <el-upload\n v-model:file-list=\"imageList\"\n class=\"image-upload\"\n accept=\"image/*\"\n :limit=\"MaxImgCount\"\n action=\"\"\n list-type=\"picture-card\"\n :on-change=\"handleChangeFile\"\n :on-exceed=\"handleExceedFile\"\n :on-preview=\"handlePictureCardPreview\"\n :on-remove=\"handleRemove\"\n :auto-upload=\"false\"\n >\n <el-icon><Plus /></el-icon>\n </el-upload>\n </section>\n <ElImageViewer\n v-if=\"imageViewerVisible\"\n hide-on-click-modal\n :initial-index=\"previewIdx\"\n :url-list=\"previewList\"\n teleported\n @close=\"imageViewerVisible = false\"\n />\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.config-panel {\n display: grid;\n gap: 16px;\n}\n\n.panel-tip,\n.setting-card {\n padding: 18px;\n background-color: #fff;\n border: 1px solid #edf2f7;\n border-radius: 14px;\n}\n\n.panel-tip,\n.setting-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n\n h4 {\n margin: 0;\n font-size: 16px;\n color: #1f2d3d;\n }\n\n p {\n margin: 8px 0 0;\n font-size: 13px;\n color: #909399;\n line-height: 1.6;\n }\n}\n\n.panel-tip {\n background-color: #f8fbff;\n}\n\n.tip-textarea,\n.image-upload {\n margin-top: 16px;\n}\n\n.actions {\n display: flex;\n gap: 10px;\n justify-content: flex-end;\n margin-top: 16px;\n}\n\n@media screen and (max-width: 700px) {\n .panel-tip,\n .setting-header,\n .actions {\n align-items: stretch;\n flex-direction: column;\n }\n}\n</style>\n"],"names":["_sfc_main","defineComponent","name","_hoisted_1","viewBox","xmlns","_hoisted_3","createElementVNode","fill","d","plus","_export_sfc","_ctx","_cache","$props","$setup","$data","$options","openBlock","createElementBlock","updateTaskInfo","debounce","key","options","successInfo","TaskApi","updateTaskMoreInfo","then","ElMessage","success","message","zIndex","duration","catch","error","props","__props","newDate","ref","updateDDL","value","ddl","formatDate","Date","getTime","k","closeDDL","watchEffect","waitTime","isOver","computed","waitTimeStr","seconds","hour","day","minute","refreshWaitTime","loop","now","setTimeout","onMounted","formatData","reactive","getDefaultFormat","typeName","updateInfo","format","JSON","stringify","handleAddType","inputValue","split","map","v","trim","toLowerCase","includes","push","handleCopyType","copyRes","join","handleChangeLimit","limit","inputSize","unitList","handleChangeUnit","idx","findIndex","sizeUnit","size","handleLimitSize","Object","assign","parseFileFormat","status","splice","emit","__emit","openPreview","infoTypeList","label","selectType","siteConfig","useSiteConfig","maxInputLength","autoRewrite","infos","needSave","showAddInfo","length","formLength","watch","info","parseInfo","immediate","resFormat","text","splitChar","handleChange","rewrite","addInfo","infoList","type","list","t","item","children","deleteInfo","minLen","judgeInfoForm","items","every","saveInfo","warning","nextInfo","markInfoChanged","importPanelInfo","taskList","taskValue","showImportPanel","async","openImportPanel","taskKey","data","getUsefulTemplate","handleSaveImportInfo","usefulInfo","find","isMobile","useIsMobile","importPanelFlexStyle","showHelp","ElMessageBox","alert","dangerouslyUseHTMLString","handleChangeSplitChar","splitCharList","nextType","temp","_sfc_main$1","activeTab","userInputName","importStatus","handAddName","PeopleApi","addPeopleByUser","finally","checkMore","people","showPeopleList","peopleList","selectSubmitStatus","searchName","filterPeopleBySearchWord","filter","peopleSubmitData","p","isLoadingPeopleData","refreshSubmitData","getPeople","res","forEach","count","lastDate","handleCheckMore","checkPeople","peopleFileList","peopleUpload","handleExceedFile","clearFiles","submitUploadPeople","file","uploadFile","raw","e","importPeople","fail","tableToExcel","handleChangeFile","handleExportExcel","headers","body","submitCount","fileCount","ImportTaskTipMsg","task","importPeopleFromTpl","bindField","handleSureBind","field","confirm","deletePeople","id","components","Tip","String","default","setup","template","percentage","fileList","elUpload","deleteTemplate","FileApi","getUploadToken","qiniuUpload","token","process","per","class","_hoisted_4","_hoisted_5","_component_el_upload","__unplugin_components_1","_createElementVNode","_hoisted_2","_createVNode","_component_Tip","imgs","_withCtx","_createTextVNode","_toDisplayString","_openBlock","_component_el_button","disabled","plain","onClick","_","_createCommentVNode","_createElementBlock","$event","action","trigger","textValue","tipData","MaxImgCount","imageList","previewList","preview","url","previewIdx","tip","parseData","parse","PublicApi","getTipImageUrl","uid","cover","updateTip","notify","imageViewerVisible","getTipImageKey","handleRemove","delTipImage","handlePictureCardPreview"],"mappings":"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","x_google_ignoreList":[0]}