@utogether/udp-core 2.0.0-beta.1 → 2.0.0-beta.4

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 (248) hide show
  1. package/dist/{403-CTJDBjz7.js → 403-CekcmGOc.js} +3 -3
  2. package/dist/403-CxOqlq0f-C28ufSE6.js +65 -0
  3. package/dist/403-WCboRvzZ-ZAPgYStl-Ck7rlpC9.js +65 -0
  4. package/dist/404-2V0Qi-d7-DkNwQggp-3kilva5o.js +65 -0
  5. package/dist/{404-BFYkWIkQ.js → 404-DeSH9KnK.js} +1 -1
  6. package/dist/404-xdB6lFeQ-DRhUFuKU.js +65 -0
  7. package/dist/500-BYfzvixf-CGpEieyQ-DLrc9brB.js +67 -0
  8. package/dist/500-C94bRK2S-_XtNljMI.js +67 -0
  9. package/dist/{500-DGG3qadg.js → 500-DHOHlmtv.js} +2 -2
  10. package/dist/{AuthorityInfo-ozZIo1Te.js → AuthorityInfo-BC8U3Zk4.js} +1 -1
  11. package/dist/AuthorityInfo-DBovfUjB-DpQwT9Q5-ChKFxbGl.js +4 -0
  12. package/dist/AuthorityInfo-Dy3b_nFN-BBC0HKlV.js +4 -0
  13. package/dist/AuthorityInfo.vue_vue_type_style_index_0_lang-Bh7IbcdY-BgLN7Lgx.js +100 -0
  14. package/dist/AuthorityInfo.vue_vue_type_style_index_0_lang-D-l_Az3s-Cw7WmFxz-B8tPqh_7.js +100 -0
  15. package/dist/{AuthorityInfo.vue_vue_type_style_index_0_lang-DujerENw.js → AuthorityInfo.vue_vue_type_style_index_0_lang-DVFi0qOJ.js} +2 -2
  16. package/dist/AuthorityPanel-CRlAwbaI-G7pZXKdE-DAeYw45g.js +4 -0
  17. package/dist/AuthorityPanel-CRlAwbaI-G7pZXKdE.js +4 -0
  18. package/dist/AuthorityPanel.vue_vue_type_style_index_0_lang-DxhZjp1S-CJvk3pW8-C6jMEDJq.js +114 -0
  19. package/dist/AuthorityPanel.vue_vue_type_style_index_0_lang-DxhZjp1S-CJvk3pW8.js +114 -0
  20. package/dist/Company-B4vsXy2I-CkNCOqjJ-PjoD0ztY.js +25 -0
  21. package/dist/{Company-6VJtwh23.js → Company-Byq4p14C.js} +3 -3
  22. package/dist/Company-gKkfnhLt-BReGxz7n.js +25 -0
  23. package/dist/CompanyPanel-BF5Pc35s-CtpymP6a.js +206 -0
  24. package/dist/{CompanyPanel-B2P488mq.js → CompanyPanel-CIHP7rVd.js} +7 -7
  25. package/dist/CompanyPanel-Czcx8Gyw-CvndXwB_-mYpxegRQ.js +206 -0
  26. package/dist/DataSet-DT-rGICv-DaUfgbxk-YztlXv7w.js +147 -0
  27. package/dist/DataSet-DT-rGICv-DaUfgbxk.js +147 -0
  28. package/dist/{Department-BnwoLEOC.js → Department-CxgSq34X.js} +3 -3
  29. package/dist/Department-D0I3QVZe-CfWPT-lY.js +25 -0
  30. package/dist/Department-D0dVUrGC-C6HJcYI1-DhAtBQym.js +25 -0
  31. package/dist/DepartmentPanel-2LHODgc7--VCCaEsu.js +254 -0
  32. package/dist/DepartmentPanel-e91Lxr1j-BS_A-ILd-V3QvVWmJ.js +254 -0
  33. package/dist/{DepartmentPanel-CRrrmxtv.js → DepartmentPanel-hYNqywSQ.js} +22 -22
  34. package/dist/DesignPanel-CtF3cAAQ-FM7zpexb.js +4 -0
  35. package/dist/DesignPanel-DdFl_ohi-uCwFxcl1-7p3ouXrw.js +4 -0
  36. package/dist/{DesignPanel-CvbccgX2.js → DesignPanel-GEhqXIAx.js} +1 -1
  37. package/dist/DesignPanel.vue_vue_type_style_index_0_lang-BACPrfUI-cC7yL0uY-CoM_RAUN.js +1013 -0
  38. package/dist/DesignPanel.vue_vue_type_style_index_0_lang-BCYgwoVt-CcCVpy0f.js +1013 -0
  39. package/dist/{DesignPanel.vue_vue_type_style_index_0_lang-Dz2tUszs.js → DesignPanel.vue_vue_type_style_index_0_lang-DxA6H5Ts.js} +3 -3
  40. package/dist/DictView-BzQLOf_P-DDicwdmM-B8CFC279.js +111 -0
  41. package/dist/DictView-H3V5hxg3-BQZWN2zT.js +111 -0
  42. package/dist/{DictView-Ce1LoVHh.js → DictView-tyGrHFO8.js} +1 -1
  43. package/dist/InvOrganization-BiGLnbqe-BK3vgYYR.js +74 -0
  44. package/dist/{InvOrganization-BwCFZO1X.js → InvOrganization-DjJ4XkxN.js} +2 -2
  45. package/dist/InvOrganization-atbhw0CI-BABbVt9V-BT8PkfWL.js +74 -0
  46. package/dist/{Org-0hzs6b0R.js → Org-3eHX7nBU.js} +2 -2
  47. package/dist/Org-BW1YHG-Q-Cow7JWlD-C7ygI7jx.js +39 -0
  48. package/dist/Org-DQTCQHNY-CEEpGGlZ.js +39 -0
  49. package/dist/{Preview--DnEAhwh.js → Preview-Cgc3O8vp.js} +1 -1
  50. package/dist/Preview-DJtVsoq1-CCGidQjJ-DQ_OC1-S.js +48 -0
  51. package/dist/Preview-DXaiis29-BYyNhC1p.js +48 -0
  52. package/dist/ReportDefine-BLh4CiER-D68a0DWB.js +10 -0
  53. package/dist/ReportDefine-CNx_ob99-6NQAHK-Q-BL5gB56o.js +10 -0
  54. package/dist/{ReportDefine-Cu983bTN.js → ReportDefine-FYxHLbPV.js} +1 -1
  55. package/dist/{ReportDesign-QsWXXgvo.js → ReportDesign-BTOVgMzz.js} +7 -7
  56. package/dist/ReportDesign-FbQ6yTJS-C1pPAUSp-DTsrU_wq.js +165 -0
  57. package/dist/ReportDesign-Ni1YxrLC-DfziOJc3.js +165 -0
  58. package/dist/ReportQuery-C5gz8Lgd-Eu2cQmda-c9iy6TZ_.js +75 -0
  59. package/dist/ReportQuery-C8G88_qF-BKknwX1u.js +75 -0
  60. package/dist/{ReportQuery-BjKIIhPu.js → ReportQuery-Dhy9sk04.js} +1 -1
  61. package/dist/{ReportQueryFrom-DIjBO6Fx.js → ReportQueryFrom-B1TE8lOG.js} +1 -1
  62. package/dist/ReportQueryFrom-C7scua5v-uHXWq8Gy-Cq4havLh.js +4 -0
  63. package/dist/ReportQueryFrom-CuZKPtB4-B_TaZr-N.js +4 -0
  64. package/dist/ReportQueryFrom.vue_vue_type_style_index_0_lang-BAn_siFW-CdTqG6KF.js +178 -0
  65. package/dist/{ReportQueryFrom.vue_vue_type_style_index_0_lang-0T62cUMK.js → ReportQueryFrom.vue_vue_type_style_index_0_lang-D93NL2N7.js} +7 -7
  66. package/dist/ReportQueryFrom.vue_vue_type_style_index_0_lang-DCbz67Wa-vK6r2uCl-kdXwDD3n.js +178 -0
  67. package/dist/ReportTemplate-BDANdIWv-D_IGjR1w-txJDRw_J.js +161 -0
  68. package/dist/{ReportTemplate-2uk9tJcy.js → ReportTemplate-C-EuU7mL.js} +8 -8
  69. package/dist/ReportTemplate-DFnDXWmx-QQkaZRvV.js +161 -0
  70. package/dist/Role-BQ7hsfPn-BLwTiMMj.js +25 -0
  71. package/dist/Role-ByB0WbxW-5E8Mb148-WoZV4JKV.js +25 -0
  72. package/dist/{Role-_QP8QEaI.js → Role-Dc1dZ0o9.js} +3 -3
  73. package/dist/{RoleAssign-C2gkcmEQ.js → RoleAssign-DDv65izq.js} +3 -3
  74. package/dist/RoleAssign-DW6iC_0v-Bis61auk-BB4DziuB.js +26 -0
  75. package/dist/RoleAssign-UPCg2d4G-g4V-duK9.js +26 -0
  76. package/dist/RolePanel-BM2MaQPU-CgcsbfaX-D28vR3Fh.js +4 -0
  77. package/dist/RolePanel-C-mQ5XRq-JQYWITkX.js +4 -0
  78. package/dist/{RolePanel-vnl_lXNY.js → RolePanel-CiDM8OSr.js} +1 -1
  79. package/dist/RolePanel-ClQy8DBL-DARL4O-o-DrElGZ66.js +4 -0
  80. package/dist/RolePanel-CoSXOCZN-BdCEhz3b.js +4 -0
  81. package/dist/{RolePanel-B8FPNGaA.js → RolePanel-Dw_pTEGV.js} +1 -1
  82. package/dist/RolePanel.vue_vue_type_script_setup_true_lang-Bc_Ao_PU-DMmxr2iI-Bsk0Mun8.js +132 -0
  83. package/dist/RolePanel.vue_vue_type_script_setup_true_lang-Bg-t2UhF-CMTLt3Lp.js +154 -0
  84. package/dist/{RolePanel.vue_vue_type_script_setup_true_lang-bxHXrBYl.js → RolePanel.vue_vue_type_script_setup_true_lang-CG_KY7NS.js} +7 -7
  85. package/dist/{RolePanel.vue_vue_type_script_setup_true_lang-BuQbYEEI.js → RolePanel.vue_vue_type_script_setup_true_lang-Ctq1lItN.js} +8 -8
  86. package/dist/RolePanel.vue_vue_type_script_setup_true_lang-D-o7HYZ8-DPs8J-8D.js +132 -0
  87. package/dist/RolePanel.vue_vue_type_script_setup_true_lang-fthF1zkp-JsbQJoDy-vZfwM6bG.js +154 -0
  88. package/dist/ScrollPanel.vue_vue_type_style_index_0_lang-ByWIwajm-BsBf2Vs3-CTeY23xN.js +100 -0
  89. package/dist/ScrollPanel.vue_vue_type_style_index_0_lang-CCsoxDfk-D-4pB58A.js +100 -0
  90. package/dist/{ScrollPanel.vue_vue_type_style_index_0_lang-C6yZXBqB.js → ScrollPanel.vue_vue_type_style_index_0_lang-CyU7XjI3.js} +1 -1
  91. package/dist/Staff-CuxzvhD9-D0KTcyRh-Cj8NbX79.js +25 -0
  92. package/dist/Staff-D-CmvG1R-uwSWH8-m.js +25 -0
  93. package/dist/{Staff-CHWrMIEb.js → Staff-DMh451jL.js} +3 -3
  94. package/dist/{StaffInfo-Cpq2eayz.js → StaffInfo-2PhYcVaz.js} +1 -1
  95. package/dist/StaffInfo-CY7gUICu-EZUhUwIp-C8POP58u.js +4 -0
  96. package/dist/StaffInfo-Idhvuc6e-COVQmEz0.js +4 -0
  97. package/dist/{StaffInfo.vue_vue_type_script_setup_true_lang-BVCjF2i1.js → StaffInfo.vue_vue_type_script_setup_true_lang-CrCFms3g.js} +1 -1
  98. package/dist/StaffInfo.vue_vue_type_script_setup_true_lang-Dd8gtQz8-Dlkt-eCn-p0kltEdZ.js +108 -0
  99. package/dist/StaffInfo.vue_vue_type_script_setup_true_lang-MUGKjnHU-Cj9lcXG6.js +108 -0
  100. package/dist/{StaffPanel-D2BMXt5p.js → StaffPanel-BrvkXT68.js} +1 -1
  101. package/dist/StaffPanel-CDDmAYE5-mLPGD2Nf.js +4 -0
  102. package/dist/StaffPanel-CwqG0_xr-CrvzLJoc-AX54GdZ3.js +4 -0
  103. package/dist/StaffPanel.vue_vue_type_script_setup_true_lang-Bdilqbee-RiBDcMMj.js +143 -0
  104. package/dist/StaffPanel.vue_vue_type_script_setup_true_lang-DCdBy8Hu-BXrueqi0-DFG90qAT.js +143 -0
  105. package/dist/{StaffPanel.vue_vue_type_script_setup_true_lang-B6jAGo-g.js → StaffPanel.vue_vue_type_script_setup_true_lang-DKr8VVOJ.js} +42 -42
  106. package/dist/SysUser-9Q2UJWhi-DprWXFlR-DUMl4Hfm.js +15 -0
  107. package/dist/{SysUser-om6H1BeC.js → SysUser-DLDd5do7.js} +2 -2
  108. package/dist/SysUser-a-j5bppr-CpP0s5DW.js +15 -0
  109. package/dist/SysUserPanel-6V232wwB-DI8apzmL.js +4 -0
  110. package/dist/{SysUserPanel-CH0HPP7h.js → SysUserPanel-DDQxi2Hk.js} +1 -1
  111. package/dist/SysUserPanel-bJy69O7x-BJtBgFEs-DEXctwBe.js +4 -0
  112. package/dist/SysUserPanel.vue_vue_type_script_setup_true_lang-BOtHuMVy-CD9JQp9h.js +356 -0
  113. package/dist/SysUserPanel.vue_vue_type_script_setup_true_lang-DUPFqgz3-BSqRCMen-BBtBr0VU.js +356 -0
  114. package/dist/{SysUserPanel.vue_vue_type_script_setup_true_lang-Dpl13ee0.js → SysUserPanel.vue_vue_type_script_setup_true_lang-DvOggZs6.js} +2 -2
  115. package/dist/SystemMenu-BnVeOSOQ-6HW3jX57.js +156 -0
  116. package/dist/SystemMenu-DGOAolc1-CJSLHP8i-DIUNb03s.js +156 -0
  117. package/dist/{SystemMenu-BkG_DKxA.js → SystemMenu-nFNfz4Nj.js} +7 -7
  118. package/dist/{UserInfo-D9croxUe.js → UserInfo-B9PLKur5.js} +1 -1
  119. package/dist/UserInfo-CKoOHkAM-DDWp0I_U-DEerO-y3.js +4 -0
  120. package/dist/UserInfo-Cax9b2nw-DBResyaY.js +4 -0
  121. package/dist/UserInfo.vue_vue_type_style_index_0_lang-BaT53SSu-DsNaAomO-7IKIrGoq.js +160 -0
  122. package/dist/{UserInfo.vue_vue_type_style_index_0_lang-DLIP8xpN.js → UserInfo.vue_vue_type_style_index_0_lang-BwZNwtQH.js} +2 -2
  123. package/dist/UserInfo.vue_vue_type_style_index_0_lang-D-cw11i9-B2nI6TLi.js +160 -0
  124. package/dist/await-to-js.es5-Bv3Eu4mi-UCggJjes-CRQnmLCs.js +10 -0
  125. package/dist/await-to-js.es5-Bv3Eu4mi-UCggJjes.js +10 -0
  126. package/dist/await-to-js.es5-Bv3Eu4mi.js +10 -0
  127. package/dist/childView-0YZQ6GBn-CEqg7k5d-CDGM_XzZ.js +4 -0
  128. package/dist/{childView-BY_Ip-l1.js → childView-BEDVB_RG.js} +1 -1
  129. package/dist/{childView-CHp_TueS.js → childView-BRa268Qh.js} +1 -1
  130. package/dist/childView-DKG3eZo8-CCtKjCU7.js +4 -0
  131. package/dist/childView-DKkgi3yo-D47ft-vi-B5yI8Dk7.js +4 -0
  132. package/dist/childView-siumuBz0-CyYKsSPy.js +4 -0
  133. package/dist/childView.vue_vue_type_style_index_0_lang-ABMrGInv-ClOdE_sa-BnvsyZ35.js +143 -0
  134. package/dist/{childView.vue_vue_type_style_index_0_lang-BNHbDRjt.js → childView.vue_vue_type_style_index_0_lang-BcyosNSH.js} +8 -8
  135. package/dist/childView.vue_vue_type_style_index_0_lang-CUfXDS1q-DNNy6Qe3.js +180 -0
  136. package/dist/childView.vue_vue_type_style_index_0_lang-CW3EbAmW-D6Jvom5y.js +143 -0
  137. package/dist/childView.vue_vue_type_style_index_0_lang-CaW106ve-CClTM8PK-ZSgCqafc.js +180 -0
  138. package/dist/{childView.vue_vue_type_style_index_0_lang-CbjGf7Z7.js → childView.vue_vue_type_style_index_0_lang-qsceJGeR.js} +8 -8
  139. package/dist/{code-rule-Ce6yWqCq.js → code-rule-CJ4FuOo1.js} +2 -2
  140. package/dist/code-rule-Dtoree6F-B4yeNvFw.js +148 -0
  141. package/dist/code-rule-wQyfgpNL-C4evD4Co-BOJCC1LY.js +148 -0
  142. package/dist/core.es.js +10 -10
  143. package/dist/cron-task-C-kryDtd-C0NuGZCe-DIJuoNx-.js +135 -0
  144. package/dist/{cron-task-DziaH0rI.js → cron-task-CXnv7hIa.js} +2 -2
  145. package/dist/cron-task-GSRgA7S5-D_xfN2g_.js +135 -0
  146. package/dist/flow-task-B07st2aD-CgQvagSQ-BaPlX6ds.js +10 -0
  147. package/dist/flow-task-B07st2aD-CgQvagSQ.js +10 -0
  148. package/dist/frameView-BOGA3ezf-QoSxzmSQ-BWs9F5mT.js +44 -0
  149. package/dist/frameView-Cy6wxW0K-BLdNZaGh.js +44 -0
  150. package/dist/{frameView-DNeCVQaY.js → frameView-g5e9PYdE.js} +1 -1
  151. package/dist/{index-BabfUVv_.js → index-BEAth5RR.js} +1057 -1033
  152. package/dist/layout-home-3Dy4onl4-COK554mq.js +228 -0
  153. package/dist/layout-home-CYHksXN_-Basy-3IH-Dnun4YUs.js +228 -0
  154. package/dist/layout-home-bl3JShSF.js +232 -0
  155. package/dist/layoutView-BaRvAbIa-xVgfqspc-zL46XaoI.js +3302 -0
  156. package/dist/layoutView-DMjNscJ--DvK2S5BQ.js +3302 -0
  157. package/dist/{layoutView-12Mlp9A2.js → layoutView-DmM9xk-X.js} +8 -8
  158. package/dist/log-in-Cx1dGik8-BVeEHeZ8-D7mV8pl4.js +117 -0
  159. package/dist/log-in-VAG6Cvcx-B6arurXx.js +117 -0
  160. package/dist/{log-in-1NGaA5OM.js → log-in-eGoxFTDE.js} +8 -8
  161. package/dist/log-out-COYdxrNC-ftopGZdE-Ch_UgXZv.js +130 -0
  162. package/dist/{log-out-B8_atGcQ.js → log-out-CthD_tSk.js} +4 -4
  163. package/dist/log-out-DZGaMCjC-OztBlMPh.js +130 -0
  164. package/dist/login-CqVMdNHs-CRJ-LWAK.js +241 -0
  165. package/dist/login-Dg9ofNS8-Bocp1XMA-DY4y3cAG.js +241 -0
  166. package/dist/{login-5dydO6GR.js → login-Dn7iO3SU.js} +16 -16
  167. package/dist/login-log-DJBGJVV0-AoOyj0jD-AoOyj0jD.js +70 -0
  168. package/dist/login-log-DJBGJVV0-AoOyj0jD.js +70 -0
  169. package/dist/{lov-view-DPvGUu3h.js → lov-view-Bt23RK6S.js} +7 -7
  170. package/dist/lov-view-C0T5prk8-B2DBmn55-BvzOsVW8.js +97 -0
  171. package/dist/lov-view-Cc68_28B-y4f2SzBr.js +97 -0
  172. package/dist/{menuInfo-DVADYfEK.js → menuInfo-BEmcSaIX.js} +1 -1
  173. package/dist/menuInfo-BIrIaJlH-Bxn4KTWH.js +4 -0
  174. package/dist/menuInfo-BZJ_q7bz-Drho-_QC-BK5n3Shr.js +4 -0
  175. package/dist/menuInfo.vue_vue_type_style_index_0_lang-BA8xjUo3-BCZ1wipf-DEApwWGK.js +363 -0
  176. package/dist/{menuInfo.vue_vue_type_style_index_0_lang-DgsifDrm.js → menuInfo.vue_vue_type_style_index_0_lang-CVuG-x2a.js} +2 -2
  177. package/dist/menuInfo.vue_vue_type_style_index_0_lang-DlE4w35X-gWYo2VJe.js +363 -0
  178. package/dist/{pda-app-BZXs-2BQ.js → pda-app-BKfXoKAs.js} +9 -9
  179. package/dist/pda-app-DnjphrRS-4tIZDsnN.js +710 -0
  180. package/dist/pda-app-m9hsppHo-B4xyja1o-9mD3zI7J.js +710 -0
  181. package/dist/redirect-BqegffKC-CBCIuqmz-46JkXpSM.js +15 -0
  182. package/dist/redirect-BqegffKC-CBCIuqmz.js +15 -0
  183. package/dist/resource-C6KEIXu--B_ddyecm-CFF-A4cr.js +97 -0
  184. package/dist/{resource-BZA9NFKc.js → resource-CshrvEYp.js} +4 -4
  185. package/dist/resource-DISgPDM7-C4P8jqU0.js +97 -0
  186. package/dist/su-welcome-BjbuSrBZ-DrInu823.js +49339 -0
  187. package/dist/su-welcome-CYYy-dzr-D3RKPoB0-DhP783YJ.js +42089 -0
  188. package/dist/su-welcome-t7YusM3U.js +49427 -0
  189. package/dist/sys-config-DCjJGtht-DARDjlrt-Dx8559bf.js +370 -0
  190. package/dist/{sys-config-DQmNjWH4.js → sys-config-Jqj3l7NK.js} +13 -13
  191. package/dist/sys-config-Yc9vh1t1-B3bJPd9S.js +370 -0
  192. package/dist/udp-core.css +1 -1
  193. package/dist/utogether-MlnyYtNS-CGgjFNPS-CGgjFNPS.js +4 -0
  194. package/dist/utogether-MlnyYtNS-CGgjFNPS.js +4 -0
  195. package/package.json +5 -2
  196. package/src/App.vue +71 -71
  197. package/src/components/udp/content/index.vue +88 -88
  198. package/src/components/udp/form-upload/form-upload.vue +492 -492
  199. package/src/components/udp/grid/index.vue +524 -524
  200. package/src/components/udp/index.ts +6 -6
  201. package/src/components/udp/ut-stamp-badge/index.vue +271 -271
  202. package/src/components/udp/utils.ts +408 -408
  203. package/src/layout/components/lay-content/index.vue +136 -136
  204. package/src/layout/components/lay-search/components/SearchModal.vue +181 -189
  205. package/src/layout/components/lay-setting/index.vue +503 -503
  206. package/src/layout/components/lay-sidebar/sidebar-logo.vue +101 -101
  207. package/src/layout/components/lay-tag/index.vue +598 -598
  208. package/src/layout/hooks/useNav.ts +176 -176
  209. package/src/layout/hooks/useTag.ts +227 -227
  210. package/src/layout/layoutView.vue +216 -216
  211. package/src/layout/types.ts +93 -93
  212. package/src/main.ts +111 -112
  213. package/src/plugins/i18n/zh.ts +1 -0
  214. package/src/plugins/vxe-table/index.ts +116 -116
  215. package/src/plugins/vxe-table/render.tsx +968 -968
  216. package/src/router/index.ts +187 -187
  217. package/src/router/modules/home.ts +32 -32
  218. package/src/router/utils.ts +420 -420
  219. package/src/store/modules/epTheme.ts +48 -48
  220. package/src/style/vxetable.scss +364 -356
  221. package/src/utils/dataFormat/index.ts +222 -222
  222. package/src/utils/lifecycle.ts +39 -39
  223. package/src/views/organization/department/DepartmentPanel.vue +303 -303
  224. package/src/views/organization/staff/StaffInfo.vue +127 -127
  225. package/src/views/organization/staff/StaffPanel.vue +3 -3
  226. package/src/views/system/layout/layout-home.vue +46 -7
  227. package/src/views/system/menu/AuthorityPanel.vue +141 -141
  228. package/src/views/system/menu/SystemMenu.vue +194 -194
  229. package/src/views/system/menu/menuInfo.vue +1 -1
  230. package/src/views/system/sysUser/SysUserPanel.vue +363 -363
  231. package/src/views/udev/coderule/code-rule.vue +132 -132
  232. package/src/views/udev/dict/DictView.vue +118 -118
  233. package/src/views/udev/dict/childView.vue +184 -184
  234. package/src/views/udev/lov/childView.vue +174 -174
  235. package/src/views/uhome/components/common-menu.vue +118 -0
  236. package/src/views/uhome/components/dynamic-component.vue +66 -0
  237. package/src/views/uhome/components/home-todo.vue +171 -0
  238. package/src/views/uhome/components/menu-favorite.vue +315 -315
  239. package/src/views/uhome/dynamic-card.vue +18 -19
  240. package/src/views/uhome/su-welcome.vue +47 -117
  241. package/src/views/ulogin/login.vue +336 -336
  242. package/src/views/upms/interface/log-in.vue +100 -100
  243. package/src/views/upms/interface/log-out.vue +104 -104
  244. package/src/views/upms/user/login-log.vue +54 -54
  245. package/types/global.d.ts +232 -232
  246. package/dist/await-to-js.es5-BtRbN2QH.js +0 -10
  247. package/dist/layout-home-Cis1KlEr.js +0 -195
  248. package/dist/su-welcome-BXe6Cdp3.js +0 -580
@@ -1,598 +1,598 @@
1
- <script lang="ts">
2
- export default { name: 'LayoutTag' };
3
- </script>
4
- <script setup lang="ts">
5
- import { ref, watch, unref, nextTick, onBeforeUnmount } from 'vue';
6
- import { isEqual, isEmpty } from 'xe-utils';
7
- import { useResizeObserver, useDebounceFn, useFullscreen, onClickOutside } from '@vueuse/core';
8
- import { delay } from '@utogether/utils';
9
- import { emitter } from '../../../utils/mitt';
10
- import { routerArrays } from '../../types';
11
- import { useSettingStoreHook } from '../../../store/modules/settings';
12
- import { handleAliveRoute, getTopMenu } from '../../../router/utils';
13
- import { useMultiTagsStoreHook } from '../../../store/modules/multiTags';
14
- import { usePermissionStoreHook } from '../../../store/modules/permission';
15
- import { useTags } from '../../hooks/useTag';
16
- import { RouteConfigs } from '../../types';
17
- import TagChrome from '../lay-chrome/index.vue';
18
-
19
- const {
20
- route,
21
- router,
22
- visible,
23
- showTags,
24
- instance,
25
- multiTags,
26
- tagsViews,
27
- buttonTop,
28
- buttonLeft,
29
- showModel,
30
- translateX,
31
- isFixedTag,
32
- SuSetting,
33
- activeIndex,
34
- getTabStyle,
35
- iconIsActive,
36
- linkIsActive,
37
- currentSelect,
38
- scheduleIsActive,
39
- getContextMenuStyle,
40
- closeMenu,
41
- onMounted,
42
- onMouseenter,
43
- onMouseleave,
44
- transformI18n,
45
- onContentFullScreen
46
- } = useTags();
47
-
48
- const suSetting = useSettingStoreHook();
49
- const tabDom = ref();
50
- const containerDom = ref();
51
- const scrollbarDom = ref();
52
- const contextmenuRef = ref();
53
- const isShowArrow = ref(false);
54
- const topPath = getTopMenu()?.path;
55
- const { isFullscreen, toggle } = useFullscreen();
56
-
57
- const fixedTags = [...routerArrays, ...usePermissionStoreHook().flatteningRoutes.filter(v => v?.meta?.fixedTag)];
58
- const dynamicTagView = async () => {
59
- await nextTick();
60
- const index = multiTags.value.findIndex(item => {
61
- if (!isEmpty(route.query)) {
62
- return isEqual(route.query, item.query);
63
- } else if (!isEmpty(route.params)) {
64
- return isEqual(route.params, item.params);
65
- } else {
66
- return route.path === item.path;
67
- }
68
- });
69
- moveToView(index);
70
- };
71
-
72
- const moveToView = async (index: number): Promise<void> => {
73
- await nextTick();
74
- const tabNavPadding = 10;
75
- if (!instance.refs['dynamic' + index]) return;
76
- const tabItemEl = instance.refs['dynamic' + index][0];
77
- const tabItemElOffsetLeft = (tabItemEl as HTMLElement)?.offsetLeft;
78
- const tabItemOffsetWidth = (tabItemEl as HTMLElement)?.offsetWidth;
79
- // 标签页导航栏可视长度(不包含溢出部分)
80
- const scrollbarDomWidth = scrollbarDom.value ? scrollbarDom.value.offsetWidth : 0;
81
- // 已有标签页总长度(包含溢出部分)
82
- const tabDomWidth = tabDom.value ? tabDom.value?.offsetWidth : 0;
83
- scrollbarDomWidth <= tabDomWidth ? (isShowArrow.value = true) : (isShowArrow.value = false);
84
- if (tabDomWidth < scrollbarDomWidth || tabItemElOffsetLeft === 0) {
85
- translateX.value = 0;
86
- } else if (tabItemElOffsetLeft < -translateX.value) {
87
- // 标签在可视区域左侧
88
- translateX.value = -tabItemElOffsetLeft + tabNavPadding;
89
- } else if (
90
- tabItemElOffsetLeft > -translateX.value &&
91
- tabItemElOffsetLeft + tabItemOffsetWidth < -translateX.value + scrollbarDomWidth
92
- ) {
93
- // 标签在可视区域
94
- translateX.value = Math.min(0, scrollbarDomWidth - tabItemOffsetWidth - tabItemElOffsetLeft - tabNavPadding);
95
- } else {
96
- // 标签在可视区域右侧
97
- translateX.value = -(tabItemElOffsetLeft - (scrollbarDomWidth - tabNavPadding - tabItemOffsetWidth));
98
- }
99
- };
100
-
101
- const handleScroll = (offset: number): void => {
102
- const scrollbarDomWidth = scrollbarDom.value ? scrollbarDom.value?.offsetWidth : 0;
103
- const tabDomWidth = tabDom.value ? tabDom.value.offsetWidth : 0;
104
- if (offset > 0) {
105
- translateX.value = Math.min(0, translateX.value + offset);
106
- } else {
107
- if (scrollbarDomWidth < tabDomWidth) {
108
- if (translateX.value >= -(tabDomWidth - scrollbarDomWidth)) {
109
- translateX.value = Math.max(translateX.value + offset, scrollbarDomWidth - tabDomWidth);
110
- }
111
- } else {
112
- translateX.value = 0;
113
- }
114
- }
115
- };
116
-
117
- function dynamicRouteTag(value: string): void {
118
- const hasValue = multiTags.value.some(item => {
119
- return item.path === value;
120
- });
121
-
122
- function concatPath(arr: object[], value: string) {
123
- if (!hasValue) {
124
- arr.forEach((arrItem: any) => {
125
- if (arrItem.path === value) {
126
- useMultiTagsStoreHook().handleTags('push', {
127
- path: value,
128
- meta: arrItem.meta,
129
- name: arrItem.name
130
- });
131
- } else {
132
- if (arrItem.children && arrItem.children.length > 0) {
133
- concatPath(arrItem.children, value);
134
- }
135
- }
136
- });
137
- }
138
- }
139
- concatPath(router.options.routes as any, value);
140
- }
141
-
142
- /** 刷新路由 */
143
- function onFresh() {
144
- const { fullPath, query } = unref(route);
145
- router.replace({
146
- path: '/redirect' + fullPath,
147
- query: query
148
- });
149
- handleAliveRoute(route as ToRouteType, 'refresh');
150
- }
151
-
152
- function deleteDynamicTag(obj: any, current: any, tag?: string) {
153
- const valueIndex: number = multiTags.value.findIndex((item: any) => {
154
- if (item.query) {
155
- if (item.path === obj.path) {
156
- return item.query === obj.query;
157
- }
158
- } else if (item.params) {
159
- if (item.path === obj.path) {
160
- return item.params === obj.params;
161
- }
162
- } else {
163
- return item.path === obj.path;
164
- }
165
- });
166
-
167
- const spliceRoute = (startIndex?: number, length?: number, other?: boolean): void => {
168
- if (other) {
169
- useMultiTagsStoreHook().handleTags('equal', [fixedTags, obj].flat());
170
- } else {
171
- useMultiTagsStoreHook().handleTags('splice', '', {
172
- startIndex,
173
- length
174
- }) as any;
175
- }
176
- dynamicTagView();
177
- };
178
-
179
- if (tag === 'other') {
180
- spliceRoute(1, 1, true);
181
- } else if (tag === 'left') {
182
- spliceRoute(fixedTags.length, valueIndex - fixedTags.length);
183
- } else if (tag === 'right') {
184
- spliceRoute(valueIndex + 1, multiTags.value.length);
185
- } else {
186
- // 从当前匹配到的路径中删除
187
- spliceRoute(valueIndex, 1);
188
- }
189
- const newRoute = useMultiTagsStoreHook().handleTags('slice');
190
- if (current === route.path) {
191
- // 如果删除当前激活tag就自动切换到最后一个tag
192
- if (tag === 'left') return;
193
- if (newRoute[0]?.query) {
194
- router.push({ name: newRoute[0].name, query: newRoute[0].query });
195
- } else if (newRoute[0]?.params) {
196
- router.push({ name: newRoute[0].name, params: newRoute[0].params });
197
- } else {
198
- router.push({ path: newRoute[0].path });
199
- }
200
- } else {
201
- if (!multiTags.value.length) return;
202
- if (multiTags.value.some(item => item.path === route.path)) return;
203
- if (newRoute[0]?.query) {
204
- router.push({ name: newRoute[0].name, query: newRoute[0].query });
205
- } else if (newRoute[0]?.params) {
206
- router.push({ name: newRoute[0].name, params: newRoute[0].params });
207
- } else {
208
- router.push({ path: newRoute[0].path });
209
- }
210
- }
211
- }
212
-
213
- function deleteMenu(item, tag?: string) {
214
- deleteDynamicTag(item, item.path, tag);
215
- handleAliveRoute(route as ToRouteType);
216
- }
217
-
218
- function onClickDrop(key, item, selectRoute?: RouteConfigs) {
219
- if (item && item.disabled) return;
220
- let selectTagRoute;
221
- if (selectRoute) {
222
- selectTagRoute = {
223
- path: selectRoute.path,
224
- meta: selectRoute.meta,
225
- name: selectRoute.name,
226
- query: selectRoute?.query,
227
- params: selectRoute?.params
228
- };
229
- } else {
230
- selectTagRoute = { path: route.path, meta: route.meta };
231
- }
232
-
233
- // 当前路由信息
234
- switch (key) {
235
- case 0:
236
- // 刷新路由
237
- onFresh();
238
- break;
239
- case 1:
240
- // 关闭当前标签页
241
- deleteMenu(selectTagRoute);
242
- break;
243
- case 2:
244
- // 关闭左侧标签页
245
- deleteMenu(selectTagRoute, 'left');
246
- break;
247
- case 3:
248
- // 关闭右侧标签页
249
- deleteMenu(selectTagRoute, 'right');
250
- break;
251
- case 4:
252
- // 关闭其他标签页
253
- deleteMenu(selectTagRoute, 'other');
254
- break;
255
- case 5:
256
- // 关闭全部标签页
257
- useMultiTagsStoreHook().handleTags('splice', '', {
258
- startIndex: fixedTags.length,
259
- length: multiTags.value.length
260
- });
261
- router.push(topPath);
262
-
263
- handleAliveRoute(route as ToRouteType);
264
- break;
265
- case 6:
266
- // 整体页面全屏
267
- toggle();
268
- setTimeout(() => {
269
- if (isFullscreen.value) {
270
- tagsViews[6].icon = 'ri:fullscreen-exit-fill';
271
- tagsViews[6].text = 'message.btn.wholeExitFullScreen';
272
- } else {
273
- tagsViews[6].icon = 'ri:fullscreen-fill';
274
- tagsViews[6].text = 'message.btn.wholeFullScreen';
275
- }
276
- }, 100);
277
- break;
278
- case 7:
279
- // 内容区全屏
280
- onContentFullScreen();
281
- setTimeout(() => {
282
- if (SuSetting.hiddenSideBar) {
283
- tagsViews[7].icon = 'ri:fullscreen-exit-fill';
284
- tagsViews[7].text = 'message.btn.contentExitFullScreen';
285
- } else {
286
- tagsViews[7].icon = 'ri:fullscreen-fill';
287
- tagsViews[7].text = 'message.btn.contentFullScreen';
288
- }
289
- }, 100);
290
- break;
291
- }
292
- setTimeout(() => {
293
- showMenuModel(route.fullPath, route.query, route.params);
294
- });
295
- }
296
-
297
- function handleCommand(command: any) {
298
- const { key, item } = command;
299
- onClickDrop(key, item);
300
- }
301
-
302
- /** 触发右键中菜单的点击事件 */
303
- function selectTag(key, item) {
304
- closeMenu();
305
- onClickDrop(key, item, currentSelect.value);
306
- }
307
-
308
- function showMenus(value: boolean) {
309
- Array.of(1, 2, 3, 4, 5).forEach(v => {
310
- tagsViews[v].show = value;
311
- });
312
- }
313
-
314
- function disabledMenus(value: boolean, fixedTag = false) {
315
- Array.of(1, 2, 3, 4, 5).forEach(v => {
316
- tagsViews[v].disabled = value;
317
- });
318
- if (fixedTag) {
319
- tagsViews[2].show = false;
320
- tagsViews[2].disabled = true;
321
- }
322
- }
323
-
324
- /** 检查当前右键的菜单两边是否存在别的菜单,如果左侧的菜单是顶级菜单,则不显示关闭左侧标签页,如果右侧没有菜单,则不显示关闭右侧标签页 */
325
- function showMenuModel(currentPath: string, query: object = {}, params: object = {}, refresh = false) {
326
- const allRoute = multiTags.value;
327
- const routeLength = multiTags.value.length;
328
- let currentIndex = -1;
329
- if (!isEmpty(params)) {
330
- currentIndex = allRoute.findIndex(v => isEqual(v.params, params));
331
- } else if (isEmpty(query)) {
332
- currentIndex = allRoute.findIndex(v => v.path === currentPath);
333
- } else {
334
- currentIndex = allRoute.findIndex(v => isEqual(v.query, query));
335
- }
336
-
337
- function fixedTagDisabled() {
338
- if (allRoute[currentIndex]?.meta?.fixedTag) {
339
- Array.of(1, 2, 3, 4, 5).forEach(v => {
340
- tagsViews[v].disabled = true;
341
- });
342
- }
343
- }
344
-
345
- showMenus(true);
346
-
347
- if (refresh) {
348
- tagsViews[0].show = true;
349
- }
350
-
351
- /**
352
- * currentIndex为1时,左侧的菜单顶级菜单,则不显示关闭左侧标签页
353
- * 如果currentIndex等于routeLength-1,右侧没有菜单,则不显示关闭右侧标签页
354
- */
355
- if (currentIndex === 1 && routeLength !== 2) {
356
- // 左侧的菜单是顶级菜单,右侧存在别的菜单
357
- tagsViews[2].show = false;
358
- Array.of(1, 3, 4, 5).forEach(v => {
359
- tagsViews[v].disabled = false;
360
- });
361
- tagsViews[2].disabled = true;
362
- fixedTagDisabled();
363
- } else if (currentIndex === 1 && routeLength === 2) {
364
- disabledMenus(false);
365
- // 左侧的菜单是顶级菜单,右侧不存在别的菜单
366
- Array.of(2, 3, 4).forEach(v => {
367
- tagsViews[v].show = false;
368
- tagsViews[v].disabled = true;
369
- });
370
- fixedTagDisabled();
371
- } else if (routeLength - 1 === currentIndex && currentIndex !== 0) {
372
- // 当前路由是所有路由中的最后一个
373
- tagsViews[3].show = false;
374
- Array.of(1, 2, 4, 5).forEach(v => {
375
- tagsViews[v].disabled = false;
376
- });
377
- tagsViews[3].disabled = true;
378
- if (allRoute[currentIndex - 1]?.meta?.fixedTag) {
379
- tagsViews[2].show = false;
380
- tagsViews[2].disabled = true;
381
- }
382
- fixedTagDisabled();
383
- } else if (currentIndex === 0 || currentPath === `/redirect${topPath}`) {
384
- // 当前路由为首页
385
- disabledMenus(true);
386
- } else {
387
- disabledMenus(false, allRoute[currentIndex - 1]?.meta?.fixedTag);
388
- fixedTagDisabled();
389
- }
390
- }
391
-
392
- function openMenu(tag, e) {
393
- closeMenu();
394
- if (tag.path === '/welcome' || tag?.meta?.fixedTag) {
395
- // 右键菜单为首页或拥有 fixedTag 属性,只显示刷新
396
- showMenus(false);
397
- tagsViews[0].show = true;
398
- } else if (route.path !== tag.path && route.name !== tag.name) {
399
- // 右键菜单不匹配当前路由,隐藏刷新
400
- tagsViews[0].show = false;
401
- showMenuModel(tag.path, tag.query, tag.params);
402
- } else if (multiTags.value.length === 2 && route.path !== tag.path) {
403
- showMenus(true);
404
- // 只有两个标签时不显示关闭其他标签页
405
- tagsViews[4].show = false;
406
- showMenuModel(tag.path, tag.query, tag.params);
407
- } else if (route.path === tag.path) {
408
- // 右键当前激活的菜单
409
- showMenuModel(tag.path, tag.query, tag.params, true);
410
- }
411
-
412
- currentSelect.value = tag;
413
- const menuMinWidth = 140;
414
- const offsetLeft = unref(containerDom).getBoundingClientRect().left;
415
- const offsetWidth = unref(containerDom).offsetWidth;
416
- const maxLeft = offsetWidth - menuMinWidth;
417
- const left = e.clientX - offsetLeft + 5;
418
- if (left > maxLeft) {
419
- buttonLeft.value = maxLeft;
420
- } else {
421
- buttonLeft.value = left;
422
- }
423
- suSetting.hiddenSideBar ? (buttonTop.value = e.clientY) : (buttonTop.value = e.clientY - 40);
424
- nextTick(() => {
425
- visible.value = true;
426
- });
427
- }
428
-
429
- /** 触发tags标签切换 */
430
- function tagOnClick(item) {
431
- const { name, path } = item;
432
- if (name) {
433
- if (item.query) {
434
- router.push({
435
- name,
436
- query: item.query
437
- });
438
- } else if (item.params) {
439
- router.push({
440
- name,
441
- params: item.params
442
- });
443
- } else {
444
- router.push({ name });
445
- }
446
- } else {
447
- router.push({ path });
448
- }
449
- // showMenuModel(item?.path, item?.query);
450
- emitter.emit('tagOnClick', item);
451
- }
452
-
453
- onClickOutside(contextmenuRef, closeMenu, {
454
- detectIframe: true
455
- });
456
-
457
- watch(route, () => {
458
- activeIndex.value = -1;
459
- dynamicTagView();
460
- });
461
-
462
- watch(isFullscreen, () => {
463
- tagsViews[6].icon = 'ri:fullscreen-fill';
464
- tagsViews[6].text = 'message.wholeFullScreen';
465
- });
466
-
467
- onMounted(() => {
468
- if (!instance) return;
469
-
470
- // 根据当前路由初始化操作标签页的禁用状态
471
- showMenuModel(route.fullPath);
472
-
473
- // 触发隐藏标签页
474
- emitter.on('tagViewsChange', (key: any) => {
475
- if (unref(showTags as any) === key) return;
476
- (showTags as any).value = key;
477
- });
478
-
479
- // 改变标签风格
480
- emitter.on('tagViewsShowModel', key => {
481
- showModel.value = key;
482
- });
483
-
484
- // 接收侧边栏切换传递过来的参数
485
- emitter.on('changLayoutRoute', indexPath => {
486
- dynamicRouteTag(indexPath);
487
- setTimeout(() => {
488
- showMenuModel(indexPath);
489
- });
490
- });
491
-
492
- useResizeObserver(
493
- scrollbarDom,
494
- useDebounceFn(() => {
495
- dynamicTagView();
496
- }, 200)
497
- );
498
- delay().then(() => dynamicTagView());
499
- });
500
-
501
- onBeforeUnmount(() => {
502
- // 解绑`tagViewsChange`、`tagViewsShowModel`、`changLayoutRoute`公共事件,防止多次触发
503
- emitter.off('tagViewsChange');
504
- emitter.off('tagViewsShowModel');
505
- emitter.off('changLayoutRoute');
506
- });
507
- </script>
508
-
509
- <template>
510
- <div v-if="!showTags" ref="containerDom" class="tags-view">
511
- <span v-show="isShowArrow" class="arrow-left">
512
- <IconifyIconOffline icon="ri:arrow-left-s-line" @click="handleScroll(200)" />
513
- </span>
514
- <div ref="scrollbarDom" class="scroll-container" :class="showModel === 'chrome' && 'chrome-scroll-container'">
515
- <div ref="tabDom" class="select-none tab" :style="getTabStyle">
516
- <div
517
- v-for="(item, index) in multiTags"
518
- :key="index"
519
- :ref="'dynamic' + index"
520
- :class="[
521
- 'scroll-item is-closable',
522
- linkIsActive(item),
523
- showModel === 'chrome' && 'chrome-item',
524
- isFixedTag(item) && 'fixed-tag'
525
- ]"
526
- @contextmenu.prevent="openMenu(item, $event)"
527
- @mouseenter.prevent="onMouseenter(index)"
528
- @mouseleave.prevent="onMouseleave(index)"
529
- @click="tagOnClick(item)"
530
- >
531
- <template v-if="showModel !== 'chrome'">
532
- <span class="tag-title dark:text-text_color_primary! dark:hover:text-primary!">
533
- {{ transformI18n(item?.meta?.title) }}
534
- </span>
535
- <span
536
- v-if="isFixedTag(item) ? false : iconIsActive(item, index) || (index === activeIndex && index !== 0)"
537
- class="el-icon-close"
538
- @click.stop="deleteMenu(item)"
539
- >
540
- <IconifyIconOffline icon="ri:close-fill" />
541
- </span>
542
- <span v-if="showModel !== 'card'" :ref="'schedule' + index" :class="[scheduleIsActive(item)]" />
543
- </template>
544
- <div v-else class="chrome-tab">
545
- <div class="chrome-tab__bg">
546
- <TagChrome />
547
- </div>
548
- <span class="tag-title">
549
- {{ transformI18n(item?.meta?.title) }}
550
- </span>
551
- <span v-if="isFixedTag(item) ? false : index !== 0" class="chrome-close-btn" @click.stop="deleteMenu(item)">
552
- <IconifyIconOffline icon="ri:close-fill" />
553
- </span>
554
- <span class="chrome-tab-divider" />
555
- </div>
556
- </div>
557
- </div>
558
- </div>
559
- <span v-show="isShowArrow" class="arrow-right">
560
- <IconifyIconOffline icon="ri:arrow-right-s-line" @click="handleScroll(-200)" />
561
- </span>
562
- <!-- 右键菜单按钮 -->
563
- <transition name="el-zoom-in-top">
564
- <ul v-show="visible" ref="contextmenuRef" :key="Math.random()" :style="getContextMenuStyle" class="contextmenu">
565
- <div v-for="(item, key) in tagsViews.slice(0, 6)" :key="key" style="display: flex; align-items: center">
566
- <li v-if="item.show" @click="selectTag(key, item)">
567
- <IconifyIconOffline :icon="item.icon" />
568
- {{ $t(item.text) }}
569
- </li>
570
- </div>
571
- </ul>
572
- </transition>
573
- <!-- 右侧功能按钮 -->
574
- <el-dropdown trigger="click" placement="bottom-end" @command="handleCommand">
575
- <span class="arrow-down">
576
- <IconifyIconOffline icon="ri:arrow-down-s-line" class="dark:text-white" />
577
- </span>
578
- <template #dropdown>
579
- <el-dropdown-menu>
580
- <el-dropdown-item
581
- v-for="(item, key) in tagsViews"
582
- :key="key"
583
- :command="{ key, item }"
584
- :divided="item.divided"
585
- :disabled="item.disabled"
586
- >
587
- <IconifyIconOffline :icon="item.icon" />
588
- {{ $t(item.text) }}
589
- </el-dropdown-item>
590
- </el-dropdown-menu>
591
- </template>
592
- </el-dropdown>
593
- </div>
594
- </template>
595
-
596
- <style lang="scss" scoped>
597
- @import url('./index.scss');
598
- </style>
1
+ <script lang="ts">
2
+ export default { name: 'LayoutTag' };
3
+ </script>
4
+ <script setup lang="ts">
5
+ import { ref, watch, unref, nextTick, onBeforeUnmount } from 'vue';
6
+ import { isEqual, isEmpty } from 'xe-utils';
7
+ import { useResizeObserver, useDebounceFn, useFullscreen, onClickOutside } from '@vueuse/core';
8
+ import { delay } from '@utogether/utils';
9
+ import { emitter } from '../../../utils/mitt';
10
+ import { routerArrays } from '../../types';
11
+ import { useSettingStoreHook } from '../../../store/modules/settings';
12
+ import { handleAliveRoute, getTopMenu } from '../../../router/utils';
13
+ import { useMultiTagsStoreHook } from '../../../store/modules/multiTags';
14
+ import { usePermissionStoreHook } from '../../../store/modules/permission';
15
+ import { useTags } from '../../hooks/useTag';
16
+ import { RouteConfigs } from '../../types';
17
+ import TagChrome from '../lay-chrome/index.vue';
18
+
19
+ const {
20
+ route,
21
+ router,
22
+ visible,
23
+ showTags,
24
+ instance,
25
+ multiTags,
26
+ tagsViews,
27
+ buttonTop,
28
+ buttonLeft,
29
+ showModel,
30
+ translateX,
31
+ isFixedTag,
32
+ SuSetting,
33
+ activeIndex,
34
+ getTabStyle,
35
+ iconIsActive,
36
+ linkIsActive,
37
+ currentSelect,
38
+ scheduleIsActive,
39
+ getContextMenuStyle,
40
+ closeMenu,
41
+ onMounted,
42
+ onMouseenter,
43
+ onMouseleave,
44
+ transformI18n,
45
+ onContentFullScreen
46
+ } = useTags();
47
+
48
+ const suSetting = useSettingStoreHook();
49
+ const tabDom = ref();
50
+ const containerDom = ref();
51
+ const scrollbarDom = ref();
52
+ const contextmenuRef = ref();
53
+ const isShowArrow = ref(false);
54
+ const topPath = getTopMenu()?.path;
55
+ const { isFullscreen, toggle } = useFullscreen();
56
+
57
+ const fixedTags = [...routerArrays, ...usePermissionStoreHook().flatteningRoutes.filter(v => v?.meta?.fixedTag)];
58
+ const dynamicTagView = async () => {
59
+ await nextTick();
60
+ const index = multiTags.value.findIndex(item => {
61
+ if (!isEmpty(route.query)) {
62
+ return isEqual(route.query, item.query);
63
+ } else if (!isEmpty(route.params)) {
64
+ return isEqual(route.params, item.params);
65
+ } else {
66
+ return route.path === item.path;
67
+ }
68
+ });
69
+ moveToView(index);
70
+ };
71
+
72
+ const moveToView = async (index: number): Promise<void> => {
73
+ await nextTick();
74
+ const tabNavPadding = 10;
75
+ if (!instance.refs['dynamic' + index]) return;
76
+ const tabItemEl = instance.refs['dynamic' + index][0];
77
+ const tabItemElOffsetLeft = (tabItemEl as HTMLElement)?.offsetLeft;
78
+ const tabItemOffsetWidth = (tabItemEl as HTMLElement)?.offsetWidth;
79
+ // 标签页导航栏可视长度(不包含溢出部分)
80
+ const scrollbarDomWidth = scrollbarDom.value ? scrollbarDom.value.offsetWidth : 0;
81
+ // 已有标签页总长度(包含溢出部分)
82
+ const tabDomWidth = tabDom.value ? tabDom.value?.offsetWidth : 0;
83
+ scrollbarDomWidth <= tabDomWidth ? (isShowArrow.value = true) : (isShowArrow.value = false);
84
+ if (tabDomWidth < scrollbarDomWidth || tabItemElOffsetLeft === 0) {
85
+ translateX.value = 0;
86
+ } else if (tabItemElOffsetLeft < -translateX.value) {
87
+ // 标签在可视区域左侧
88
+ translateX.value = -tabItemElOffsetLeft + tabNavPadding;
89
+ } else if (
90
+ tabItemElOffsetLeft > -translateX.value &&
91
+ tabItemElOffsetLeft + tabItemOffsetWidth < -translateX.value + scrollbarDomWidth
92
+ ) {
93
+ // 标签在可视区域
94
+ translateX.value = Math.min(0, scrollbarDomWidth - tabItemOffsetWidth - tabItemElOffsetLeft - tabNavPadding);
95
+ } else {
96
+ // 标签在可视区域右侧
97
+ translateX.value = -(tabItemElOffsetLeft - (scrollbarDomWidth - tabNavPadding - tabItemOffsetWidth));
98
+ }
99
+ };
100
+
101
+ const handleScroll = (offset: number): void => {
102
+ const scrollbarDomWidth = scrollbarDom.value ? scrollbarDom.value?.offsetWidth : 0;
103
+ const tabDomWidth = tabDom.value ? tabDom.value.offsetWidth : 0;
104
+ if (offset > 0) {
105
+ translateX.value = Math.min(0, translateX.value + offset);
106
+ } else {
107
+ if (scrollbarDomWidth < tabDomWidth) {
108
+ if (translateX.value >= -(tabDomWidth - scrollbarDomWidth)) {
109
+ translateX.value = Math.max(translateX.value + offset, scrollbarDomWidth - tabDomWidth);
110
+ }
111
+ } else {
112
+ translateX.value = 0;
113
+ }
114
+ }
115
+ };
116
+
117
+ function dynamicRouteTag(value: string): void {
118
+ const hasValue = multiTags.value.some(item => {
119
+ return item.path === value;
120
+ });
121
+
122
+ function concatPath(arr: object[], value: string) {
123
+ if (!hasValue) {
124
+ arr.forEach((arrItem: any) => {
125
+ if (arrItem.path === value) {
126
+ useMultiTagsStoreHook().handleTags('push', {
127
+ path: value,
128
+ meta: arrItem.meta,
129
+ name: arrItem.name
130
+ });
131
+ } else {
132
+ if (arrItem.children && arrItem.children.length > 0) {
133
+ concatPath(arrItem.children, value);
134
+ }
135
+ }
136
+ });
137
+ }
138
+ }
139
+ concatPath(router.options.routes as any, value);
140
+ }
141
+
142
+ /** 刷新路由 */
143
+ function onFresh() {
144
+ const { fullPath, query } = unref(route);
145
+ router.replace({
146
+ path: '/redirect' + fullPath,
147
+ query: query
148
+ });
149
+ handleAliveRoute(route as ToRouteType, 'refresh');
150
+ }
151
+
152
+ function deleteDynamicTag(obj: any, current: any, tag?: string) {
153
+ const valueIndex: number = multiTags.value.findIndex((item: any) => {
154
+ if (item.query) {
155
+ if (item.path === obj.path) {
156
+ return item.query === obj.query;
157
+ }
158
+ } else if (item.params) {
159
+ if (item.path === obj.path) {
160
+ return item.params === obj.params;
161
+ }
162
+ } else {
163
+ return item.path === obj.path;
164
+ }
165
+ });
166
+
167
+ const spliceRoute = (startIndex?: number, length?: number, other?: boolean): void => {
168
+ if (other) {
169
+ useMultiTagsStoreHook().handleTags('equal', [fixedTags, obj].flat());
170
+ } else {
171
+ useMultiTagsStoreHook().handleTags('splice', '', {
172
+ startIndex,
173
+ length
174
+ }) as any;
175
+ }
176
+ dynamicTagView();
177
+ };
178
+
179
+ if (tag === 'other') {
180
+ spliceRoute(1, 1, true);
181
+ } else if (tag === 'left') {
182
+ spliceRoute(fixedTags.length, valueIndex - fixedTags.length);
183
+ } else if (tag === 'right') {
184
+ spliceRoute(valueIndex + 1, multiTags.value.length);
185
+ } else {
186
+ // 从当前匹配到的路径中删除
187
+ spliceRoute(valueIndex, 1);
188
+ }
189
+ const newRoute = useMultiTagsStoreHook().handleTags('slice');
190
+ if (current === route.path) {
191
+ // 如果删除当前激活tag就自动切换到最后一个tag
192
+ if (tag === 'left') return;
193
+ if (newRoute[0]?.query) {
194
+ router.push({ name: newRoute[0].name, query: newRoute[0].query });
195
+ } else if (newRoute[0]?.params) {
196
+ router.push({ name: newRoute[0].name, params: newRoute[0].params });
197
+ } else {
198
+ router.push({ path: newRoute[0].path });
199
+ }
200
+ } else {
201
+ if (!multiTags.value.length) return;
202
+ if (multiTags.value.some(item => item.path === route.path)) return;
203
+ if (newRoute[0]?.query) {
204
+ router.push({ name: newRoute[0].name, query: newRoute[0].query });
205
+ } else if (newRoute[0]?.params) {
206
+ router.push({ name: newRoute[0].name, params: newRoute[0].params });
207
+ } else {
208
+ router.push({ path: newRoute[0].path });
209
+ }
210
+ }
211
+ }
212
+
213
+ function deleteMenu(item, tag?: string) {
214
+ deleteDynamicTag(item, item.path, tag);
215
+ handleAliveRoute(route as ToRouteType);
216
+ }
217
+
218
+ function onClickDrop(key, item, selectRoute?: RouteConfigs) {
219
+ if (item && item.disabled) return;
220
+ let selectTagRoute;
221
+ if (selectRoute) {
222
+ selectTagRoute = {
223
+ path: selectRoute.path,
224
+ meta: selectRoute.meta,
225
+ name: selectRoute.name,
226
+ query: selectRoute?.query,
227
+ params: selectRoute?.params
228
+ };
229
+ } else {
230
+ selectTagRoute = { path: route.path, meta: route.meta };
231
+ }
232
+
233
+ // 当前路由信息
234
+ switch (key) {
235
+ case 0:
236
+ // 刷新路由
237
+ onFresh();
238
+ break;
239
+ case 1:
240
+ // 关闭当前标签页
241
+ deleteMenu(selectTagRoute);
242
+ break;
243
+ case 2:
244
+ // 关闭左侧标签页
245
+ deleteMenu(selectTagRoute, 'left');
246
+ break;
247
+ case 3:
248
+ // 关闭右侧标签页
249
+ deleteMenu(selectTagRoute, 'right');
250
+ break;
251
+ case 4:
252
+ // 关闭其他标签页
253
+ deleteMenu(selectTagRoute, 'other');
254
+ break;
255
+ case 5:
256
+ // 关闭全部标签页
257
+ useMultiTagsStoreHook().handleTags('splice', '', {
258
+ startIndex: fixedTags.length,
259
+ length: multiTags.value.length
260
+ });
261
+ router.push(topPath);
262
+
263
+ handleAliveRoute(route as ToRouteType);
264
+ break;
265
+ case 6:
266
+ // 整体页面全屏
267
+ toggle();
268
+ setTimeout(() => {
269
+ if (isFullscreen.value) {
270
+ tagsViews[6].icon = 'ri:fullscreen-exit-fill';
271
+ tagsViews[6].text = 'message.btn.wholeExitFullScreen';
272
+ } else {
273
+ tagsViews[6].icon = 'ri:fullscreen-fill';
274
+ tagsViews[6].text = 'message.btn.wholeFullScreen';
275
+ }
276
+ }, 100);
277
+ break;
278
+ case 7:
279
+ // 内容区全屏
280
+ onContentFullScreen();
281
+ setTimeout(() => {
282
+ if (SuSetting.hiddenSideBar) {
283
+ tagsViews[7].icon = 'ri:fullscreen-exit-fill';
284
+ tagsViews[7].text = 'message.btn.contentExitFullScreen';
285
+ } else {
286
+ tagsViews[7].icon = 'ri:fullscreen-fill';
287
+ tagsViews[7].text = 'message.btn.contentFullScreen';
288
+ }
289
+ }, 100);
290
+ break;
291
+ }
292
+ setTimeout(() => {
293
+ showMenuModel(route.fullPath, route.query, route.params);
294
+ });
295
+ }
296
+
297
+ function handleCommand(command: any) {
298
+ const { key, item } = command;
299
+ onClickDrop(key, item);
300
+ }
301
+
302
+ /** 触发右键中菜单的点击事件 */
303
+ function selectTag(key, item) {
304
+ closeMenu();
305
+ onClickDrop(key, item, currentSelect.value);
306
+ }
307
+
308
+ function showMenus(value: boolean) {
309
+ Array.of(1, 2, 3, 4, 5).forEach(v => {
310
+ tagsViews[v].show = value;
311
+ });
312
+ }
313
+
314
+ function disabledMenus(value: boolean, fixedTag = false) {
315
+ Array.of(1, 2, 3, 4, 5).forEach(v => {
316
+ tagsViews[v].disabled = value;
317
+ });
318
+ if (fixedTag) {
319
+ tagsViews[2].show = false;
320
+ tagsViews[2].disabled = true;
321
+ }
322
+ }
323
+
324
+ /** 检查当前右键的菜单两边是否存在别的菜单,如果左侧的菜单是顶级菜单,则不显示关闭左侧标签页,如果右侧没有菜单,则不显示关闭右侧标签页 */
325
+ function showMenuModel(currentPath: string, query: object = {}, params: object = {}, refresh = false) {
326
+ const allRoute = multiTags.value;
327
+ const routeLength = multiTags.value.length;
328
+ let currentIndex = -1;
329
+ if (!isEmpty(params)) {
330
+ currentIndex = allRoute.findIndex(v => isEqual(v.params, params));
331
+ } else if (isEmpty(query)) {
332
+ currentIndex = allRoute.findIndex(v => v.path === currentPath);
333
+ } else {
334
+ currentIndex = allRoute.findIndex(v => isEqual(v.query, query));
335
+ }
336
+
337
+ function fixedTagDisabled() {
338
+ if (allRoute[currentIndex]?.meta?.fixedTag) {
339
+ Array.of(1, 2, 3, 4, 5).forEach(v => {
340
+ tagsViews[v].disabled = true;
341
+ });
342
+ }
343
+ }
344
+
345
+ showMenus(true);
346
+
347
+ if (refresh) {
348
+ tagsViews[0].show = true;
349
+ }
350
+
351
+ /**
352
+ * currentIndex为1时,左侧的菜单顶级菜单,则不显示关闭左侧标签页
353
+ * 如果currentIndex等于routeLength-1,右侧没有菜单,则不显示关闭右侧标签页
354
+ */
355
+ if (currentIndex === 1 && routeLength !== 2) {
356
+ // 左侧的菜单是顶级菜单,右侧存在别的菜单
357
+ tagsViews[2].show = false;
358
+ Array.of(1, 3, 4, 5).forEach(v => {
359
+ tagsViews[v].disabled = false;
360
+ });
361
+ tagsViews[2].disabled = true;
362
+ fixedTagDisabled();
363
+ } else if (currentIndex === 1 && routeLength === 2) {
364
+ disabledMenus(false);
365
+ // 左侧的菜单是顶级菜单,右侧不存在别的菜单
366
+ Array.of(2, 3, 4).forEach(v => {
367
+ tagsViews[v].show = false;
368
+ tagsViews[v].disabled = true;
369
+ });
370
+ fixedTagDisabled();
371
+ } else if (routeLength - 1 === currentIndex && currentIndex !== 0) {
372
+ // 当前路由是所有路由中的最后一个
373
+ tagsViews[3].show = false;
374
+ Array.of(1, 2, 4, 5).forEach(v => {
375
+ tagsViews[v].disabled = false;
376
+ });
377
+ tagsViews[3].disabled = true;
378
+ if (allRoute[currentIndex - 1]?.meta?.fixedTag) {
379
+ tagsViews[2].show = false;
380
+ tagsViews[2].disabled = true;
381
+ }
382
+ fixedTagDisabled();
383
+ } else if (currentIndex === 0 || currentPath === `/redirect${topPath}`) {
384
+ // 当前路由为首页
385
+ disabledMenus(true);
386
+ } else {
387
+ disabledMenus(false, allRoute[currentIndex - 1]?.meta?.fixedTag);
388
+ fixedTagDisabled();
389
+ }
390
+ }
391
+
392
+ function openMenu(tag, e) {
393
+ closeMenu();
394
+ if (tag.path === '/welcome' || tag?.meta?.fixedTag) {
395
+ // 右键菜单为首页或拥有 fixedTag 属性,只显示刷新
396
+ showMenus(false);
397
+ tagsViews[0].show = true;
398
+ } else if (route.path !== tag.path && route.name !== tag.name) {
399
+ // 右键菜单不匹配当前路由,隐藏刷新
400
+ tagsViews[0].show = false;
401
+ showMenuModel(tag.path, tag.query, tag.params);
402
+ } else if (multiTags.value.length === 2 && route.path !== tag.path) {
403
+ showMenus(true);
404
+ // 只有两个标签时不显示关闭其他标签页
405
+ tagsViews[4].show = false;
406
+ showMenuModel(tag.path, tag.query, tag.params);
407
+ } else if (route.path === tag.path) {
408
+ // 右键当前激活的菜单
409
+ showMenuModel(tag.path, tag.query, tag.params, true);
410
+ }
411
+
412
+ currentSelect.value = tag;
413
+ const menuMinWidth = 140;
414
+ const offsetLeft = unref(containerDom).getBoundingClientRect().left;
415
+ const offsetWidth = unref(containerDom).offsetWidth;
416
+ const maxLeft = offsetWidth - menuMinWidth;
417
+ const left = e.clientX - offsetLeft + 5;
418
+ if (left > maxLeft) {
419
+ buttonLeft.value = maxLeft;
420
+ } else {
421
+ buttonLeft.value = left;
422
+ }
423
+ suSetting.hiddenSideBar ? (buttonTop.value = e.clientY) : (buttonTop.value = e.clientY - 40);
424
+ nextTick(() => {
425
+ visible.value = true;
426
+ });
427
+ }
428
+
429
+ /** 触发tags标签切换 */
430
+ function tagOnClick(item) {
431
+ const { name, path } = item;
432
+ if (name) {
433
+ if (item.query) {
434
+ router.push({
435
+ name,
436
+ query: item.query
437
+ });
438
+ } else if (item.params) {
439
+ router.push({
440
+ name,
441
+ params: item.params
442
+ });
443
+ } else {
444
+ router.push({ name });
445
+ }
446
+ } else {
447
+ router.push({ path });
448
+ }
449
+ // showMenuModel(item?.path, item?.query);
450
+ emitter.emit('tagOnClick', item);
451
+ }
452
+
453
+ onClickOutside(contextmenuRef, closeMenu, {
454
+ detectIframe: true
455
+ });
456
+
457
+ watch(route, () => {
458
+ activeIndex.value = -1;
459
+ dynamicTagView();
460
+ });
461
+
462
+ watch(isFullscreen, () => {
463
+ tagsViews[6].icon = 'ri:fullscreen-fill';
464
+ tagsViews[6].text = 'message.wholeFullScreen';
465
+ });
466
+
467
+ onMounted(() => {
468
+ if (!instance) return;
469
+
470
+ // 根据当前路由初始化操作标签页的禁用状态
471
+ showMenuModel(route.fullPath);
472
+
473
+ // 触发隐藏标签页
474
+ emitter.on('tagViewsChange', (key: any) => {
475
+ if (unref(showTags as any) === key) return;
476
+ (showTags as any).value = key;
477
+ });
478
+
479
+ // 改变标签风格
480
+ emitter.on('tagViewsShowModel', key => {
481
+ showModel.value = key;
482
+ });
483
+
484
+ // 接收侧边栏切换传递过来的参数
485
+ emitter.on('changLayoutRoute', indexPath => {
486
+ dynamicRouteTag(indexPath);
487
+ setTimeout(() => {
488
+ showMenuModel(indexPath);
489
+ });
490
+ });
491
+
492
+ useResizeObserver(
493
+ scrollbarDom,
494
+ useDebounceFn(() => {
495
+ dynamicTagView();
496
+ }, 200)
497
+ );
498
+ delay().then(() => dynamicTagView());
499
+ });
500
+
501
+ onBeforeUnmount(() => {
502
+ // 解绑`tagViewsChange`、`tagViewsShowModel`、`changLayoutRoute`公共事件,防止多次触发
503
+ emitter.off('tagViewsChange');
504
+ emitter.off('tagViewsShowModel');
505
+ emitter.off('changLayoutRoute');
506
+ });
507
+ </script>
508
+
509
+ <template>
510
+ <div v-if="!showTags" ref="containerDom" class="tags-view">
511
+ <span v-show="isShowArrow" class="arrow-left">
512
+ <IconifyIconOffline icon="ri:arrow-left-s-line" @click="handleScroll(200)" />
513
+ </span>
514
+ <div ref="scrollbarDom" class="scroll-container" :class="showModel === 'chrome' && 'chrome-scroll-container'">
515
+ <div ref="tabDom" class="select-none tab" :style="getTabStyle">
516
+ <div
517
+ v-for="(item, index) in multiTags"
518
+ :key="index"
519
+ :ref="'dynamic' + index"
520
+ :class="[
521
+ 'scroll-item is-closable',
522
+ linkIsActive(item),
523
+ showModel === 'chrome' && 'chrome-item',
524
+ isFixedTag(item) && 'fixed-tag'
525
+ ]"
526
+ @contextmenu.prevent="openMenu(item, $event)"
527
+ @mouseenter.prevent="onMouseenter(index)"
528
+ @mouseleave.prevent="onMouseleave(index)"
529
+ @click="tagOnClick(item)"
530
+ >
531
+ <template v-if="showModel !== 'chrome'">
532
+ <span class="tag-title dark:text-text_color_primary! dark:hover:text-primary!">
533
+ {{ transformI18n(item?.meta?.title) }}
534
+ </span>
535
+ <span
536
+ v-if="isFixedTag(item) ? false : iconIsActive(item, index) || (index === activeIndex && index !== 0)"
537
+ class="el-icon-close"
538
+ @click.stop="deleteMenu(item)"
539
+ >
540
+ <IconifyIconOffline icon="ri:close-fill" />
541
+ </span>
542
+ <span v-if="showModel !== 'card'" :ref="'schedule' + index" :class="[scheduleIsActive(item)]" />
543
+ </template>
544
+ <div v-else class="chrome-tab">
545
+ <div class="chrome-tab__bg">
546
+ <TagChrome />
547
+ </div>
548
+ <span class="tag-title">
549
+ {{ transformI18n(item?.meta?.title) }}
550
+ </span>
551
+ <span v-if="isFixedTag(item) ? false : index !== 0" class="chrome-close-btn" @click.stop="deleteMenu(item)">
552
+ <IconifyIconOffline icon="ri:close-fill" />
553
+ </span>
554
+ <span class="chrome-tab-divider" />
555
+ </div>
556
+ </div>
557
+ </div>
558
+ </div>
559
+ <span v-show="isShowArrow" class="arrow-right">
560
+ <IconifyIconOffline icon="ri:arrow-right-s-line" @click="handleScroll(-200)" />
561
+ </span>
562
+ <!-- 右键菜单按钮 -->
563
+ <transition name="el-zoom-in-top">
564
+ <ul v-show="visible" ref="contextmenuRef" :key="Math.random()" :style="getContextMenuStyle" class="contextmenu">
565
+ <div v-for="(item, key) in tagsViews.slice(0, 6)" :key="key" style="display: flex; align-items: center">
566
+ <li v-if="item.show" @click="selectTag(key, item)">
567
+ <IconifyIconOffline :icon="item.icon" />
568
+ {{ $t(item.text) }}
569
+ </li>
570
+ </div>
571
+ </ul>
572
+ </transition>
573
+ <!-- 右侧功能按钮 -->
574
+ <el-dropdown trigger="click" placement="bottom-end" @command="handleCommand">
575
+ <span class="arrow-down">
576
+ <IconifyIconOffline icon="ri:arrow-down-s-line" class="dark:text-white" />
577
+ </span>
578
+ <template #dropdown>
579
+ <el-dropdown-menu>
580
+ <el-dropdown-item
581
+ v-for="(item, key) in tagsViews"
582
+ :key="key"
583
+ :command="{ key, item }"
584
+ :divided="item.divided"
585
+ :disabled="item.disabled"
586
+ >
587
+ <IconifyIconOffline :icon="item.icon" />
588
+ {{ $t(item.text) }}
589
+ </el-dropdown-item>
590
+ </el-dropdown-menu>
591
+ </template>
592
+ </el-dropdown>
593
+ </div>
594
+ </template>
595
+
596
+ <style lang="scss" scoped>
597
+ @import url('./index.scss');
598
+ </style>