@jx3box/jx3box-ui 2.0.5 → 2.0.7

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 (241) hide show
  1. package/.storybook/preview.js +22 -13
  2. package/.storybook/storybookMocks.js +214 -0
  3. package/README.md +39 -43
  4. package/assets/css/bread/admin.less +20 -2
  5. package/assets/css/bread/breadcrumb.less +5 -2
  6. package/assets/css/comment/quick-reply.less +1 -1
  7. package/assets/css/common/left-sidebar.less +1 -1
  8. package/assets/css/interact/like2.less +5 -2
  9. package/assets/css/interact/qrcode.less +69 -0
  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/css/wiki/wiki-comments.less +176 -0
  14. package/assets/css/wiki/wiki-panel.less +177 -0
  15. package/assets/css/wiki/wiki-revisions.less +62 -0
  16. package/assets/data/nav.json +344 -10
  17. package/assets/img/comment/comment.svg +1 -1
  18. package/assets/img/comment/heart_1.svg +1 -1
  19. package/assets/img/comment/hide.svg +1 -1
  20. package/assets/img/leftsidebar/medal.svg +1 -1
  21. package/assets/img/leftsidebar/post.svg +27 -46
  22. package/i18n/messages/en-US.js +357 -22
  23. package/i18n/messages/vi.js +350 -22
  24. package/i18n/messages/zh-CN.js +469 -20
  25. package/i18n/messages/zh-TW.js +350 -22
  26. package/index.js +19 -7
  27. package/package.json +8 -5
  28. package/service/cms.js +22 -0
  29. package/service/commit-history.js +18 -0
  30. package/service/community.js +60 -0
  31. package/service/fav.js +5 -6
  32. package/src/App.vue +210 -80
  33. package/src/Breadcrumb.vue +24 -11
  34. package/src/CommonFooter.vue +2 -2
  35. package/src/Footer.vue +13 -5
  36. package/src/LeftSideToggle.vue +10 -3
  37. package/src/LeftSidebar.vue +19 -5
  38. package/src/Main.vue +9 -2
  39. package/src/RightSidebar.vue +12 -3
  40. package/src/SuspendCommon.vue +52 -38
  41. package/src/author/AuthorFans.vue +7 -5
  42. package/src/author/AuthorFollow.vue +14 -7
  43. package/src/author/AuthorGift.vue +25 -17
  44. package/src/author/AuthorInfo.vue +46 -19
  45. package/src/author/AuthorLink.vue +3 -1
  46. package/src/author/AuthorMedals.vue +5 -2
  47. package/src/author/AuthorPosts.vue +31 -13
  48. package/src/author/AuthorRss.vue +7 -3
  49. package/src/author/AuthorTeams.vue +3 -1
  50. package/src/author/UserPop.vue +29 -17
  51. package/src/bread/Admin.vue +55 -32
  52. package/src/bread/AdminDirectMessage.vue +15 -8
  53. package/src/bread/AdminDrop.vue +124 -45
  54. package/src/bread/CommunityAdmin.vue +527 -0
  55. package/src/bread/DesignTask.vue +30 -26
  56. package/src/bread/ListAdmin.vue +199 -0
  57. package/src/bread/MigrateCommunity.vue +192 -0
  58. package/src/bread/MoveToCommunityDialog.vue +234 -0
  59. package/src/comment/Avatar.vue +18 -24
  60. package/src/comment/CommentContent.vue +57 -37
  61. package/src/comment/CommentContentSimple.vue +61 -63
  62. package/src/comment/CommentInputForm.vue +45 -34
  63. package/src/comment/CommentWithReply.vue +9 -6
  64. package/src/comment/QuickReply.vue +5 -1
  65. package/src/comment/ReplyForReply.vue +6 -4
  66. package/src/comment/ReplyList.vue +28 -18
  67. package/src/comment/Upload.vue +24 -6
  68. package/src/filters/clientBy.vue +10 -8
  69. package/src/filters/markBy.vue +35 -31
  70. package/src/filters/menuBy.vue +20 -22
  71. package/src/filters/orderBy.vue +17 -11
  72. package/src/filters/tagBy.vue +4 -2
  73. package/src/filters/topicBy.vue +12 -10
  74. package/src/filters/versionBy.vue +5 -3
  75. package/src/filters/zlpBy.vue +29 -25
  76. package/src/footer/copyright.vue +5 -5
  77. package/src/footer/links.vue +2 -2
  78. package/src/footer/official.vue +1 -1
  79. package/src/footer/resource.vue +6 -6
  80. package/src/header/alternate.vue +35 -18
  81. package/src/header/asset.vue +9 -19
  82. package/src/header/box.vue +20 -8
  83. package/src/header/box2.vue +16 -9
  84. package/src/header/client.vue +7 -7
  85. package/src/header/lang.vue +41 -6
  86. package/src/header/logo.vue +2 -3
  87. package/src/header/manage.vue +2 -2
  88. package/src/header/message.vue +3 -3
  89. package/src/header/nav.vue +26 -23
  90. package/src/header/publish.vue +2 -2
  91. package/src/header/search.vue +2 -2
  92. package/src/header/shop.vue +2 -2
  93. package/src/header/user.vue +4 -4
  94. package/src/header/userInfo.vue +22 -24
  95. package/src/header/vip.vue +2 -2
  96. package/src/interact/BoxcoinAdmin.vue +30 -16
  97. package/src/interact/BoxcoinRecords.vue +28 -11
  98. package/src/interact/BoxcoinUser.vue +33 -17
  99. package/src/interact/Fav.vue +5 -1
  100. package/src/interact/Homework.vue +317 -0
  101. package/src/interact/Like.vue +4 -2
  102. package/src/interact/QRcode.vue +104 -0
  103. package/src/interact/Rss.vue +10 -4
  104. package/src/interact/Share.vue +18 -19
  105. package/src/interact/WatchLater.vue +5 -1
  106. package/src/main.js +1 -0
  107. package/src/single/Author.vue +5 -1
  108. package/src/single/CmsSingle.vue +29 -15
  109. package/src/single/Collection.vue +36 -26
  110. package/src/single/Comment.vue +19 -13
  111. package/src/single/Creators.vue +5 -3
  112. package/src/single/PostCollection.vue +158 -0
  113. package/src/single/PostDirectory.vue +0 -126
  114. package/src/single/PostGuide.vue +93 -0
  115. package/src/single/PostHeader.vue +39 -17
  116. package/src/single/PostTopic.vue +3 -3
  117. package/src/single/PostVersion.vue +219 -0
  118. package/src/single/RightAffix.vue +160 -0
  119. package/src/single/SimpleThx.vue +4 -2
  120. package/src/single/Thx.vue +14 -2
  121. package/src/single/VersionDialog.vue +238 -0
  122. package/src/stories/components/StoryPropsTable.vue +137 -0
  123. package/src/stories/filters/FilterGallery.stories.js +110 -0
  124. package/src/stories/filters/clientBy.stories.js +24 -0
  125. package/src/stories/filters/markBy.stories.js +6 -0
  126. package/src/stories/filters/menuBy.stories.js +6 -0
  127. package/src/stories/filters/orderBy.stories.js +6 -0
  128. package/src/stories/filters/tagBy.stories.js +6 -0
  129. package/src/stories/filters/topicBy.stories.js +6 -0
  130. package/src/stories/filters/versionBy.stories.js +6 -0
  131. package/src/stories/filters/zlpBy.stories.js +6 -0
  132. package/src/stories/interact/QRcode.stories.js +59 -0
  133. package/src/stories/layout/BaseShell.stories.js +38 -0
  134. package/src/stories/layout/Breadcrumb.stories.js +40 -0
  135. package/src/stories/layout/CommonFooter.stories.js +1 -1
  136. package/src/stories/layout/CommonHeader.stories.js +1 -1
  137. package/src/stories/layout/LeftSideToggle.stories.js +78 -0
  138. package/src/stories/layout/LeftSidebar.stories.js +40 -0
  139. package/src/stories/layout/Main.stories.js +41 -0
  140. package/src/stories/layout/RightSidebar.stories.js +36 -0
  141. package/src/stories/layout/StorybookShell.vue +271 -0
  142. package/src/stories/layout/SuspendCommon.stories.js +67 -0
  143. package/src/stories/layout/SuspendCommonStage.vue +143 -0
  144. package/src/stories/mockData.js +369 -0
  145. package/src/stories/other/UserPop.stories.js +51 -0
  146. package/src/stories/single/Author.stories.js +19 -0
  147. package/src/stories/single/AuthorStoryStage.vue +103 -0
  148. package/src/stories/single/CmsSingle.stories.js +19 -0
  149. package/src/stories/single/CmsSingleStoryStage.vue +118 -0
  150. package/src/stories/single/Collection.stories.js +34 -0
  151. package/src/stories/single/Comment.stories.js +36 -0
  152. package/src/stories/single/Creators.stories.js +34 -0
  153. package/src/stories/single/PostCollection.stories.js +34 -0
  154. package/src/stories/single/PostDirectory.stories.js +31 -0
  155. package/src/stories/single/PostGuide.stories.js +47 -0
  156. package/src/stories/single/PostHeader.stories.js +39 -0
  157. package/src/stories/single/PostVersion.stories.js +41 -0
  158. package/src/stories/single/RightAffix.stories.js +84 -0
  159. package/src/stories/single/SimpleThx.stories.js +39 -0
  160. package/src/stories/single/SingleGallery.stories.js +207 -0
  161. package/src/stories/single/Thx.stories.js +38 -0
  162. package/src/stories/wiki/GamePrice.stories.js +64 -0
  163. package/src/stories/wiki/WikiComments.stories.js +58 -0
  164. package/src/stories/wiki/WikiPanel.stories.js +69 -0
  165. package/src/stories/wiki/WikiRevisions.stories.js +47 -0
  166. package/src/wiki/GamePrice.vue +107 -0
  167. package/src/wiki/WikiComment.vue +153 -0
  168. package/src/wiki/WikiComments.vue +206 -0
  169. package/src/wiki/WikiPanel.vue +121 -0
  170. package/src/wiki/WikiRevisions.vue +125 -0
  171. package/vue.config.js +2 -12
  172. package/assets/css/common/bottom.less +0 -25
  173. package/assets/css/editor/article.less +0 -36
  174. package/assets/css/editor/combo.less +0 -362
  175. package/assets/css/editor/resource.less +0 -399
  176. package/assets/css/editor/tinymce.less +0 -100
  177. package/assets/css/editor/upload.less +0 -136
  178. package/assets/css/module/author.less +0 -231
  179. package/assets/css/module/buff.less +0 -88
  180. package/assets/css/module/directory.less +0 -165
  181. package/assets/css/module/icon.less +0 -25
  182. package/assets/css/module/item.less +0 -279
  183. package/assets/css/module/item_simple.less +0 -58
  184. package/assets/css/module/jx3_element.less +0 -5
  185. package/assets/css/module/macro.less +0 -89
  186. package/assets/css/module/npc.less +0 -265
  187. package/assets/css/module/resource.less +0 -93
  188. package/assets/css/module/skill.less +0 -74
  189. package/assets/css/module/talent.less +0 -495
  190. package/assets/js/a.js +0 -46
  191. package/assets/js/code.js +0 -13
  192. package/assets/js/combo.js +0 -40
  193. package/assets/js/directory.js +0 -114
  194. package/assets/js/filter2.js +0 -186
  195. package/assets/js/fold.js +0 -11
  196. package/assets/js/gallery.js +0 -14
  197. package/assets/js/hljs_languages.js +0 -177
  198. package/assets/js/iframe.js +0 -38
  199. package/assets/js/img.js +0 -23
  200. package/assets/js/item/attribute_percent.js +0 -88
  201. package/assets/js/item/bind.js +0 -18
  202. package/assets/js/item/border.js +0 -19
  203. package/assets/js/item/border_quest.js +0 -12
  204. package/assets/js/item/color.js +0 -25
  205. package/assets/js/item/hljs_languages.js +0 -177
  206. package/assets/js/item/icon_url.js +0 -15
  207. package/assets/js/item/second_format.js +0 -19
  208. package/assets/js/jx3_element.js +0 -73
  209. package/assets/js/katex.js +0 -181
  210. package/assets/js/macro.js +0 -16
  211. package/assets/js/nextpage.js +0 -4
  212. package/assets/js/pswp.js +0 -67
  213. package/assets/js/pswp_template.js +0 -66
  214. package/assets/js/pz_iframe.js +0 -30
  215. package/assets/js/qixue.js +0 -28
  216. package/assets/js/renderImgPreview.js +0 -18
  217. package/assets/js/script.js +0 -6
  218. package/assets/js/stat.js +0 -107
  219. package/assets/js/talent2.js +0 -21
  220. package/assets/js/tex-mml-chtml.js +0 -36310
  221. package/assets/js/voice.js +0 -238
  222. package/assets/js/xss.js +0 -130
  223. package/src/editor/Article.vue +0 -230
  224. package/src/editor/BoxResource.vue +0 -441
  225. package/src/editor/Resource.vue +0 -623
  226. package/src/editor/Tinymce.vue +0 -204
  227. package/src/editor/Upload.vue +0 -277
  228. package/src/editor/UploadAlum.vue +0 -176
  229. package/src/editor/UploadBanner.vue +0 -156
  230. package/src/editor/components/Author.vue +0 -322
  231. package/src/editor/components/Avatar.vue +0 -95
  232. package/src/editor/components/Buff.vue +0 -80
  233. package/src/editor/components/Combo.vue +0 -259
  234. package/src/editor/components/Equip.vue +0 -299
  235. package/src/editor/components/GameText.vue +0 -242
  236. package/src/editor/components/Item.vue +0 -325
  237. package/src/editor/components/ItemSimple.vue +0 -134
  238. package/src/editor/components/Medal.vue +0 -43
  239. package/src/editor/components/Npc.vue +0 -215
  240. package/src/editor/components/PostAuthor.vue +0 -102
  241. package/src/editor/components/Skill.vue +0 -71
@@ -1,204 +0,0 @@
1
- <template>
2
- <div class="c-editor-tinymce">
3
- <slot name="prepend"></slot>
4
-
5
- <div class="c-editor-header">
6
- <Upload v-if="attachmentEnable" @insert="insertAttachments" />
7
- <Resource v-if="resourceEnable" @insert="insertResource" />
8
- <BoxResource v-if="resourceEnable" @insert="insertResource" />
9
- </div>
10
- <Emotion class="c-editor-emotion" @selected="emotionSelected"></Emotion>
11
-
12
- <slot></slot>
13
-
14
- <editor
15
- id="tinymce"
16
- v-model="data"
17
- :init="init"
18
- class="c-tinymce"
19
- placeholder="✔ 图片可右键粘贴或拖拽至编辑器内自动上传 ✔ 支持word/excel内容一键粘贴"
20
- />
21
- <el-alert class="u-tutorial" type="warning" show-icon
22
- >进入特殊区域(代码块,折叠块等等)脱离或使用工具栏触发后,请使用键盘方向 → ↓
23
- 键进行脱离,回车只是正常在区块内换行。去掉样式点击第二行第一个&lt;清除格式&gt;即可复位。
24
- <!-- <a href="" target="_blank">[编辑器使用指南]</a> -->
25
- </el-alert>
26
-
27
- <slot name="append"></slot>
28
- </div>
29
- </template>
30
-
31
- <script>
32
- import Editor from "@tinymce/tinymce-vue";
33
- import Upload from "./Upload.vue";
34
- import Resource from "./Resource.vue";
35
- import BoxResource from "./BoxResource.vue";
36
- import JX3BOX from "@jx3box/jx3box-common/data/jx3box.json";
37
- import Emotion from "@jx3box/jx3box-emotion/src/Emotion2.vue";
38
- import hljs_languages from "../../assets/js/item/hljs_languages.js";
39
- const { __cms, __imgPath } = JX3BOX;
40
- const proxyEnabled = ["1", "true", "yes", "on"].includes(String(process.env.VUE_APP_PROXY_ENABLE || "").toLowerCase());
41
- const proxyPrefix = process.env.VUE_APP_PROXY_PREFIX || "/__proxy";
42
- const API_Root = process.env.NODE_ENV === "production" ? __cms : proxyEnabled ? `${proxyPrefix}/cms/` : "/";
43
- const API = API_Root.replace(/\/+$/, "/") + "api/cms/upload/tinymce";
44
-
45
- export default {
46
- name: "TinyMce",
47
- props: ["modelValue", "height", "attachmentEnable", "resourceEnable"],
48
- emits: ["update:modelValue"],
49
- data: function () {
50
- return {
51
- data: "",
52
- init: {
53
- // 选择器
54
- selector: "#tinymce",
55
-
56
- // 语言
57
- language: "zh_CN",
58
-
59
- // 设置
60
- convert_urls: false,
61
-
62
- // 样式
63
- // TODO:
64
- content_css: `https://oss.jx3box.com/static/tinymce/skins/content/default/content.min.css`,
65
- // content_css: `http://localhost:5000/skins/content/default/content.min.css`,
66
- body_class: "c-article c-article-editor c-article-tinymce",
67
- height: this.height || 800,
68
- autosave_ask_before_unload: false,
69
-
70
- // UI
71
- icons: "custom",
72
- menubar: false,
73
- branding: false,
74
- contextmenu: "",
75
- plugins: [
76
- "link autolink",
77
- "hr lists advlist table codeinline codesample checklist foldtext latex",
78
- "image emoticons media",
79
- "code fullscreen wordcount powerpaste pagebreak printpage", // template anchor jx3icon autosave
80
- ],
81
- toolbar: [
82
- "undo | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough superscript subscript | link unlink | fullscreen code", //restoredraft
83
- "removeformat | hr alignleft aligncenter alignright alignjustify indent outdent | bullist numlist checklist table blockquote foldtext codeinline codesample latex | emoticons image media | pagebreak printpage", // template anchor jx3icon
84
- ],
85
- mobile: {
86
- toolbar_drawer: true,
87
- toolbar: [
88
- "undo emoticons bold forecolor backcolor removeformat pagebreak fullscreen",
89
- "hr alignleft aligncenter alignright alignjustify indent outdent bullist numlist checklist table blockquote codesample latex media",
90
- ],
91
- },
92
- block_formats: "段落=p;一级标题=h1;二级标题=h2;三级标题=h3;四级标题=h4;五级标题=h5;六级标题=h6;",
93
- fontsize_formats: "12px 14px 16px 18px 22px 24px 26px 28px 32px 48px 72px",
94
- color_map: [
95
- "FF99CC",
96
- "浅粉",
97
- "FF3399",
98
- "深粉",
99
- "FF0000",
100
- "正红",
101
- "CC99FF",
102
- "紫色",
103
- "9933ff",
104
- "深紫",
105
-
106
- "FFFF99",
107
- "浅黄",
108
- "FFFF00",
109
- "金黄",
110
- "FFCC00",
111
- "亮黄",
112
- "FFCC99",
113
- "浅桃",
114
- "FF6600",
115
- "橘色",
116
-
117
- "CCFFCC",
118
- "浅绿",
119
- "9bf915",
120
- "荧光绿",
121
- "00FF00",
122
- "辣眼绿",
123
- "49c10f",
124
- "深绿",
125
- "008080",
126
- "深青",
127
-
128
- "CCFFFF",
129
- "浅蓝",
130
- "00FFFF",
131
- "参考线",
132
- "00CCFF",
133
- "天蓝",
134
- "99CCFF",
135
- "蔚蓝",
136
- "0000FF",
137
- "辣眼蓝",
138
-
139
- "CC0000",
140
- "深红",
141
- "000000",
142
- "黑色",
143
- ],
144
-
145
- codesample_languages: hljs_languages,
146
-
147
- // Image
148
- image_advtab: true,
149
- file_picker_types: "file image",
150
- images_upload_url: API,
151
- automatic_uploads: true,
152
- images_upload_credentials: true,
153
- valid_children: "+body[style]",
154
- },
155
- mode: "tinymce",
156
- };
157
- },
158
- watch: {
159
- data: function (val) {
160
- this.$emit("update:modelValue", val);
161
- },
162
- modelValue: {
163
- immediate: true,
164
- handler: function (val) {
165
- this.data = val;
166
- },
167
- },
168
- },
169
- methods: {
170
- setup: function (editor) {
171
- console.log("ID为: " + editor.id + " 的编辑器即将初始化.");
172
- },
173
- ready: function (editor) {
174
- console.log("ID为: " + editor.id + " 的编辑器已初始化完成.");
175
- },
176
- insertAttachments: function (data) {
177
- tinyMCE.editors["tinymce"].insertContent(data.html);
178
- },
179
- insertResource: function (data) {
180
- tinyMCE.editors["tinymce"].insertContent(data);
181
- },
182
- emotionSelected: function (emotion) {
183
- let src = emotion.filename;
184
- if (!emotion.filename.startsWith("http")) {
185
- src = `${__imgPath}emotion/output/${emotion.filename}`;
186
- }
187
- const IMAGE = `<img class="t-emotion" src="${src}" alt="${src}" style="max-width:60px; max-height: 60px"/>`;
188
- tinyMCE.editors["tinymce"].insertContent(IMAGE);
189
- },
190
- },
191
- mounted: function () {},
192
- components: {
193
- Editor,
194
- Upload,
195
- Emotion,
196
- Resource,
197
- BoxResource,
198
- },
199
- };
200
- </script>
201
-
202
- <style lang="less">
203
- @import "../../assets/css/tinymce/_.less";
204
- </style>
@@ -1,277 +0,0 @@
1
- <template>
2
- <div class="c-upload">
3
- <!-- 上传触发按钮 -->
4
- <el-button type="primary" @click="dialogVisible = true" :disabled="!enable">
5
- <el-icon class="u-icon"><UploadFilled /></el-icon>
6
- {{ btn_txt }}
7
- </el-button>
8
-
9
- <!-- 弹出界面 -->
10
- <el-dialog class="c-large-dialog" title="上传" v-model="dialogVisible" @close="closeUpload">
11
- <!-- 清空按钮 -->
12
- <el-button class="u-upload-clear" plain size="small" @click="clear"
13
- ><el-icon><Delete /></el-icon>清空</el-button
14
- >
15
-
16
- <!-- 限制提示 -->
17
- <el-alert class="u-upload-tip" :title="tip" type="info" show-icon :closable="false"></el-alert>
18
-
19
- <!-- 文件区 -->
20
- <el-upload
21
- :action="API"
22
- list-type="picture-card"
23
- :auto-upload="false"
24
- :limit="10"
25
- multiple
26
- with-credentials
27
- :file-list="fileList"
28
- :on-change="change"
29
- ref="uploadBox"
30
- :accept="accept"
31
- :key="timeStamp + fileList.length"
32
- >
33
- <template #default>
34
- <el-icon><Plus /></el-icon>
35
- </template>
36
-
37
- <!-- 文件项 -->
38
- <template #file="{ file }">
39
- <div
40
- class="u-file-wrapper"
41
- @click="select(file)"
42
- :class="{
43
- isSelected: file.selected,
44
- disabled: file.status != 'success',
45
- }"
46
- >
47
- <span style="display: none">{{ fileList }}</span>
48
- <!-- 图片类型 -->
49
- <img v-if="file.is_img" class="el-upload-list__item-thumbnail u-imgbox" :src="file.url" alt />
50
- <!-- 其他类型 -->
51
- <div v-else class="u-filebox">
52
- <img class="u-fileplaceholder" svg-inline src="../../assets/img/editor/file.svg" />
53
- <span class="u-filename">{{ file.name }}</span>
54
- </div>
55
- <!-- 勾选角标 -->
56
- <label v-show="file.selected" class="u-file-select-label">
57
- <el-icon class="el-icon-upload-success el-icon-check" color="#fff"><Check /></el-icon>
58
- </label>
59
- </div>
60
- </template>
61
- </el-upload>
62
-
63
- <!-- 插入按钮 -->
64
- <template #footer>
65
- <span class="dialog-footer">
66
- <el-button @click="closeUpload">取 消</el-button>
67
- <el-button type="primary" @click="insert">
68
- {{ buttonTXT }}
69
- </el-button>
70
- </span>
71
- </template>
72
- </el-dialog>
73
- </div>
74
- </template>
75
-
76
- <script>
77
- import axios from "axios";
78
- import { cloneDeep } from "lodash";
79
- import JX3BOX from "@jx3box/jx3box-common/data/jx3box.json";
80
- const { __cms } = JX3BOX;
81
- const API_Root = process.env.NODE_ENV === "production" ? __cms : "/";
82
- const API = API_Root + "api/cms/upload";
83
- const imgtypes = ["jpg", "png", "gif", "bmp", "webp", "jpeg", "JPG", "PNG", "GIF", "BMP", "WEBP", "JPEG"];
84
-
85
- export default {
86
- name: "EditorUpload",
87
- props: {
88
- text: {
89
- type: String,
90
- },
91
- onlyImage: {
92
- type: Boolean,
93
- },
94
- desc: {
95
- type: String,
96
- },
97
- accept: {
98
- type: String,
99
- },
100
- enable: {
101
- type: Boolean,
102
- default: true,
103
- },
104
- max: {
105
- type: Number,
106
- default: 10,
107
- },
108
- // 文件大小限制
109
- sizeLimit: {
110
- type: Number,
111
- default: 30,
112
- },
113
- },
114
- data: function () {
115
- return {
116
- API: API,
117
- dialogVisible: false,
118
- tip:
119
- this.desc ||
120
- `一次最多同时上传${this.max}个文件(单个文件不超过${this.sizeLimit}M),格式限常见的图片、文档、数据表及压缩包`,
121
- btn_txt: this.text || "上传附件",
122
-
123
- fileList: [],
124
- selectedCount: 0,
125
- insertList: "",
126
- timeStamp: null,
127
-
128
- // accept: allow_types.accept,
129
- // sizeLimit: allow_types.sizeLimit,
130
- };
131
- },
132
- watch: {
133
- fileList: {
134
- deep: true,
135
- handler: function (newVal) {
136
- this.timeStamp = new Date().getTime() + Math.random();
137
- this.$emit("update", newVal);
138
- },
139
- },
140
- insertList: function (newVal) {
141
- this.$emit("htmlUpdate", newVal);
142
- },
143
- },
144
- computed: {
145
- buttonTXT: function () {
146
- return this.selectedCount ? "插 入" : "确 定";
147
- },
148
- },
149
- methods: {
150
- change: function (file) {
151
- if (file.status != "success") {
152
- // 判断大小
153
- // if (file.size > this.sizeLimit) {
154
- // this.$message.error("文件超出大小限制");
155
- // this.removeFile(fileList, file.uid);
156
- // return;
157
- // }
158
-
159
- // 分析文件类型
160
- let ext = file.name.split(".").pop();
161
- let is_img = imgtypes.includes(ext);
162
-
163
- if (this.onlyImage && !is_img) return;
164
-
165
- // 构建数据
166
- let fdata = new FormData();
167
- fdata.append("file", file.raw);
168
-
169
- // 异步上传
170
- axios
171
- .post(API, fdata, {
172
- headers: {
173
- "Content-Type": "multipart/form-data",
174
- },
175
- withCredentials: true,
176
- auth: {
177
- username: (localStorage && localStorage.getItem("token")) || "",
178
- password: "cms common request",
179
- },
180
- })
181
- .then((res) => {
182
- if (res.data.code) {
183
- this.$message({
184
- message: res.data.msg,
185
- type: "error",
186
- });
187
- return;
188
- }
189
- // 提醒
190
- this.$message({
191
- message: "上传成功",
192
- type: "success",
193
- });
194
-
195
- // 修改path
196
- file.url = res.data.data && res.data.data[0];
197
-
198
- // 额外赋值
199
- file.is_img = is_img;
200
- file.selected = true;
201
-
202
- // 修改状态加入仓库
203
- file.status = "success";
204
- this.fileList.push(file);
205
- this.selectedCount++;
206
- })
207
- .catch((err) => {
208
- if (err.response.data.code) {
209
- this.$message.error(`[${err.response.data.code}] ${err.response.data.message}`);
210
- } else {
211
- this.$message.error("请求异常");
212
- }
213
- });
214
- }
215
- },
216
- select: function (file) {
217
- this.fileList = this.fileList.map((item) => {
218
- if (item.uid == file.uid) {
219
- item.selected = !item.selected;
220
- }
221
- return item;
222
- });
223
- if (file.status == "success") {
224
- file.selected ? this.selectedCount++ : this.selectedCount--;
225
- }
226
- },
227
- buildHTML: function () {
228
- const list = cloneDeep(this.fileList)
229
- .filter((item) => item.selected && item.status == "success")
230
- .map((file) => {
231
- const html = file.is_img
232
- ? ` <img src="${file.url}" />`
233
- : `<a target="_blank" href="${file.url}">${file.name}</a>`;
234
- return html;
235
- });
236
- this.insertList = list.join(" \n");
237
- return this.insertList;
238
- },
239
- insert: function () {
240
- // 关闭窗口
241
- this.closeUpload();
242
-
243
- //为空不执行插入
244
- if (!this.selectedCount) return;
245
-
246
- // 传递值
247
- this.$emit("insert", {
248
- list: this.fileList.filter((item) => item.selected && item.status == "success"),
249
- html: this.buildHTML(),
250
- });
251
-
252
- //移除所有上传图片
253
- this.clear();
254
- },
255
-
256
- clear: function () {
257
- this.$refs.uploadBox.clearFiles();
258
- this.fileList = [];
259
- this.selectedCount = 0;
260
- },
261
- closeUpload() {
262
- this.dialogVisible = false;
263
- },
264
- removeFile: function (fileList, uid) {
265
- fileList.forEach((file, i) => {
266
- if (file.uid == uid) {
267
- fileList.splice(i, 1);
268
- }
269
- });
270
- },
271
- },
272
- };
273
- </script>
274
-
275
- <style lang="less">
276
- @import "../../assets/css/editor/upload.less";
277
- </style>
@@ -1,176 +0,0 @@
1
- <template>
2
- <div class="c-upload-album">
3
- <Upload @insert="updateFileList" text="批量上传图片" />
4
- <div class="c-upload-album-list">
5
- <draggable class="m-album" v-model="imgList" item-key="id" v-if="imgList && imgList.length">
6
- <template #item="{ element }">
7
- <div class="u-album-item">
8
- <img class="u-pic" :src="element.url ? element.url : element" />
9
- <i class="u-mask"></i>
10
- <el-icon class="u-op u-preview" @click="previewHandle(element)"><ZoomIn /></el-icon>
11
- <el-icon class="u-op u-delete" @click="deleteHandle(element)"><Delete /></el-icon>
12
- </div>
13
- </template>
14
- </draggable>
15
- <div class="u-null" v-else><i class="el-icon-warning-outline"></i> 当前没有任何图片</div>
16
- </div>
17
- <el-dialog class="c-upload-album-preview" v-model="dialogVisible">
18
- <img class="u-img" :src="dialogImageUrl" alt />
19
- </el-dialog>
20
- </div>
21
- </template>
22
-
23
- <script>
24
- import draggable from "vuedraggable";
25
- import JX3BOX from "@jx3box/jx3box-common/data/jx3box.json";
26
- import Upload from "./Upload.vue";
27
- const { getThumbnail } = JX3BOX;
28
-
29
- export default {
30
- name: "UploadAlum",
31
- props: ["data"],
32
- data: function () {
33
- return {
34
- imgList: this.data || [],
35
- dialogImageUrl: "",
36
- dialogVisible: false,
37
- };
38
- },
39
- model: {
40
- prop: "data", //向上同步数据
41
- event: "update",
42
- },
43
- components: {
44
- Upload,
45
- draggable,
46
- },
47
- watch: {
48
- data: {
49
- immediate: true,
50
- deep: true,
51
- handler: function (newVal) {
52
- this.imgList = newVal || [];
53
- },
54
- },
55
- imgList: {
56
- deep: true,
57
- handler: function (list) {
58
- this.$emit("update", list);
59
- },
60
- },
61
- },
62
- computed: {},
63
- methods: {
64
- updateFileList: function (data) {
65
- let upload_list = data.list;
66
- let img_list = [];
67
- upload_list.forEach((item) => {
68
- if (item.is_img) {
69
- img_list.push({
70
- name: item.name,
71
- url: item.url,
72
- });
73
- }
74
- });
75
- this.imgList = [...this.imgList, ...img_list];
76
- },
77
- previewHandle: function (item) {
78
- this.dialogImageUrl = item;
79
- this.dialogVisible = true;
80
- },
81
- deleteHandle: function (row) {
82
- this.imgList= this.imgList.filter(item=>item !== row);
83
- },
84
- showThumbnail(val) {
85
- return getThumbnail(val, 146);
86
- },
87
- },
88
- };
89
- </script>
90
-
91
- <style lang="less">
92
- .c-upload-album {
93
- .flex;
94
- .w(100%);
95
- flex-direction: column;
96
- gap: 20px;
97
- .c-upload-album-list {
98
- .flex;
99
- .w(100%);
100
- .r(8px);
101
- gap: 20px;
102
- box-sizing: border-box;
103
- flex-wrap: wrap;
104
- padding: 20px;
105
- border: 2px dashed #eee;
106
- @h: 148px;
107
- min-height: @h;
108
- .u-null {
109
- .x;
110
- .auto(x);
111
- .fz(12px,@h);
112
- color: #999;
113
- }
114
- .m-album {
115
- .flex;
116
- gap: 10px;
117
- .u-album-item {
118
- .pr;
119
- .size(@h);
120
- img {
121
- .db;
122
- .size(100%);
123
- }
124
- overflow: hidden;
125
- background-color: #fff;
126
- border: 1px solid #c0ccda;
127
- border-radius: 6px;
128
- box-sizing: border-box;
129
- display: inline-block;
130
- &:hover {
131
- .u-mask,
132
- .u-op {
133
- .db;
134
- }
135
- }
136
- }
137
-
138
- .u-mask,
139
- .u-op {
140
- .pa;
141
- .none;
142
- }
143
- .u-op {
144
- .pointer;
145
- }
146
- .u-mask {
147
- background-color: rgba(0, 0, 0, 0.5);
148
- transition: opacity 0.3s;
149
- .lt(0);
150
- .size(100%);
151
- .none;
152
- cursor: move;
153
- }
154
- .u-delete,
155
- .u-preview {
156
- .fz(20px);
157
- color: #fff;
158
- .lt(50%);
159
- .size(20px);
160
- transform: translate(-50%, -50%);
161
- }
162
- .u-delete {
163
- .ml(20px);
164
- }
165
- .u-preview {
166
- .ml(-20px);
167
- }
168
- }
169
- }
170
- }
171
- .c-upload-album-preview {
172
- .u-img {
173
- min-width: 800px;
174
- }
175
- }
176
- </style>