@jx3box/jx3box-editor 2.2.48 → 3.0.0

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 (175) hide show
  1. package/config/global.js +79 -0
  2. package/config/global.less +16 -0
  3. package/index.js +21 -8
  4. package/package.json +64 -63
  5. package/readme.md +25 -99
  6. package/src/Article.vue +96 -57
  7. package/src/ArticleMarkdown.vue +54 -47
  8. package/src/BoxResource.vue +67 -42
  9. package/src/Buff.vue +18 -7
  10. package/src/GameText.vue +32 -45
  11. package/src/Item.vue +143 -235
  12. package/src/ItemSimple.vue +27 -37
  13. package/src/Markdown.vue +362 -210
  14. package/src/Npc.vue +51 -30
  15. package/src/Resource.vue +296 -252
  16. package/src/Skill.vue +36 -26
  17. package/src/Tinymce.vue +124 -137
  18. package/src/Upload.vue +238 -155
  19. package/src/UploadAlbum.vue +189 -118
  20. package/{assets → src/assets}/css/article.less +1 -0
  21. package/src/assets/css/markdown.less +4 -0
  22. package/{assets → src/assets}/css/module/author.less +4 -3
  23. package/{assets → src/assets}/css/module/directory.less +23 -32
  24. package/{assets → src/assets}/css/module/talent.less +2 -2
  25. package/{assets → src/assets}/css/resource.less +56 -22
  26. package/src/assets/css/tinymce/_.less +28 -0
  27. package/src/assets/css/tinymce/a.less +21 -0
  28. package/{assets → src/assets}/css/tinymce/code.less +1 -1
  29. package/{assets/css → src/assets/css/tinymce}/combo.less +123 -18
  30. package/{assets → src/assets}/css/tinymce/fold.less +3 -6
  31. package/src/assets/css/tinymce/h.less +90 -0
  32. package/{assets → src/assets}/css/tinymce/latex.less +14 -14
  33. package/{assets → src/assets}/css/tinymce/macro.less +3 -3
  34. package/{assets → src/assets}/css/tinymce/pz.less +2 -2
  35. package/{assets → src/assets}/css/tinymce/table.less +5 -10
  36. package/{assets → src/assets}/css/tinymce.less +8 -4
  37. package/src/assets/css/upload.less +195 -0
  38. package/src/assets/css/upload_album.less +164 -0
  39. package/src/assets/css/var.less +2 -0
  40. package/src/assets/img/other/qr-code.svg +1 -0
  41. package/{assets → src/assets}/js/audio.js +2 -2
  42. package/{assets → src/assets}/js/directory.js +51 -23
  43. package/src/assets/js/hljs_languages.js +177 -0
  44. package/src/assets/js/katex.js +211 -0
  45. package/src/assets/js/renderImgPreview.js +49 -0
  46. package/{assets → src/assets}/js/xss.js +48 -5
  47. package/src/components/Author.vue +32 -13
  48. package/src/components/Avatar.vue +22 -3
  49. package/src/components/Combo.vue +118 -72
  50. package/src/components/PostAuthor.vue +13 -11
  51. package/src/components/QRcode.vue +136 -0
  52. package/src/components/SkillMartial.vue +13 -12
  53. package/src/pages/article.js +14 -0
  54. package/src/pages/index.js +5 -0
  55. package/src/pages/markdown.js +14 -0
  56. package/src/pages/tinymce.js +49 -0
  57. package/src/pages/upload.js +14 -0
  58. package/{service → src/service}/author.js +2 -2
  59. package/{service → src/service}/cms.js +5 -3
  60. package/{service → src/service}/database.js +4 -2
  61. package/{service → src/service}/item.js +1 -1
  62. package/{service → src/service}/node.js +1 -1
  63. package/{service → src/service}/resource.js +1 -1
  64. package/src/views/article.vue +72 -0
  65. package/src/views/index.vue +11 -0
  66. package/src/views/markdown.vue +58 -0
  67. package/src/views/tinymce.vue +58 -0
  68. package/src/views/upload.vue +111 -0
  69. package/.env +0 -2
  70. package/.vscode/settings.json +0 -5
  71. package/assets/css/katex-fix.css +0 -20
  72. package/assets/css/tinymce/_.less +0 -30
  73. package/assets/css/tinymce/a.less +0 -30
  74. package/assets/css/tinymce/combo.less +0 -111
  75. package/assets/css/tinymce/h.less +0 -58
  76. package/assets/css/upload.less +0 -105
  77. package/assets/js/katex.js +0 -191
  78. package/assets/js/renderImgPreview.js +0 -25
  79. package/babel.config.js +0 -3
  80. package/docs/markdown.md +0 -16
  81. package/jsconfig.json +0 -9
  82. package/public/article.html +0 -15
  83. package/public/css/article.css +0 -2481
  84. package/public/css/article.less +0 -3
  85. package/public/favicon.ico +0 -0
  86. package/public/tinymce.html +0 -33
  87. package/src/Equip.vue +0 -301
  88. package/src/components/LetterDemo.vue +0 -93
  89. package/src/components/medal.vue +0 -43
  90. package/test-audio.html +0 -121
  91. package/vue.config.js +0 -147
  92. /package/{assets → src/assets}/css/markdown/_.less +0 -0
  93. /package/{assets → src/assets}/css/markdown/macro.less +0 -0
  94. /package/{assets/css/article_markdown.less → src/assets/css/markdown/markdown-article.less} +0 -0
  95. /package/{assets/css/markdown.less → src/assets/css/markdown/markdown-editor.less} +0 -0
  96. /package/{assets → src/assets}/css/markdown/talent.less +0 -0
  97. /package/{assets → src/assets}/css/markdown/video.less +0 -0
  98. /package/{assets → src/assets}/css/module/buff.less +0 -0
  99. /package/{assets → src/assets}/css/module/icon.less +0 -0
  100. /package/{assets → src/assets}/css/module/item.less +0 -0
  101. /package/{assets → src/assets}/css/module/item_simple.less +0 -0
  102. /package/{assets → src/assets}/css/module/jx3_element.less +0 -0
  103. /package/{assets → src/assets}/css/module/macro.less +0 -0
  104. /package/{assets → src/assets}/css/module/npc.less +0 -0
  105. /package/{assets → src/assets}/css/module/resource.less +0 -0
  106. /package/{assets → src/assets}/css/module/skill.less +0 -0
  107. /package/{assets → src/assets}/css/tinymce/hr.less +0 -0
  108. /package/{assets → src/assets}/css/tinymce/img.less +0 -0
  109. /package/{assets → src/assets}/css/tinymce/imgpreview.less +0 -0
  110. /package/{assets → src/assets}/css/tinymce/list.less +0 -0
  111. /package/{assets → src/assets}/css/tinymce/nextpage.less +0 -0
  112. /package/{assets → src/assets}/css/tinymce/p.less +0 -0
  113. /package/{assets → src/assets}/css/tinymce/plugin.less +0 -0
  114. /package/{assets → src/assets}/css/tinymce/qixue.less +0 -0
  115. /package/{assets → src/assets}/css/tinymce/quote.less +0 -0
  116. /package/{assets → src/assets}/css/tinymce/video.less +0 -0
  117. /package/{assets → src/assets}/css/tinymce/voice.less +0 -0
  118. /package/{assets → src/assets}/data/detach_type.json +0 -0
  119. /package/{assets → src/assets}/data/game_font.json +0 -0
  120. /package/{assets → src/assets}/data/markdown_whitelist.json +0 -0
  121. /package/{assets → src/assets}/data/weapon_type.json +0 -0
  122. /package/{assets → src/assets}/img/buff.svg +0 -0
  123. /package/{assets → src/assets}/img/equip_bg.png +0 -0
  124. /package/{assets → src/assets}/img/file.svg +0 -0
  125. /package/{assets → src/assets}/img/icons.svg +0 -0
  126. /package/{assets → src/assets}/img/item/pve.png +0 -0
  127. /package/{assets → src/assets}/img/item/pvp.png +0 -0
  128. /package/{assets → src/assets}/img/item/pvx.png +0 -0
  129. /package/{assets → src/assets}/img/item/std.png +0 -0
  130. /package/{assets → src/assets}/img/item/wujie.png +0 -0
  131. /package/{assets → src/assets}/img/item.svg +0 -0
  132. /package/{assets → src/assets}/img/jx3.svg +0 -0
  133. /package/{assets → src/assets}/img/jx3box.svg +0 -0
  134. /package/{assets → src/assets}/img/npc/attack.svg +0 -0
  135. /package/{assets → src/assets}/img/npc/buff.svg +0 -0
  136. /package/{assets → src/assets}/img/npc/energy.svg +0 -0
  137. /package/{assets → src/assets}/img/npc/miss.svg +0 -0
  138. /package/{assets → src/assets}/img/npc/npc.svg +0 -0
  139. /package/{assets → src/assets}/img/npc/radar.svg +0 -0
  140. /package/{assets → src/assets}/img/npc/shield.svg +0 -0
  141. /package/{assets → src/assets}/img/npc/sight.svg +0 -0
  142. /package/{assets → src/assets}/img/npc/skull.svg +0 -0
  143. /package/{assets → src/assets}/img/npc/target.svg +0 -0
  144. /package/{assets → src/assets}/img/skill.svg +0 -0
  145. /package/{assets → src/assets}/img/skillset.png +0 -0
  146. /package/{assets → src/assets}/js/a.js +0 -0
  147. /package/{assets → src/assets}/js/code.js +0 -0
  148. /package/{assets → src/assets}/js/combo.js +0 -0
  149. /package/{assets → src/assets}/js/drag.js +0 -0
  150. /package/{assets → src/assets}/js/filter2.js +0 -0
  151. /package/{assets → src/assets}/js/fold.js +0 -0
  152. /package/{assets → src/assets}/js/gallery.js +0 -0
  153. /package/{assets → src/assets}/js/iframe.js +0 -0
  154. /package/{assets → src/assets}/js/img.js +0 -0
  155. /package/{assets → src/assets}/js/item/attribute_percent.js +0 -0
  156. /package/{assets → src/assets}/js/item/bind.js +0 -0
  157. /package/{assets → src/assets}/js/item/border.js +0 -0
  158. /package/{assets → src/assets}/js/item/border_quest.js +0 -0
  159. /package/{assets → src/assets}/js/item/color.js +0 -0
  160. /package/{assets → src/assets}/js/item/hljs_languages.js +0 -0
  161. /package/{assets → src/assets}/js/item/icon_url.js +0 -0
  162. /package/{assets → src/assets}/js/item/second_format.js +0 -0
  163. /package/{assets → src/assets}/js/jx3_element.js +0 -0
  164. /package/{assets → src/assets}/js/macro.js +0 -0
  165. /package/{assets → src/assets}/js/nextpage.js +0 -0
  166. /package/{assets → src/assets}/js/pswp.js +0 -0
  167. /package/{assets → src/assets}/js/pswp_template.js +0 -0
  168. /package/{assets → src/assets}/js/pz_iframe.js +0 -0
  169. /package/{assets → src/assets}/js/qixue.js +0 -0
  170. /package/{assets → src/assets}/js/script.js +0 -0
  171. /package/{assets → src/assets}/js/talent2.js +0 -0
  172. /package/{assets → src/assets}/js/tex-mml-chtml.js +0 -0
  173. /package/{service → src/service}/enum/CollectionPublic.js +0 -0
  174. /package/{service → src/service}/enum/EquipPosition.js +0 -0
  175. /package/{service → src/service}/enum/EquipType.js +0 -0
package/src/Resource.vue CHANGED
@@ -1,19 +1,19 @@
1
1
  <template>
2
2
  <div class="c-resource">
3
3
  <!-- 上传触发按钮 -->
4
- <el-button class="u-switch" type="primary" @click="openDialog" :disabled="!enable"> <img class="u-icon" svg-inline src="../assets/img/jx3.svg" />剑三资源 </el-button>
4
+ <el-button class="u-switch" type="primary" @click="openDialog" :disabled="!enable"> <img class="u-icon" svg-inline src="./assets/img/jx3.svg" />剑三资源 </el-button>
5
5
 
6
6
  <!-- 弹出界面 -->
7
- <el-dialog class="c-large-dialog" title="剑三数据库" :visible.sync="dialogVisible" v-draggable>
7
+ <el-dialog class="c-large-dialog" title="剑三数据库" v-model="dialogVisible" draggable>
8
8
  <div class="c-resource-content" v-loading="loading">
9
9
  <div class="m-database-search">
10
- <el-radio-group class="u-client" v-model="client" @change="search">
11
- <el-radio-button label="std">重制</el-radio-button>
12
- <el-radio-button label="origin">缘起</el-radio-button>
10
+ <el-radio-group class="u-client" v-model="client" @change="search" size="large">
11
+ <el-radio-button value="std">重制</el-radio-button>
12
+ <el-radio-button value="origin">缘起</el-radio-button>
13
13
  </el-radio-group>
14
- <el-input class="u-input" placeholder="请输入 ID 或 名称" v-model="query" @change="search" @keyup.enter.native="search">
15
- <template slot="prepend">ID /名称</template>
16
- <template slot="append" v-if="isPC">
14
+ <el-input size="large" class="u-input" placeholder="请输入 ID 或 名称" v-model="query" @change="search" @keyup.enter="search">
15
+ <template #prepend>ID /名称</template>
16
+ <template #append v-if="isPC">
17
17
  <el-switch v-model="strict" active-text="精确匹配" @change="search" title="仅对Buff/Skill有效"></el-switch>
18
18
  </template>
19
19
  </el-input>
@@ -21,26 +21,36 @@
21
21
 
22
22
  <el-tabs class="m-database-tabs" v-model="type" type="card" @tab-click="changeType">
23
23
  <el-tab-pane label="Buff" name="buff">
24
- <span slot="label" class="u-tab-label">
25
- <img class="u-icon" svg-inline src="../assets/img/buff.svg" />
26
- <b>Buff</b>
27
- <em class="u-count">{{ stat.buff }}</em>
28
- </span>
24
+ <template #label>
25
+ <span class="u-tab-label">
26
+ <img class="u-icon" svg-inline src="./assets/img/buff.svg" />
27
+ <b>Buff</b>
28
+ <em class="u-count">{{ stat.buff }}</em>
29
+ </span>
30
+ </template>
29
31
  <div v-if="total && done" class="m-resource-count">
30
- <i class="el-icon-s-data"></i> 共找到 <b>{{ total }}</b> 条记录
32
+ <el-icon><Histogram /></el-icon>
33
+ 共找到 <b>{{ total }}</b> 条记录
31
34
  <div class="u-mode">
32
35
  插入模式:
33
- <el-radio-group v-model="buff_mode" size="mini" @change="changeMode">
34
- <el-radio-button label="simple">简版</el-radio-button>
35
- <el-radio-button label="full">完整版</el-radio-button>
36
+ <el-radio-group v-model="buff_mode" size="small" @change="changeMode">
37
+ <el-radio-button value="simple">简版</el-radio-button>
38
+ <el-radio-button value="full">完整版</el-radio-button>
36
39
  </el-radio-group>
37
40
  </div>
38
41
  </div>
39
42
  <ul class="m-resource-list">
40
- <li v-for="(o, i) in buff" class="u-item" :key="i" :class="{ on: !!o.isSelected }" @click="selectBuff(o, i)" ref="buff">
43
+ <li
44
+ v-for="(o, i) in buff"
45
+ :key="o.BuffID || i"
46
+ class="u-item"
47
+ :class="{ on: !!o.isSelected }"
48
+ @click="selectBuff(o, i)"
49
+ :ref="(el) => setResultItemRef('buff', i, el)"
50
+ >
41
51
  <span class="u-id">
42
52
  ID:{{ o.BuffID }}
43
- <span class="u-detach">{{ o.DetachType | showDetachType }}</span>
53
+ <span class="u-detach">{{ showDetachType(o.DetachType) }}</span>
44
54
  </span>
45
55
  <img class="u-pic" :title="'IconID:' + o.IconID" :src="iconURL(o.IconID)" />
46
56
  <span class="u-primary">
@@ -55,23 +65,33 @@
55
65
  <el-alert v-if="!buff.length && done" title="没有找到相关条目" type="info" show-icon></el-alert>
56
66
  </el-tab-pane>
57
67
  <el-tab-pane label="技能" name="skill">
58
- <span slot="label" class="u-tab-label">
59
- <img class="u-icon" svg-inline src="../assets/img/skill.svg" />
60
- <b>技能</b>
61
- <em class="u-count">{{ stat.skill }}</em>
62
- </span>
68
+ <template #label>
69
+ <span class="u-tab-label">
70
+ <img class="u-icon" svg-inline src="./assets/img/skill.svg" />
71
+ <b>技能</b>
72
+ <em class="u-count">{{ stat.skill }}</em>
73
+ </span>
74
+ </template>
63
75
  <div v-if="total && done" class="m-resource-count">
64
- <i class="el-icon-s-data"></i> 共找到 <b>{{ total }}</b> 条记录
76
+ <el-icon><Histogram /></el-icon>
77
+ 共找到 <b>{{ total }}</b> 条记录
65
78
  <div class="u-mode">
66
79
  插入模式:
67
- <el-radio-group v-model="skill_mode" size="mini" @change="changeMode">
68
- <el-radio-button label="simple">简版</el-radio-button>
69
- <el-radio-button label="full">完整版</el-radio-button>
80
+ <el-radio-group v-model="skill_mode" size="small" @change="changeMode">
81
+ <el-radio-button value="simple">简版</el-radio-button>
82
+ <el-radio-button value="full">完整版</el-radio-button>
70
83
  </el-radio-group>
71
84
  </div>
72
85
  </div>
73
86
  <ul class="m-resource-list">
74
- <li v-for="(o, i) in skill" class="u-item" :key="i" :class="{ on: !!o.isSelected }" @click="selectSkill(o, i)" ref="skill">
87
+ <li
88
+ v-for="(o, i) in skill"
89
+ :key="o.SkillID || i"
90
+ class="u-item"
91
+ :class="{ on: !!o.isSelected }"
92
+ @click="selectSkill(o, i)"
93
+ :ref="(el) => setResultItemRef('skill', i, el)"
94
+ >
75
95
  <span class="u-id">ID:{{ o.SkillID }}</span>
76
96
  <img class="u-pic" :title="'IconID:' + o.IconID" :src="iconURL(o.IconID)" />
77
97
  <span class="u-primary">
@@ -80,7 +100,7 @@
80
100
  <em v-if="o.SkillName">({{ o.SkillName }})</em>
81
101
  </span>
82
102
  <span class="u-content">
83
- {{ o.Desc | filterRaw }}
103
+ {{ filterRaw(o.Desc) }}
84
104
  </span>
85
105
  </span>
86
106
  </li>
@@ -88,27 +108,32 @@
88
108
  <el-alert v-if="!skill.length && done" title="没有找到相关条目" type="info" show-icon></el-alert>
89
109
  </el-tab-pane>
90
110
  <el-tab-pane label="物品" name="item">
91
- <span slot="label" class="u-tab-label">
92
- <img class="u-icon" svg-inline src="../assets/img/item.svg" />
93
- <b>物品</b>
94
- <em class="u-count">{{ stat.item }}</em>
95
- </span>
111
+ <template #label>
112
+ <span class="u-tab-label">
113
+ <img class="u-icon" svg-inline src="./assets/img/item.svg" />
114
+ <b>物品</b>
115
+ <em class="u-count">{{ stat.item }}</em>
116
+ </span>
117
+ </template>
96
118
  <p v-if="total && done" class="m-resource-count">
97
- <i class="el-icon-s-data"></i> 共找到 <b>{{ total }}</b> 条记录
119
+ <el-icon><Histogram /></el-icon>
120
+ 共找到 <b>{{ total }}</b> 条记录
98
121
  </p>
99
122
  <ul class="m-resource-list" v-if="item.length">
100
123
  <el-popover popper-class="m-item-pop" :visible-arrow="false" trigger="hover" placement="left" v-for="(o, i) in item" :key="o.id">
101
- <li slot="reference" class="u-item" :class="{ on: o.isSelected }" @click="selectItem(o, i)" ref="item">
102
- <span class="u-id">ID:{{ o.id }}</span>
103
- <img class="u-pic" :title="'IconID:' + o.IconID" :src="iconURL(o.IconID)" />
104
- <span class="u-name">{{ o.Name }}</span>
105
- <span class="u-content">
106
- <game-text :text="o.Desc"></game-text>
107
- </span>
108
- <span class="u-remark">
109
- {{ o.Requirement }}
110
- </span>
111
- </li>
124
+ <template #reference>
125
+ <li class="u-item" :class="{ on: o.isSelected }" @click="selectItem(o, i)" :ref="(el) => setResultItemRef('item', i, el)">
126
+ <span class="u-id">ID:{{ o.id }}</span>
127
+ <img class="u-pic" :title="'IconID:' + o.IconID" :src="iconURL(o.IconID)" />
128
+ <span class="u-name">{{ o.Name }}</span>
129
+ <span class="u-content">
130
+ <game-text :text="o.Desc"></game-text>
131
+ </span>
132
+ <span class="u-remark">
133
+ {{ o.Requirement }}
134
+ </span>
135
+ </li>
136
+ </template>
112
137
 
113
138
  <jx3-item :item_id="o.id" :client="client"></jx3-item>
114
139
  </el-popover>
@@ -116,16 +141,26 @@
116
141
  <el-alert v-if="!item.length && done" title="没有找到相关条目" type="info" show-icon></el-alert>
117
142
  </el-tab-pane>
118
143
  <el-tab-pane label="Npc" name="npc">
119
- <span slot="label" class="u-tab-label">
120
- <img class="u-icon" svg-inline src="../assets/img/npc/skull.svg" />
121
- <b>Npc</b>
122
- <em class="u-count">{{ stat.npc }}</em>
123
- </span>
144
+ <template #label>
145
+ <span class="u-tab-label">
146
+ <img class="u-icon" svg-inline src="./assets/img/npc/skull.svg" />
147
+ <b>Npc</b>
148
+ <em class="u-count">{{ stat.npc }}</em>
149
+ </span>
150
+ </template>
124
151
  <p v-if="total && done" class="m-resource-count">
125
- <i class="el-icon-s-data"></i> 共找到 <b>{{ total }}</b> 条记录
152
+ <el-icon><Histogram /></el-icon>
153
+ 共找到 <b>{{ total }}</b> 条记录
126
154
  </p>
127
155
  <ul class="m-resource-list" v-if="npc.length">
128
- <li v-for="(o, i) in npc" :key="i" class="u-item" :class="{ on: o.isSelected }" @click="selectNpc(o, i)" ref="item">
156
+ <li
157
+ v-for="(o, i) in npc"
158
+ :key="o.ID || i"
159
+ class="u-item"
160
+ :class="{ on: o.isSelected }"
161
+ @click="selectNpc(o, i)"
162
+ :ref="(el) => setResultItemRef('npc', i, el)"
163
+ >
129
164
  <span class="u-id">ID:{{ o.ID }}</span>
130
165
  <img class="u-pic" :title="'IconID:' + o.IconID" :src="iconURL(o.IconID)" />
131
166
  <span class="u-name">
@@ -145,16 +180,26 @@
145
180
  <el-alert v-if="!npc.length && done" title="没有找到相关条目" type="info" show-icon></el-alert>
146
181
  </el-tab-pane>
147
182
  <el-tab-pane label="图标" name="icon">
148
- <span slot="label" class="u-tab-label">
149
- <img class="u-icon" svg-inline src="../assets/img/icons.svg" />
150
- <b>图标</b>
151
- <em class="u-count">{{ stat.icon }}</em>
152
- </span>
183
+ <template #label>
184
+ <span class="u-tab-label">
185
+ <img class="u-icon" svg-inline src="./assets/img/icons.svg" />
186
+ <b>图标</b>
187
+ <em class="u-count">{{ stat.icon }}</em>
188
+ </span>
189
+ </template>
153
190
  <p v-if="icon.length && done" class="m-resource-count">
154
- <i class="el-icon-s-data"></i> 共找到 <b>{{ icon.length }}</b> 条记录
191
+ <el-icon><Histogram /></el-icon>
192
+ 共找到 <b>{{ icon.length }}</b> 条记录
155
193
  </p>
156
194
  <ul class="m-resource-iconlist">
157
- <li v-for="(o, i) in icon" class="u-item" :key="i" :class="{ on: !!o.isSelected }" @click="selectIcon(o)" ref="icon">
195
+ <li
196
+ v-for="(o, i) in icon"
197
+ :key="o.iconID || i"
198
+ class="u-item"
199
+ :class="{ on: !!o.isSelected }"
200
+ @click="selectIcon(o)"
201
+ :ref="(el) => setResultItemRef('icon', i, el)"
202
+ >
158
203
  <!-- <el-tooltip
159
204
  effect="dark"
160
205
  :content="o.Name || query"
@@ -170,7 +215,7 @@
170
215
 
171
216
  <template v-if="multipage">
172
217
  <!-- 下一页 -->
173
- <el-button class="m-archive-more" :class="{ show: hasNextPage }" type="primary" icon="el-icon-arrow-down" @click="appendPage">加载更多</el-button>
218
+ <el-button class="m-archive-more" :class="{ show: hasNextPage }" type="primary" icon="ArrowDown" @click="appendPage" size="large">加载更多</el-button>
174
219
  <!-- 分页 -->
175
220
  <el-pagination
176
221
  class="m-archive-pages"
@@ -179,7 +224,7 @@
179
224
  :hide-on-single-page="true"
180
225
  :page-size="per"
181
226
  :total="total"
182
- :current-page.sync="page"
227
+ v-model:current-page="page"
183
228
  @current-change="changePage"
184
229
  ></el-pagination>
185
230
  </template>
@@ -188,52 +233,66 @@
188
233
  </div>
189
234
 
190
235
  <!-- 插入按钮 -->
191
- <span slot="footer" class="dialog-footer">
192
- <el-button @click="dialogVisible = false">取 消</el-button>
193
- <el-button type="primary" @click="insert">
194
- {{ buttonTXT }}
195
- </el-button>
196
- </span>
236
+ <template #footer>
237
+ <span class="dialog-footer">
238
+ <el-button @click="dialogVisible = false" size="large">取 消</el-button>
239
+ <el-button type="primary" @click="insert" size="large">
240
+ {{ buttonTXT }}
241
+ </el-button>
242
+ </span>
243
+ </template>
197
244
  </el-dialog>
198
245
  </div>
199
246
  </template>
200
247
 
201
248
  <script>
202
- import { loadResource, loadStat, getIcons } from "../service/database";
203
- import { loadEmotions } from "../service/cms";
204
- import { __iconPath, __Root, __OriginRoot } from "@jx3box/jx3box-common/data/jx3box.json";
205
- import detach_types from "../assets/data/detach_type.json";
206
- import { iconLink, getLink, showAvatar } from "@jx3box/jx3box-common/js/utils";
249
+ import { ArrowDown, Histogram } from "@element-plus/icons-vue";
250
+ import { loadResource, loadStat, getIcons } from "./service/database";
251
+ import JX3BOX from "@jx3box/jx3box-common/data/jx3box.json";
252
+ import detach_types from "./assets/data/detach_type.json";
253
+ import { iconLink, getLink as resolveLink } from "@jx3box/jx3box-common/js/utils";
207
254
  import GameText from "./GameText.vue";
208
- import User from "@jx3box/jx3box-common/js/user";
209
- import Item from './Item.vue';
255
+ import Item from "./Item.vue";
256
+
257
+ const { __iconPath, __Root, __OriginRoot } = JX3BOX;
258
+ const RESULT_REF_TYPES = ["buff", "skill", "item", "icon", "npc"];
259
+
260
+ const createResultItemRefs = () =>
261
+ RESULT_REF_TYPES.reduce((refs, type) => {
262
+ refs[type] = [];
263
+ return refs;
264
+ }, {});
265
+
210
266
  export default {
211
267
  name: "Resource",
268
+ components: {
269
+ ArrowDown,
270
+ Histogram,
271
+ GameText,
272
+ Jx3Item: Item,
273
+ },
212
274
  props: {
213
275
  enable: {
214
276
  type: Boolean,
215
277
  default: true,
216
278
  },
217
279
  },
218
- data: function() {
280
+ emits: ["insert", "update"],
281
+ data() {
219
282
  return {
220
283
  dialogVisible: false,
221
284
  actived: false,
222
- userInfo: {},
223
285
 
224
286
  type: "buff",
225
287
  query: "",
226
288
  strict: false,
227
- client: location.hostname.includes("origin") ? "origin" : "std",
289
+ client: window.location.hostname.includes("origin") ? "origin" : "std",
228
290
 
229
291
  skill: [],
230
292
  buff: [],
231
293
  item: [],
232
294
  icon: [],
233
295
  npc: [],
234
- authors: [],
235
- selectedAuthor: {},
236
- emotions: [],
237
296
 
238
297
  stat: {
239
298
  skill: 0,
@@ -246,283 +305,268 @@ export default {
246
305
  done: false,
247
306
  loading: false,
248
307
 
249
- isSuper: false,
250
-
251
308
  html: "",
252
- isPC: true,
309
+ isPC: window.innerWidth > 720,
253
310
 
254
311
  per: 10,
255
312
  page: 1,
256
- total: 1,
313
+ total: 0,
257
314
  pages: 1,
258
315
 
259
316
  buff_mode: "simple",
260
317
  skill_mode: "simple",
318
+
319
+ resultItemRefs: createResultItemRefs(),
261
320
  };
262
321
  },
263
322
  computed: {
264
- buttonTXT: function() {
323
+ buttonTXT() {
265
324
  return this.selectedCount ? "插 入" : "确 定";
266
325
  },
267
- isBlank: function() {
268
- return !this.query && !this[this.type]["length"];
326
+ currentList() {
327
+ return Array.isArray(this[this.type]) ? this[this.type] : [];
269
328
  },
270
- selectedCount: function() {
271
- return !!this.html;
329
+ isBlank() {
330
+ return !this.query && !this.currentList.length;
272
331
  },
273
- isNumber: function() {
274
- return !isNaN(this.query);
332
+ selectedCount() {
333
+ return Boolean(this.html);
275
334
  },
276
- hasNextPage: function() {
335
+ hasNextPage() {
277
336
  return this.total > 1 && this.page < this.pages;
278
337
  },
279
- multipage: function() {
338
+ multipage() {
280
339
  return this.type !== "icon" && this.done && this.pages > 1;
281
340
  },
282
- iconDir: function() {
283
- return this.client == "origin" ? "origin_icon" : "icon";
341
+ iconDir() {
342
+ return this.client === "origin" ? "origin_icon" : "icon";
284
343
  },
285
- userStatus: function (){
286
- return User.getInfo().status
287
- },
288
- uid: function (){
289
- return User.getInfo().uid
290
- },
291
- canInsertAuthor: function() {
292
- return User.getLevel(this.userInfo && this.userInfo.experience) >= 2;
293
- }
294
344
  },
295
345
  watch: {
296
- html: function(newval) {
297
- this.$emit("update", newval);
346
+ html(newValue) {
347
+ this.$emit("update", newValue);
298
348
  },
299
- client: function() {
300
- loadStat({client: this.client}).then((data) => {
301
- this.stat = data;
302
- this.actived = true;
303
- });
349
+ client() {
350
+ void this.fetchStat();
304
351
  },
305
352
  },
353
+ created() {
354
+ this.checkUA();
355
+ },
356
+ mounted() {
357
+ window.addEventListener("resize", this.checkUA, { passive: true });
358
+ },
359
+ beforeUpdate() {
360
+ RESULT_REF_TYPES.forEach((type) => {
361
+ this.resultItemRefs[type] = [];
362
+ });
363
+ },
364
+ beforeUnmount() {
365
+ window.removeEventListener("resize", this.checkUA);
366
+ },
306
367
  methods: {
307
- nl2br: function(str) {
368
+ async fetchStat() {
369
+ const data = await loadStat({ client: this.client });
370
+ if (!data) return;
371
+
372
+ this.stat = data;
373
+ this.actived = true;
374
+ },
375
+ resetResultState(type = this.type) {
376
+ if (Array.isArray(this[type])) {
377
+ this[type] = [];
378
+ }
379
+ this.total = 0;
380
+ this.pages = 1;
381
+ this.loading = false;
382
+ this.done = false;
383
+ },
384
+ setResultItemRef(type, index, el) {
385
+ if (!RESULT_REF_TYPES.includes(type) || !el) return;
386
+ this.resultItemRefs[type][index] = el;
387
+ },
388
+ getResultItemHtml(type, index) {
389
+ return this.resultItemRefs[type]?.[index]?.innerHTML ?? "";
390
+ },
391
+ nl2br(str = "") {
308
392
  // 替换\n \\\n 为 <br>
309
- return str.replace(/\\n/g, "<br>").replace(/\n/g, "<br>");
393
+ return String(str).replace(/\\n/g, "<br>").replace(/\n/g, "<br>");
310
394
  },
311
- getData: function(page = 1, append = false) {
312
- if (!this.query) return;
395
+ async getData(page = 1, append = false) {
396
+ const query = this.query.trim();
397
+ if (!query) {
398
+ this.resetResultState();
399
+ return;
400
+ }
313
401
 
314
402
  this.loading = true;
315
403
  this.per = 10;
316
404
  this.done = false;
317
- let query = this.query;
318
405
  let params = {
319
406
  strict: ~~this.strict,
320
407
  per: this.per,
321
- page: page,
408
+ page,
322
409
  client: this.client,
323
410
  };
324
411
 
325
- // 图标
326
- if (this.type == "icon") {
327
- if (isNaN(query)) {
328
- getIcons(query, params)
329
- .then((data) => {
330
- this.icon = data;
331
- })
332
- .finally(() => {
333
- this.done = true;
334
- this.loading = false;
335
- });
412
+ try {
413
+ if (this.type === "icon") {
414
+ if (isNaN(query)) {
415
+ const data = await getIcons(query, params);
416
+ this.icon = Array.isArray(data) ? data : [];
417
+ } else {
418
+ this.icon = [
419
+ {
420
+ iconID: Number.parseInt(query, 10),
421
+ isSelected: false,
422
+ },
423
+ ];
424
+ }
425
+ this.total = this.icon.length;
426
+ this.pages = 1;
336
427
  } else {
337
- let arr = [
338
- {
339
- iconID: ~~this.query,
340
- isSelected: false,
341
- },
342
- ];
343
- this.icon = arr;
344
- this.done = true;
345
- this.loading = false;
346
- }
428
+ const data = await loadResource(this.type, query, params);
429
+ if (!append) this[this.type] = [];
430
+
431
+ if (!data) {
432
+ this.total = 0;
433
+ this.pages = 1;
434
+ return;
435
+ }
347
436
 
348
- } else if (this.type === 'emotions') {
349
- this.per = 30;
350
- params = {
351
- per: this.per,
352
- page: page,
353
- search: query,
437
+ let list = [];
438
+ if (this.type === "item") {
439
+ list = this.transformData(data.data || []);
440
+ this.total = data.total || 0;
441
+ this.pages = data.per_page ? Math.ceil(data.total / data.per_page) : 1;
442
+ } else {
443
+ list = this.transformData(data.list || []);
444
+ this.pages = data.pages || 1;
445
+ this.total = data.total || 0;
446
+ }
447
+ this[this.type] = this[this.type].concat(list);
354
448
  }
355
- loadEmotions(params)
356
- .then((res) => {
357
- if (!append) this.emotions = [];
358
- let list = this.transformData(res.data.data.list)
359
- this.emotions = this.emotions.concat(list);
360
- this.pages = res.data.data.pages;
361
- this.total = res.data.data.total;
362
- })
363
- .finally(() => {
364
- this.done = true;
365
- this.loading = false;
366
- });
367
- } else {
368
- // 非图标
369
- loadResource(this.type, query, params)
370
- .then((data) => {
371
- if (!append) this[this.type] = [];
372
- let list;
373
- if (this.type == "item") {
374
- list = this.transformData(data.data);
375
- this.total = data.total;
376
- this.pages = Math.ceil(data.total / data.per_page);
377
- } else {
378
- list = this.transformData(data.list || []);
379
- this.pages = data.pages;
380
- this.total = data.total;
381
- }
382
- this[this.type] = this[this.type].concat(list);
383
- })
384
- .finally(() => {
385
- this.done = true;
386
- this.loading = false;
387
- });
449
+ } finally {
450
+ this.done = true;
451
+ this.loading = false;
388
452
  }
389
453
  },
390
- search: function() {
454
+ search() {
391
455
  this.page = 1;
392
- this.getData();
456
+ void this.getData();
393
457
  },
394
- appendPage: function() {
395
- this.getData(++this.page, true);
458
+ appendPage() {
459
+ if (!this.hasNextPage) return;
460
+ this.page += 1;
461
+ void this.getData(this.page, true);
396
462
  },
397
- changePage: function(i) {
398
- this.getData(i);
463
+ changePage(page) {
464
+ this.page = page;
465
+ void this.getData(page);
399
466
  },
400
- changeType: function() {
467
+ changeType(tab) {
468
+ const nextType = tab?.paneName || tab?.props?.name || tab?.name || this.type;
469
+ this.type = nextType;
401
470
  this.page = 1;
402
- this.getData();
471
+ this.resetItems();
472
+ this.resetResultState(this.type);
473
+ if (!this.query.trim()) return;
474
+ void this.getData();
403
475
  },
404
- insert: function() {
476
+ insert() {
405
477
  this.$emit("insert", this.html);
406
478
  this.dialogVisible = false;
407
479
  },
408
- transformData: function(data) {
409
- data.forEach((item) => {
410
- item.isSelected = false;
411
- });
412
- return data;
480
+ transformData(data = []) {
481
+ return data.map((item) => ({
482
+ ...item,
483
+ isSelected: false,
484
+ }));
413
485
  },
414
- changeMode: function() {
486
+ changeMode() {
415
487
  this.resetItems();
416
488
  },
417
- selectBuff: function(o, i) {
489
+ selectBuff(o, i) {
418
490
  this.resetItems();
419
491
  o.isSelected = true;
420
- if (this.buff_mode == "simple") {
421
- // <img src="${this.iconURL(
422
- // o.IconID
423
- // )}">
424
- this.html = `<a data-type="buff" class="e-jx3-buff w-jx3-element ${o.CanCancel == 1 ? "isBuff" : "isDebuff"}" href="${this.getDbLink(
492
+ if (this.buff_mode === "simple") {
493
+ this.html = `<a data-type="buff" class="e-jx3-buff w-jx3-element ${o.CanCancel === 1 ? "isBuff" : "isDebuff"}" href="${this.getDbLink(
425
494
  "buff",
426
495
  this.client,
427
496
  o.BuffID,
428
497
  o.Level
429
498
  )}" data-client="${this.client}" data-id="${o.BuffID}" data-level="${o.Level}">[${o.Name}]</a>`;
430
499
  } else {
431
- this.html = `<pre data-type="buff" data-id="${o.BuffID}" class="e-jx3-resource">${this.nl2br(this.$refs[this.type][i]["innerHTML"])}</pre>`;
500
+ this.html = `<pre data-type="buff" data-id="${o.BuffID}" class="e-jx3-resource">${this.nl2br(this.getResultItemHtml("buff", i))}</pre>`;
432
501
  }
433
502
  },
434
- selectSkill: function(o, i) {
503
+ selectSkill(o, i) {
435
504
  this.resetItems();
436
505
  o.isSelected = true;
437
- if (this.skill_mode == "simple") {
506
+ if (this.skill_mode === "simple") {
438
507
  this.html = `<a data-type="skill" class="e-jx3-skill w-jx3-element" href="${this.getDbLink("skill", this.client, o.SkillID, o.Level)}" data-client="${this.client}" data-id="${
439
508
  o.SkillID
440
509
  }" data-level="${o.Level}">[${o.Name}]</a>`;
441
510
  } else {
442
- this.html = `<pre data-type="skill" data-id="${o.SkillID}" class="e-jx3-resource">${this.nl2br(this.$refs[this.type][i]["innerHTML"])}</pre>`;
511
+ this.html = `<pre data-type="skill" data-id="${o.SkillID}" class="e-jx3-resource">${this.nl2br(this.getResultItemHtml("skill", i))}</pre>`;
443
512
  }
444
513
  },
445
- selectItem: function(o, i) {
514
+ selectItem(o) {
446
515
  this.resetItems();
447
516
  o.isSelected = true;
448
- this.html = `<a data-type="item" class="e-jx3-item e-jx3-item-q${o.Quality} w-jx3-element" data-mode="" data-id="${o.id}" data-quality="${o.Quality}" data-client="${this.client}" target="_blank" href="${this.getLink('item', o.id)}">[${o.Name}]</a>`;
517
+ this.html = `<a data-type="item" class="e-jx3-item e-jx3-item-q${o.Quality} w-jx3-element" data-mode="" data-id="${o.id}" data-quality="${o.Quality}" data-client="${this.client}" target="_blank" href="${this.getLink("item", o.id)}">[${o.Name}]</a>`;
449
518
  },
450
- selectIcon: function(o) {
519
+ selectIcon(o) {
451
520
  this.resetItems();
452
521
  o.isSelected = true;
453
522
  this.html = `<img class="e-jx3-icon" src="${__iconPath}${this.iconDir}/${o.iconID}.png" alt="${o.iconID}"/>`;
454
523
  },
455
- selectNpc: function (o, i){
456
- this.resetItems()
457
- o.isSelected = true
458
- this.html = `<a data-type="npc" class="e-jx3-npc w-jx3-element" data-mode="" data-id="${o.ID}" data-client="${this.client}" target="_blank" href="${this.getDbLink("npc", this.client, o.ID, '')}">${o.Name}]</a>`
459
- },
460
- selectEmotion: function (o){
524
+ selectNpc(o) {
461
525
  this.resetItems();
462
526
  o.isSelected = true;
463
- this.html = `<img class="e-jx3-emotion" style="width:80px;" src="${o.url}" alt="${o.id}"/>`
527
+ this.html = `<a data-type="npc" class="e-jx3-npc w-jx3-element" data-mode="" data-id="${o.ID}" data-client="${this.client}" target="_blank" href="${this.getDbLink("npc", this.client, o.ID)}">[${o.Name}]</a>`;
464
528
  },
465
- resetItems: function() {
466
- let data = this[this.type];
467
- data.forEach((item) => {
529
+ resetItems() {
530
+ this.currentList.forEach((item) => {
468
531
  item.isSelected = false;
469
532
  });
470
533
  this.html = "";
471
534
  },
472
- checkUA: function() {
535
+ checkUA() {
473
536
  this.isPC = window.innerWidth > 720;
474
537
  },
475
- iconURL: function(id) {
538
+ iconURL(id) {
476
539
  return iconLink(id, this.client);
477
540
  },
478
- getDbLink: function(type, client, id, level) {
479
- let domain = client == "origin" ? __OriginRoot : __Root;
480
- return domain + "app/database/?type=" + type + `&query=${id}&level=${level}`;
541
+ getDbLink(type, client, id, level = "") {
542
+ const domain = client === "origin" ? __OriginRoot : __Root;
543
+ return `${domain}app/database/?type=${type}&query=${id}&level=${level}`;
544
+ },
545
+ getLink(type, id) {
546
+ const domain = this.client === "origin" ? __OriginRoot : __Root;
547
+ return domain + resolveLink(type, id).slice(1);
481
548
  },
482
- getLink : function (type,id){
483
- let domain = this.client == "origin" ? __OriginRoot : __Root;
484
- return domain + getLink(type,id).slice(1)
549
+ filterRaw(str) {
550
+ return str?.replace(/\\n/g, "\n") ?? "";
485
551
  },
486
- userAvatar: function(url) {
487
- return showAvatar(url,'m');
552
+ showDetachType(val) {
553
+ return val && detach_types[val] ? detach_types[val] : "";
488
554
  },
489
555
 
490
556
  // 杂项
491
557
  // ==============================
492
- openDialog: function() {
558
+ async openDialog() {
493
559
  this.dialogVisible = true;
494
560
  if (!this.actived) {
495
- loadStat({client: this.client}).then((data) => {
496
- this.stat = data;
497
- this.actived = true;
498
- });
499
- }
500
- },
501
- },
502
- filters: {
503
- filterRaw: function(str) {
504
- return str && str.replace(/\\n/g, "\n");
505
- },
506
- showDetachType: function(val) {
507
- if (val && detach_types[val]) {
508
- return detach_types[val];
509
- } else {
510
- return "";
561
+ await this.fetchStat();
511
562
  }
512
563
  },
513
564
  },
514
- created: function() {
515
- this.checkUA();
516
- },
517
- components: {
518
- 'jx3-item': Item,
519
- GameText
520
- },
521
565
  };
522
566
  </script>
523
567
 
524
568
  <style lang="less">
525
- @import "../assets/css/resource.less";
569
+ @import "./assets/css/resource.less";
526
570
 
527
571
  .m-item-pop {
528
572
  padding: 0 !important;