@jx3box/jx3box-ui 2.0.4 → 2.0.6

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 (227) hide show
  1. package/.storybook/main.js +208 -0
  2. package/.storybook/preview.js +93 -0
  3. package/.storybook/storybookMocks.js +191 -0
  4. package/README.md +29 -82
  5. package/assets/css/bread/admin.less +20 -2
  6. package/assets/css/bread/breadcrumb.less +5 -2
  7. package/assets/css/comment/quick-reply.less +1 -1
  8. package/assets/css/common/left-sidebar.less +1 -1
  9. package/assets/css/interact/like2.less +5 -2
  10. package/assets/css/single/author.less +15 -10
  11. package/assets/css/single/cms-single.less +1 -0
  12. package/assets/css/single/thx.less +34 -11
  13. package/assets/data/nav.json +344 -10
  14. package/assets/img/comment/comment.svg +1 -1
  15. package/assets/img/comment/heart_1.svg +1 -1
  16. package/assets/img/comment/hide.svg +1 -1
  17. package/assets/img/leftsidebar/medal.svg +1 -1
  18. package/assets/img/leftsidebar/post.svg +27 -46
  19. package/i18n/messages/en-US.js +357 -22
  20. package/i18n/messages/vi.js +350 -22
  21. package/i18n/messages/zh-CN.js +469 -20
  22. package/i18n/messages/zh-TW.js +350 -22
  23. package/index.js +19 -7
  24. package/package.json +15 -5
  25. package/service/cms.js +22 -0
  26. package/service/commit-history.js +18 -0
  27. package/service/community.js +60 -0
  28. package/service/fav.js +5 -6
  29. package/src/App.vue +154 -80
  30. package/src/Breadcrumb.vue +24 -11
  31. package/src/CommonFooter.vue +4 -4
  32. package/src/Footer.vue +13 -5
  33. package/src/LeftSideToggle.vue +10 -3
  34. package/src/LeftSidebar.vue +19 -5
  35. package/src/Main.vue +9 -2
  36. package/src/RightSidebar.vue +12 -3
  37. package/src/SuspendCommon.vue +52 -38
  38. package/src/author/AuthorFans.vue +7 -5
  39. package/src/author/AuthorFollow.vue +14 -7
  40. package/src/author/AuthorGift.vue +25 -17
  41. package/src/author/AuthorInfo.vue +46 -19
  42. package/src/author/AuthorLink.vue +3 -1
  43. package/src/author/AuthorMedals.vue +5 -2
  44. package/src/author/AuthorPosts.vue +31 -13
  45. package/src/author/AuthorRss.vue +7 -3
  46. package/src/author/AuthorTeams.vue +3 -1
  47. package/src/author/UserPop.vue +29 -17
  48. package/src/bread/Admin.vue +55 -32
  49. package/src/bread/AdminDirectMessage.vue +15 -8
  50. package/src/bread/AdminDrop.vue +124 -45
  51. package/src/bread/CommunityAdmin.vue +527 -0
  52. package/src/bread/DesignTask.vue +30 -26
  53. package/src/bread/ListAdmin.vue +199 -0
  54. package/src/bread/MigrateCommunity.vue +192 -0
  55. package/src/bread/MoveToCommunityDialog.vue +234 -0
  56. package/src/comment/Avatar.vue +18 -24
  57. package/src/comment/CommentContent.vue +57 -37
  58. package/src/comment/CommentContentSimple.vue +61 -63
  59. package/src/comment/CommentInputForm.vue +45 -34
  60. package/src/comment/CommentWithReply.vue +9 -6
  61. package/src/comment/QuickReply.vue +5 -1
  62. package/src/comment/ReplyForReply.vue +6 -4
  63. package/src/comment/ReplyList.vue +28 -18
  64. package/src/comment/Upload.vue +24 -6
  65. package/src/filters/clientBy.vue +10 -8
  66. package/src/filters/markBy.vue +35 -31
  67. package/src/filters/menuBy.vue +20 -22
  68. package/src/filters/orderBy.vue +17 -11
  69. package/src/filters/tagBy.vue +4 -2
  70. package/src/filters/topicBy.vue +12 -10
  71. package/src/filters/versionBy.vue +5 -3
  72. package/src/filters/zlpBy.vue +29 -25
  73. package/src/footer/copyright.vue +5 -5
  74. package/src/footer/links.vue +2 -2
  75. package/src/footer/official.vue +1 -1
  76. package/src/footer/resource.vue +41 -8
  77. package/src/header/alternate.vue +35 -18
  78. package/src/header/asset.vue +9 -19
  79. package/src/header/box.vue +20 -8
  80. package/src/header/box2.vue +25 -13
  81. package/src/header/client.vue +7 -7
  82. package/src/header/lang.vue +41 -6
  83. package/src/header/logo.vue +2 -3
  84. package/src/header/manage.vue +2 -2
  85. package/src/header/message.vue +3 -3
  86. package/src/header/nav.vue +26 -23
  87. package/src/header/publish.vue +2 -2
  88. package/src/header/search.vue +2 -2
  89. package/src/header/shop.vue +2 -2
  90. package/src/header/user.vue +4 -4
  91. package/src/header/userInfo.vue +22 -24
  92. package/src/header/vip.vue +2 -2
  93. package/src/interact/BoxcoinAdmin.vue +30 -16
  94. package/src/interact/BoxcoinRecords.vue +28 -11
  95. package/src/interact/BoxcoinUser.vue +33 -17
  96. package/src/interact/Fav.vue +5 -1
  97. package/src/interact/Homework.vue +318 -0
  98. package/src/interact/Like.vue +4 -2
  99. package/src/interact/Rss.vue +10 -4
  100. package/src/interact/Share.vue +18 -19
  101. package/src/interact/WatchLater.vue +5 -1
  102. package/src/main.js +1 -0
  103. package/src/single/Author.vue +5 -1
  104. package/src/single/CmsSingle.vue +29 -15
  105. package/src/single/Collection.vue +36 -26
  106. package/src/single/Comment.vue +19 -13
  107. package/src/single/Creators.vue +5 -3
  108. package/src/single/PostCollection.vue +158 -0
  109. package/src/single/PostDirectory.vue +0 -126
  110. package/src/single/PostGuide.vue +93 -0
  111. package/src/single/PostHeader.vue +39 -17
  112. package/src/single/PostTopic.vue +3 -3
  113. package/src/single/PostVersion.vue +219 -0
  114. package/src/single/RightAffix.vue +160 -0
  115. package/src/single/SimpleThx.vue +4 -2
  116. package/src/single/Thx.vue +14 -2
  117. package/src/single/VersionDialog.vue +238 -0
  118. package/src/stories/components/StoryPropsTable.vue +137 -0
  119. package/src/stories/filters/FilterGallery.stories.js +110 -0
  120. package/src/stories/filters/clientBy.stories.js +24 -0
  121. package/src/stories/filters/markBy.stories.js +6 -0
  122. package/src/stories/filters/menuBy.stories.js +6 -0
  123. package/src/stories/filters/orderBy.stories.js +6 -0
  124. package/src/stories/filters/tagBy.stories.js +6 -0
  125. package/src/stories/filters/topicBy.stories.js +6 -0
  126. package/src/stories/filters/versionBy.stories.js +6 -0
  127. package/src/stories/filters/zlpBy.stories.js +6 -0
  128. package/src/stories/layout/BaseShell.stories.js +38 -0
  129. package/src/stories/layout/Breadcrumb.stories.js +40 -0
  130. package/src/stories/layout/CommonFooter.stories.js +22 -0
  131. package/src/stories/layout/CommonHeader.stories.js +39 -0
  132. package/src/stories/layout/LeftSideToggle.stories.js +78 -0
  133. package/src/stories/layout/LeftSidebar.stories.js +40 -0
  134. package/src/stories/layout/Main.stories.js +41 -0
  135. package/src/stories/layout/RightSidebar.stories.js +36 -0
  136. package/src/stories/layout/StorybookShell.vue +271 -0
  137. package/src/stories/layout/SuspendCommon.stories.js +67 -0
  138. package/src/stories/layout/SuspendCommonStage.vue +143 -0
  139. package/src/stories/mockData.js +275 -0
  140. package/src/stories/other/UserPop.stories.js +51 -0
  141. package/src/stories/single/Author.stories.js +19 -0
  142. package/src/stories/single/AuthorStoryStage.vue +103 -0
  143. package/src/stories/single/CmsSingle.stories.js +19 -0
  144. package/src/stories/single/CmsSingleStoryStage.vue +118 -0
  145. package/src/stories/single/Collection.stories.js +34 -0
  146. package/src/stories/single/Comment.stories.js +36 -0
  147. package/src/stories/single/Creators.stories.js +34 -0
  148. package/src/stories/single/PostCollection.stories.js +34 -0
  149. package/src/stories/single/PostDirectory.stories.js +31 -0
  150. package/src/stories/single/PostGuide.stories.js +47 -0
  151. package/src/stories/single/PostHeader.stories.js +39 -0
  152. package/src/stories/single/PostVersion.stories.js +41 -0
  153. package/src/stories/single/RightAffix.stories.js +84 -0
  154. package/src/stories/single/SimpleThx.stories.js +39 -0
  155. package/src/stories/single/SingleGallery.stories.js +207 -0
  156. package/src/stories/single/Thx.stories.js +38 -0
  157. package/vue.config.js +2 -12
  158. package/assets/css/common/bottom.less +0 -25
  159. package/assets/css/editor/article.less +0 -36
  160. package/assets/css/editor/combo.less +0 -362
  161. package/assets/css/editor/resource.less +0 -399
  162. package/assets/css/editor/tinymce.less +0 -100
  163. package/assets/css/editor/upload.less +0 -136
  164. package/assets/css/module/author.less +0 -231
  165. package/assets/css/module/buff.less +0 -88
  166. package/assets/css/module/directory.less +0 -165
  167. package/assets/css/module/icon.less +0 -25
  168. package/assets/css/module/item.less +0 -279
  169. package/assets/css/module/item_simple.less +0 -58
  170. package/assets/css/module/jx3_element.less +0 -5
  171. package/assets/css/module/macro.less +0 -89
  172. package/assets/css/module/npc.less +0 -265
  173. package/assets/css/module/resource.less +0 -93
  174. package/assets/css/module/skill.less +0 -74
  175. package/assets/css/module/talent.less +0 -495
  176. package/assets/js/a.js +0 -46
  177. package/assets/js/code.js +0 -13
  178. package/assets/js/combo.js +0 -40
  179. package/assets/js/directory.js +0 -114
  180. package/assets/js/filter2.js +0 -186
  181. package/assets/js/fold.js +0 -11
  182. package/assets/js/gallery.js +0 -14
  183. package/assets/js/hljs_languages.js +0 -177
  184. package/assets/js/iframe.js +0 -38
  185. package/assets/js/img.js +0 -23
  186. package/assets/js/item/attribute_percent.js +0 -88
  187. package/assets/js/item/bind.js +0 -18
  188. package/assets/js/item/border.js +0 -19
  189. package/assets/js/item/border_quest.js +0 -12
  190. package/assets/js/item/color.js +0 -25
  191. package/assets/js/item/hljs_languages.js +0 -177
  192. package/assets/js/item/icon_url.js +0 -15
  193. package/assets/js/item/second_format.js +0 -19
  194. package/assets/js/jx3_element.js +0 -73
  195. package/assets/js/katex.js +0 -181
  196. package/assets/js/macro.js +0 -16
  197. package/assets/js/nextpage.js +0 -4
  198. package/assets/js/pswp.js +0 -67
  199. package/assets/js/pswp_template.js +0 -66
  200. package/assets/js/pz_iframe.js +0 -30
  201. package/assets/js/qixue.js +0 -28
  202. package/assets/js/renderImgPreview.js +0 -18
  203. package/assets/js/script.js +0 -6
  204. package/assets/js/stat.js +0 -107
  205. package/assets/js/talent2.js +0 -21
  206. package/assets/js/tex-mml-chtml.js +0 -36310
  207. package/assets/js/voice.js +0 -238
  208. package/assets/js/xss.js +0 -130
  209. package/src/editor/Article.vue +0 -230
  210. package/src/editor/BoxResource.vue +0 -441
  211. package/src/editor/Resource.vue +0 -623
  212. package/src/editor/Tinymce.vue +0 -204
  213. package/src/editor/Upload.vue +0 -277
  214. package/src/editor/UploadAlum.vue +0 -176
  215. package/src/editor/UploadBanner.vue +0 -156
  216. package/src/editor/components/Author.vue +0 -322
  217. package/src/editor/components/Avatar.vue +0 -95
  218. package/src/editor/components/Buff.vue +0 -80
  219. package/src/editor/components/Combo.vue +0 -259
  220. package/src/editor/components/Equip.vue +0 -299
  221. package/src/editor/components/GameText.vue +0 -242
  222. package/src/editor/components/Item.vue +0 -325
  223. package/src/editor/components/ItemSimple.vue +0 -134
  224. package/src/editor/components/Medal.vue +0 -43
  225. package/src/editor/components/Npc.vue +0 -215
  226. package/src/editor/components/PostAuthor.vue +0 -102
  227. package/src/editor/components/Skill.vue +0 -71
@@ -1,33 +1,33 @@
1
1
  <template>
2
- <span class="w-filter-menu">
3
- <el-dropdown>
4
- <span class="el-dropdown-link">
5
- <span class="u-menu-label">
6
- <el-icon> <operation /> </el-icon>
7
- {{ value ? value : "资料片" }}
8
- <el-icon>
9
- <arrow-down />
10
- </el-icon>
11
- </span>
2
+ <el-dropdown class="w-filter-menu w-filter-zlp">
3
+ <span class="el-dropdown-link">
4
+ <span class="u-menu-label">
5
+ <el-icon> <operation /> </el-icon>
6
+ {{ value ? value : $jx3boxT("jx3boxUi.zlpBy.default", "资料片") }}
7
+ <el-icon>
8
+ <arrow-down />
9
+ </el-icon>
12
10
  </span>
13
- <template #dropdown>
14
- <el-dropdown-menu>
15
- <el-dropdown-item @click="filter('')">
16
- {{ "全部" }}
17
- </el-dropdown-item>
18
- <el-dropdown-item v-for="item in data" :key="item" @click="filter(item)">{{
19
- item
20
- }}</el-dropdown-item>
21
- </el-dropdown-menu>
22
- </template>
23
- </el-dropdown>
24
- </span>
11
+ </span>
12
+ <template #dropdown>
13
+ <el-dropdown-menu class="w-filter-zlp__list">
14
+ <el-dropdown-item @click="filter('')">
15
+ {{ $jx3boxT("jx3boxUi.zlpBy.all", "全部") }}
16
+ </el-dropdown-item>
17
+ <el-dropdown-item v-for="item in data" :key="item" @click="filter(item)">{{
18
+ item
19
+ }}</el-dropdown-item>
20
+ </el-dropdown-menu>
21
+ </template>
22
+ </el-dropdown>
25
23
  </template>
26
24
 
27
25
  <script>
28
26
  import zlps from "@jx3box/jx3box-common/data/jx3_zlp.json";
27
+ import i18nMixin from "../../i18n/mixin";
29
28
  export default {
30
29
  name: "zlpBy",
30
+ mixins: [i18nMixin],
31
31
  emits: ["filter"],
32
32
  props: {
33
33
  client: {
@@ -66,10 +66,14 @@ export default {
66
66
  .w-filter-menu {
67
67
  .pointer;
68
68
  .u-menu-label {
69
- i {
70
- .mr(5px);
71
- }
69
+ .flex;
70
+ align-items: center;
71
+ gap: 5px;
72
72
  .fz(12px);
73
73
  }
74
74
  }
75
+ .w-filter-zlp__list{
76
+ max-height: 200px;
77
+ overflow-y: auto;
78
+ }
75
79
  </style>
@@ -5,9 +5,9 @@
5
5
  >
6
6
  <div class="flex flex-wrap items-center justify-center gap-x-6 gap-y-2 md:justify-start">
7
7
  <span>{{
8
- $jx3boxT("jx3boxUi.footer.copyright", "© 2019-{year} JX3BOX {poweredBy}", {
8
+ $jx3boxT("jx3boxUi.commonFooter.copyright", "© 2019-{year} JX3BOX {poweredBy}", {
9
9
  year: new Date().getFullYear(),
10
- poweredBy: $jx3boxT("jx3boxUi.footer.poweredBy", "All rights reserved."),
10
+ poweredBy: $jx3boxT("jx3boxUi.commonFooter.poweredBy", "All rights reserved."),
11
11
  })
12
12
  }}</span>
13
13
  <a
@@ -16,7 +16,7 @@
16
16
  target="_blank"
17
17
  rel="noopener noreferrer"
18
18
  >
19
- {{ $jx3boxT("jx3boxUi.footer.icp", "湘ICP备2021002288号") }}
19
+ {{ $jx3boxT("jx3boxUi.commonFooter.icp", "湘ICP备2021002288号") }}
20
20
  </a>
21
21
  </div>
22
22
  <div class="mt-4 flex items-center space-x-6 md:mt-0">
@@ -26,7 +26,7 @@
26
26
  target="_blank"
27
27
  rel="noopener noreferrer"
28
28
  >
29
- {{ $jx3boxT("jx3boxUi.footer.contactUs", "联系我们") }}
29
+ {{ $jx3boxT("jx3boxUi.commonFooter.contactUs", "联系我们") }}
30
30
  </a>
31
31
  <a
32
32
  class="text-gray-500 transition-colors hover:text-white"
@@ -34,7 +34,7 @@
34
34
  target="_blank"
35
35
  rel="noopener noreferrer"
36
36
  >
37
- {{ $jx3boxT("jx3boxUi.footer.feedback", "反馈建议") }}
37
+ {{ $jx3boxT("jx3boxUi.commonFooter.feedback", "反馈建议") }}
38
38
  </a>
39
39
  </div>
40
40
  </div>
@@ -3,7 +3,7 @@
3
3
  <div class="grid grid-cols-1 gap-8 sm:grid-cols-3">
4
4
  <div v-for="group in footerGroups" :key="group.title">
5
5
  <h3 class="text-sm font-semibold tracking-wide text-white">
6
- {{ $jx3boxT(`jx3boxUi.footer.${group.key}`, group.title) }}
6
+ {{ $jx3boxT(`jx3boxUi.commonFooter.${group.key}`, group.title) }}
7
7
  </h3>
8
8
  <div class="mt-4 space-y-3">
9
9
  <a
@@ -14,7 +14,7 @@
14
14
  target="_blank"
15
15
  rel="noopener noreferrer"
16
16
  >
17
- {{ $jx3boxT(`jx3boxUi.footer.${item.key}`, item.name) }}
17
+ {{ $jx3boxT(`jx3boxUi.commonFooter.${item.key}`, item.name) }}
18
18
  </a>
19
19
  </div>
20
20
  </div>
@@ -123,7 +123,7 @@ export default {
123
123
  douyin: "douyin",
124
124
  };
125
125
  const tKey = map[item.key] || item.key;
126
- return this.$jx3boxT(`jx3boxUi.footer.${tKey}`, item.name || tKey);
126
+ return this.$jx3boxT(`jx3boxUi.commonFooter.${tKey}`, item.name || tKey);
127
127
  },
128
128
  },
129
129
  created: function () {},
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <section class="lg:col-span-4 lg:col-start-9">
3
3
  <h3 class="text-sm font-semibold tracking-wide text-white">
4
- {{ $jx3boxT("jx3boxUi.footer.downloadCenter", "下载中心") }}
4
+ {{ $jx3boxT("jx3boxUi.commonFooter.downloadCenter", "下载中心") }}
5
5
  </h3>
6
6
  <div class="mt-4 grid grid-cols-1 gap-3 sm:grid-cols-2">
7
7
  <div v-for="item in downloadLinks" :key="item.name">
@@ -17,9 +17,35 @@
17
17
  <template #reference>
18
18
  <a
19
19
  class="flex h-12 items-center rounded-xl border border-gray-700 bg-gray-800 px-4 text-xs text-gray-300 transition hover:border-blue-500 hover:bg-gray-700"
20
- :href="item.href || 'javascript:;'"
20
+ :href="item.href || '#'"
21
21
  :target="item.href ? '_blank' : null"
22
22
  :rel="item.href ? 'noopener noreferrer' : null"
23
+ @click="handleLinkClick($event, item)"
24
+ >
25
+ <span class="mr-2.5 flex h-4 w-4 items-center justify-center">
26
+ <img class="h-4 w-4" :src="item.icon" :alt="getDownloadName(item)" />
27
+ </span>
28
+ <span>{{ getDownloadName(item) }}</span>
29
+ </a>
30
+ </template>
31
+ </el-popover>
32
+ <el-popover
33
+ v-else-if="item.placeholder"
34
+ trigger="hover"
35
+ placement="top"
36
+ :show-after="150"
37
+ popper-class="c-footer--v4__popover"
38
+ >
39
+ <div class="p-3 text-center text-xs font-semibold">
40
+ {{ item.placeholder }}
41
+ </div>
42
+ <template #reference>
43
+ <a
44
+ class="flex h-12 items-center rounded-xl border border-gray-700 bg-gray-800 px-4 text-xs text-gray-300 transition hover:border-blue-500 hover:bg-gray-700"
45
+ :href="item.href || '#'"
46
+ :target="item.href ? '_blank' : null"
47
+ :rel="item.href ? 'noopener noreferrer' : null"
48
+ @click="handleLinkClick($event, item)"
23
49
  >
24
50
  <span class="mr-2.5 flex h-4 w-4 items-center justify-center">
25
51
  <img class="h-4 w-4" :src="item.icon" :alt="getDownloadName(item)" />
@@ -31,9 +57,10 @@
31
57
  <a
32
58
  v-else
33
59
  class="flex h-12 items-center rounded-xl border border-gray-700 bg-gray-800 px-4 text-xs text-gray-300 transition hover:border-blue-500 hover:bg-gray-700"
34
- :href="item.href || 'javascript:;'"
60
+ :href="item.href || '#'"
35
61
  :target="item.href ? '_blank' : null"
36
62
  :rel="item.href ? 'noopener noreferrer' : null"
63
+ @click="handleLinkClick($event, item)"
37
64
  >
38
65
  <span class="mr-2.5 flex h-4 w-4 items-center justify-center">
39
66
  <img class="h-4 w-4" :src="item.icon" :alt="getDownloadName(item)" />
@@ -59,12 +86,12 @@
59
86
  class="h-6 w-6"
60
87
  svg-inline
61
88
  src="../../assets/img/common/qqbot.svg"
62
- :alt="$jx3boxT('jx3boxUi.footer.qqBot', 'QQ机器人')"
89
+ :alt="$jx3boxT('jx3boxUi.commonFooter.qqBot', 'QQ机器人')"
63
90
  />
64
91
  </div>
65
92
  <div @click="copyText('3889010020')" class="cursor-pointer">
66
93
  <p class="font-bold uppercase tracking-wider text-gray-500" style="font-size: 10px">
67
- {{ $jx3boxT("jx3boxUi.footer.qqBotService", "QQ 机器人服务") }}
94
+ {{ $jx3boxT("jx3boxUi.commonFooter.qqBotService", "QQ 机器人服务") }}
68
95
  </p>
69
96
  <p class="mt-1 font-mono text-sm font-semibold text-white">3889 010 020</p>
70
97
  </div>
@@ -75,7 +102,7 @@
75
102
  target="_blank"
76
103
  rel="noopener noreferrer"
77
104
  >
78
- {{ $jx3boxT("jx3boxUi.footer.add", "添加") }}
105
+ {{ $jx3boxT("jx3boxUi.commonFooter.add", "添加") }}
79
106
  </a>
80
107
  </div>
81
108
  </section>
@@ -98,6 +125,7 @@ export default {
98
125
  href: "",
99
126
  icon: require("../../assets/img/common/ios.svg"),
100
127
  // qrcode: require("../../assets/img/common/ios.jpg"),
128
+ placeholder: "即将上线",
101
129
  },
102
130
  {
103
131
  key: "android",
@@ -105,6 +133,7 @@ export default {
105
133
  href: "",
106
134
  icon: require("../../assets/img/common/android.svg"),
107
135
  // qrcode: require("../../assets/img/common/android.jpg"),
136
+ placeholder: "即将上线",
108
137
  },
109
138
  {
110
139
  key: "harmonyNext",
@@ -112,6 +141,7 @@ export default {
112
141
  href: "",
113
142
  icon: require("../../assets/img/common/harmony.svg"),
114
143
  // qrcode: require("../../assets/img/common/harmony.jpg"),
144
+ placeholder: "即将上线",
115
145
  },
116
146
  {
117
147
  key: "miniProgram",
@@ -132,15 +162,18 @@ export default {
132
162
  getDownloadName(item) {
133
163
  if (item?.key) {
134
164
  const k = item.key === "harmonyNext" ? "harmonyNext" : item.key;
135
- const maybe = `jx3boxUi.footer.${k}`;
165
+ const maybe = `jx3boxUi.commonFooter.${k}`;
136
166
  return this.$jx3boxT(maybe, item.name || k);
137
167
  }
138
168
  return item?.name || "";
139
169
  },
140
170
  getDownloadLabel(item) {
141
- if (item?.labelKey) return this.$jx3boxT(`jx3boxUi.footer.${item.labelKey}`, item.label || item.labelKey);
171
+ if (item?.labelKey) return this.$jx3boxT(`jx3boxUi.commonFooter.${item.labelKey}`, item.label || item.labelKey);
142
172
  return item?.label || "";
143
173
  },
174
+ handleLinkClick(e, item) {
175
+ if (!item?.href) e.preventDefault();
176
+ },
144
177
  },
145
178
  created: function () {},
146
179
  mounted: function () {},
@@ -4,7 +4,7 @@
4
4
  v-model="visible"
5
5
  custom-class="c-alternate"
6
6
  width="320px"
7
- :title="$jx3boxT('jx3boxUi.alternate.title', '切换马甲')"
7
+ :title="$jx3boxT('jx3boxUi.commonHeader.alternate.title', '切换马甲')"
8
8
  >
9
9
  <div class="c-alternate__content">
10
10
  <div
@@ -20,14 +20,14 @@
20
20
  </div>
21
21
  <div class="m-misc">
22
22
  <span class="u-name"
23
- ><span class="u-label">{{ $jx3boxT("jx3boxUi.alternate.userNickname", "用户昵称:") }}</span
23
+ ><span class="u-label">{{ $jx3boxT("jx3boxUi.commonHeader.alternate.userNickname", "用户昵称:") }}</span
24
24
  >{{ item.name }}</span
25
25
  >
26
26
  <span class="u-time">
27
- <span class="u-label">{{ $jx3boxT("jx3boxUi.alternate.lastLogin", "上次登录:") }}</span
27
+ <span class="u-label">{{ $jx3boxT("jx3boxUi.commonHeader.alternate.lastLogin", "上次登录:") }}</span
28
28
  >{{ getFormatTime(item.created_at) }}
29
29
  <span class="u-extra" v-if="isExpired(item.created_at)">{{
30
- $jx3boxT("jx3boxUi.alternate.expired", "(已过期)")
30
+ $jx3boxT("jx3boxUi.commonHeader.alternate.expired", "(已过期)")
31
31
  }}</span>
32
32
  </span>
33
33
  </div>
@@ -75,11 +75,18 @@ export default {
75
75
  },
76
76
  },
77
77
  mounted() {
78
- Bus.on("showAlternate", () => {
78
+ this.__showAlternateHandler = () => {
79
79
  this.visible = true;
80
- });
80
+ };
81
+ Bus.on("showAlternate", this.__showAlternateHandler);
81
82
  this.init();
82
83
  },
84
+ beforeUnmount() {
85
+ if (this.__showAlternateHandler) {
86
+ Bus.off("showAlternate", this.__showAlternateHandler);
87
+ this.__showAlternateHandler = null;
88
+ }
89
+ },
83
90
  methods: {
84
91
  init() {
85
92
  // 获取localStorage中以jx3box-alternate-开头的数据
@@ -138,17 +145,23 @@ export default {
138
145
  // 选择马甲
139
146
  onSelectAlternate(item) {
140
147
  if (this.isExpired(item.created_at)) {
141
- this.$message.error(this.$jx3boxT("jx3boxUi.alternate.expiredNeedRelogin", "该马甲已过期,请重新登录"));
148
+ this.$message.error(
149
+ this.$jx3boxT("jx3boxUi.commonHeader.alternate.expiredNeedRelogin", "该马甲已过期,请重新登录")
150
+ );
142
151
  return;
143
152
  }
144
153
  if (this.profile.uid == item.uid) {
145
154
  return;
146
155
  }
147
- this.$confirm(this.$jx3boxT("jx3boxUi.alternate.switchConfirm", "确定要切换到该马甲吗?"), this.$jx3boxT("jx3boxUi.common.tip", "提示"), {
148
- confirmButtonText: this.$jx3boxT("jx3boxUi.common.confirm", "确定"),
149
- cancelButtonText: this.$jx3boxT("jx3boxUi.common.cancel", "取消"),
150
- type: "warning",
151
- })
156
+ this.$confirm(
157
+ this.$jx3boxT("jx3boxUi.commonHeader.alternate.switchConfirm", "确定要切换到该马甲吗?"),
158
+ this.$jx3boxT("jx3boxUi.common.tip", "提示"),
159
+ {
160
+ confirmButtonText: this.$jx3boxT("jx3boxUi.common.confirm", "确定"),
161
+ cancelButtonText: this.$jx3boxT("jx3boxUi.common.cancel", "取消"),
162
+ type: "warning",
163
+ }
164
+ )
152
165
  .then(() => {
153
166
  User.update(item).then(async () => {
154
167
  localStorage.setItem(
@@ -167,11 +180,15 @@ export default {
167
180
  },
168
181
  // 删除马甲
169
182
  onRemoveAlternate(item) {
170
- this.$confirm(this.$jx3boxT("jx3boxUi.alternate.deleteConfirm", "确定要删除该马甲吗?"), this.$jx3boxT("jx3boxUi.common.tip", "提示"), {
171
- confirmButtonText: this.$jx3boxT("jx3boxUi.common.confirm", "确定"),
172
- cancelButtonText: this.$jx3boxT("jx3boxUi.common.cancel", "取消"),
173
- type: "warning",
174
- })
183
+ this.$confirm(
184
+ this.$jx3boxT("jx3boxUi.commonHeader.alternate.deleteConfirm", "确定要删除该马甲吗?"),
185
+ this.$jx3boxT("jx3boxUi.common.tip", "提示"),
186
+ {
187
+ confirmButtonText: this.$jx3boxT("jx3boxUi.common.confirm", "确定"),
188
+ cancelButtonText: this.$jx3boxT("jx3boxUi.common.cancel", "取消"),
189
+ type: "warning",
190
+ }
191
+ )
175
192
  .then(() => {
176
193
  localStorage.removeItem("jx3box-alternate-" + item.uid);
177
194
 
@@ -182,7 +199,7 @@ export default {
182
199
  // 新增马甲
183
200
  onAddAlternate() {
184
201
  if (this.overLength) {
185
- this.$message.error(this.$jx3boxT("jx3boxUi.alternate.maxFive", "最多只能添加5个马甲"));
202
+ this.$message.error(this.$jx3boxT("jx3boxUi.commonHeader.alternate.maxFive", "最多只能添加5个马甲"));
186
203
  return;
187
204
  }
188
205
  // 跳转至登录页
@@ -5,7 +5,7 @@
5
5
  class="u-icon"
6
6
  svg-inline
7
7
  src="../../assets/img/common/coin.svg"
8
- :alt="$jx3boxT('jx3boxUi.header.asset', '资产')"
8
+ :alt="$jx3boxT('jx3boxUi.commonHeader.asset', '资产')"
9
9
  />
10
10
  </a>
11
11
 
@@ -14,7 +14,7 @@
14
14
  <span class="u-item">
15
15
  <a class="u-item-primary" href="/about/incentives" :target="target">
16
16
  <span class="u-label"
17
- ><el-icon><User /></el-icon> {{ $jx3boxT("jx3boxUi.header.level", "等级") }}</span
17
+ ><el-icon><User /></el-icon> {{ $jx3boxT("jx3boxUi.commonHeader.level", "等级") }}</span
18
18
  >
19
19
  <span class="u-value u-level" :style="levelStyle">Lv.{{ level }}</span>
20
20
  </a>
@@ -23,49 +23,39 @@
23
23
  <span class="u-item">
24
24
  <a class="u-item-primary" href="/dashboard/boxcoin" :target="target"
25
25
  ><span class="u-label"
26
- ><el-icon><Coin /></el-icon> {{ $jx3boxT("jx3boxUi.header.boxCoin", "盒币") }}</span
26
+ ><el-icon><Coin /></el-icon> {{ $jx3boxT("jx3boxUi.commonHeader.boxCoin", "盒币") }}</span
27
27
  >
28
28
  <span class="u-value">{{ asset.box_coin }}</span></a
29
29
  >
30
30
  <span class="u-item-extend"
31
31
  ><a href="/dashboard/boxcoin" :target="target"
32
- >[{{ $jx3boxT("jx3boxUi.header.exchangeTongbao", "兑换通宝") }}]</a
32
+ >[{{ $jx3boxT("jx3boxUi.commonHeader.exchangeTongbao", "兑换通宝") }}]</a
33
33
  ></span
34
34
  >
35
35
  </span>
36
- <!-- <span class="u-item">
37
- <a class="u-item-primary" href="/dashboard/cny" :target="target"
38
- ><span class="u-label"><i class="el-icon-wallet"></i> 金箔</span
39
- ><span class="u-value">{{ asset.cny }}</span></a
40
- >
41
- <span class="u-item-extend"
42
- ><a href="/vip/cny" :target="target">[充值]</a>
43
- <a href="/dashboard/cny" :target="target">[提现]</a></span
44
- >
45
- </span> -->
46
36
  <span class="u-item">
47
37
  <a class="u-item-primary" href="/dashboard/points" :target="target"
48
38
  ><span class="u-label"
49
- ><el-icon><Sugar /></el-icon> {{ $jx3boxT("jx3boxUi.header.points", "积分") }}</span
39
+ ><el-icon><Sugar /></el-icon> {{ $jx3boxT("jx3boxUi.commonHeader.points", "积分") }}</span
50
40
  >
51
41
  <span class="u-value">{{ asset.points }}</span></a
52
42
  >
53
43
  <span class="u-item-extend"
54
- ><a href="/vip/mall" :target="target">[{{ $jx3boxT("jx3boxUi.header.redeem", "兑礼") }}]</a
44
+ ><a href="/vip/mall" :target="target">[{{ $jx3boxT("jx3boxUi.commonHeader.redeem", "兑礼") }}]</a
55
45
  ><a href="/vip/lottery" :target="target"
56
- >[{{ $jx3boxT("jx3boxUi.header.lottery", "抽奖") }}]</a
46
+ >[{{ $jx3boxT("jx3boxUi.commonHeader.lottery", "抽奖") }}]</a
57
47
  ></span
58
48
  >
59
49
  </span>
60
50
  <span class="u-item">
61
51
  <a class="u-item-primary" href="/dashboard/card" :target="target"
62
52
  ><span class="u-label"
63
- ><el-icon><CreditCard /></el-icon> {{ $jx3boxT("jx3boxUi.header.card", "卡密") }}</span
53
+ ><el-icon><CreditCard /></el-icon> {{ $jx3boxT("jx3boxUi.commonHeader.card", "卡密") }}</span
64
54
  >
65
55
  <span class="u-value">{{ asset.ext_info ? asset.ext_info.keycode : 0 }}</span></a
66
56
  >
67
57
  <span class="u-item-extend"
68
- ><a href="/dashboard/card" :target="target">[{{ $jx3boxT("jx3boxUi.header.view", "查看") }}]</a></span
58
+ ><a href="/dashboard/card" :target="target">[{{ $jx3boxT("jx3boxUi.commonHeader.view", "查看") }}]</a></span
69
59
  >
70
60
  </span>
71
61
  </div>
@@ -9,20 +9,19 @@
9
9
  <a class="u-item" href="/index">
10
10
  <img class="u-pic" svg-inline :src="homeicon" />
11
11
  <img class="u-pic-hover" svg-inline :src="homeicon" />
12
- <span class="u-txt">{{ $jx3boxT("jx3boxUi.header.home", "首页") }}</span>
12
+ <span class="u-txt">{{ $jx3boxT("jx3boxUi.commonHeader.home", "首页") }}</span>
13
13
  </a>
14
14
  </li>
15
15
  <li v-for="(item, i) in list" :key="i" :class="{ 'u-app-start': item.lf }">
16
16
  <a class="u-item" :href="item.href" :target="getTarget(item.href)">
17
17
  <img class="u-pic" :src="getBoxIcon(item.img)" />
18
- <!-- <img class="u-pic-hover" svg-inline :src="item.hover | getBoxIcon" /> -->
19
18
  <span class="u-txt">{{ item.abbr }}</span>
20
19
  </a>
21
20
  </li>
22
21
  </ul>
23
22
  <span class="u-close" @click="closeBox($event)">
24
- <i class="el-icon-upload2"></i>
25
- <span>{{ $jx3boxT("jx3boxUi.header.collapse", "收起") }}</span>
23
+ <el-icon><Upload /></el-icon>
24
+ <span>{{ $jx3boxT("jx3boxUi.commonHeader.collapse", "收起") }}</span>
26
25
  </span>
27
26
  </div>
28
27
  </template>
@@ -126,16 +125,29 @@ export default {
126
125
  this.loadMenu();
127
126
  },
128
127
  mounted: function () {
129
- Bus.on("toggleBox", (status) => {
128
+ this.__toggleBoxHandler = (status) => {
130
129
  if (status == undefined) {
131
130
  this.status = !this.status;
132
131
  } else {
133
132
  this.status = status;
134
133
  }
135
- });
136
- document.addEventListener("click", function () {
134
+ };
135
+ Bus.on("toggleBox", this.__toggleBoxHandler);
136
+
137
+ this.__docClickHandler = () => {
137
138
  Bus.emit("toggleBox", false);
138
- });
139
+ };
140
+ document.addEventListener("click", this.__docClickHandler);
141
+ },
142
+ beforeUnmount() {
143
+ if (this.__toggleBoxHandler) {
144
+ Bus.off("toggleBox", this.__toggleBoxHandler);
145
+ this.__toggleBoxHandler = null;
146
+ }
147
+ if (this.__docClickHandler) {
148
+ document.removeEventListener("click", this.__docClickHandler);
149
+ this.__docClickHandler = null;
150
+ }
139
151
  },
140
152
  components: {
141
153
  "header-search": search,
@@ -10,15 +10,20 @@
10
10
  <img svg-inline src="../../assets/img/common/logo.svg" alt="JX3BOX" />
11
11
  </div>
12
12
  <div>
13
- <h2 class="u-title">魔盒矩阵</h2>
13
+ <h2 class="u-title">{{ $jx3boxT("jx3boxUi.box2.title", "魔盒矩阵") }}</h2>
14
14
  <p class="u-subtitle">THE BOX MATRIX NAVIGATION</p>
15
15
  </div>
16
16
  </div>
17
17
  <div class="u-search">
18
- <i class="el-icon-search u-search-icon"></i>
19
- <input v-model.trim="searchQuery" class="u-search-input" type="text" placeholder="搜索应用" />
18
+ <el-icon class="u-search-icon"><Search></Search></el-icon>
19
+ <input
20
+ v-model.trim="searchQuery"
21
+ class="u-search-input"
22
+ type="text"
23
+ :placeholder="$jx3boxT('jx3boxUi.box2.searchPlaceholder', '搜索应用')"
24
+ />
20
25
  <button v-if="searchQuery" class="u-search-clear" type="button" @click="searchQuery = ''">
21
- <i class="el-icon-close"></i>
26
+ <el-icon><Close /></el-icon>
22
27
  </button>
23
28
  </div>
24
29
  </div>
@@ -30,7 +35,7 @@
30
35
  <div class="u-icon-wrap">
31
36
  <img class="u-pic" svg-inline :src="homeicon" />
32
37
  </div>
33
- <span class="u-txt">{{ $jx3boxT("jx3boxUi.header.home", "首页") }}</span>
38
+ <span class="u-txt">{{ $jx3boxT("jx3boxUi.commonHeader.home", "首页") }}</span>
34
39
  </a>
35
40
  </li>
36
41
  <li v-for="(item, i) in filteredList" :key="i">
@@ -46,12 +51,12 @@
46
51
  <div class="u-icon-wrap">
47
52
  <img class="u-pic" svg-inline :src="allicon" />
48
53
  </div>
49
- <span class="u-txt">{{ $jx3boxT("jx3boxUi.header.all", "全部") }}</span>
54
+ <span class="u-txt">{{ $jx3boxT("jx3boxUi.commonHeader.all", "全部") }}</span>
50
55
  </a>
51
56
  </li>
52
57
  </ul>
53
58
  <div v-if="searchQuery && !homeMatched && filteredList.length === 0" class="u-empty">
54
- 未找到匹配应用
59
+ {{ $jx3boxT("jx3boxUi.box2.empty", "未找到匹配应用") }}
55
60
  </div>
56
61
  </div>
57
62
  </section>
@@ -92,11 +97,16 @@ export default {
92
97
  return this.data.filter((item) => {
93
98
  const currentClient = String(this.client || "").toLowerCase();
94
99
  const rawClient = item.client;
95
- const matchedClient = !rawClient
96
- ? true
100
+ const clients = !rawClient
101
+ ? []
97
102
  : Array.isArray(rawClient)
98
- ? rawClient.map((c) => String(c || "").toLowerCase()).includes(currentClient)
99
- : String(rawClient || "").toLowerCase().includes(currentClient);
103
+ ? rawClient.map((c) => String(c || "").toLowerCase())
104
+ : String(rawClient || "")
105
+ .split(",")
106
+ .map((c) => String(c || "").trim().toLowerCase())
107
+ .filter(Boolean);
108
+ const matchedClient =
109
+ !clients.length || clients.includes("all") || clients.includes(currentClient);
100
110
  return matchedClient;
101
111
  });
102
112
  },
@@ -115,12 +125,12 @@ export default {
115
125
  homeMatched: function () {
116
126
  const query = (this.searchQuery || "").toLowerCase().trim();
117
127
  if (!query) return true;
118
- return this.$jx3boxT("jx3boxUi.header.home", "首页").includes(query);
128
+ return this.$jx3boxT("jx3boxUi.commonHeader.home", "首页").includes(query);
119
129
  },
120
130
  allMatched: function () {
121
131
  const query = (this.searchQuery || "").toLowerCase().trim();
122
132
  if (!query) return true;
123
- return this.$jx3boxT("jx3boxUi.header.all", "全部").includes(query);
133
+ return this.$jx3boxT("jx3boxUi.commonHeader.all", "全部").includes(query);
124
134
  },
125
135
  },
126
136
  methods: {
@@ -329,6 +339,8 @@ export default {
329
339
  width: min(460px, 100%);
330
340
  margin-left: auto;
331
341
  position: relative;
342
+ .flex;
343
+ align-items: center;
332
344
  }
333
345
 
334
346
  .u-search-input {