@jx3box/jx3box-editor 2.2.47 → 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 +162 -126
  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/Skill.vue CHANGED
@@ -1,17 +1,9 @@
1
1
  <template>
2
2
  <div class="w-skill" v-if="data">
3
3
  <div class="w-skill-wrapper">
4
- <img
5
- class="w-skill-icon"
6
- :src="iconLink(data.IconID || 13)"
7
- :alt="data.Name"
8
- />
4
+ <img class="w-skill-icon" :src="iconLink(data.IconID || 13)" :alt="data.Name" />
9
5
  <div class="w-skill-content">
10
- <el-button
11
- type="text"
12
- class="w-skill-switch-parse"
13
- @click="show_parse = !show_parse"
14
- >
6
+ <el-button link class="w-skill-switch-parse" @click="show_parse = !show_parse">
15
7
  <i class="el-icon-refresh"></i>
16
8
  </el-button>
17
9
  <span class="w-skill-name">{{ data.Name }}</span>
@@ -26,28 +18,42 @@
26
18
  </template>
27
19
 
28
20
  <script>
29
- import { getSkill } from "../service/database.js";
21
+ import { getSkill } from "./service/database.js";
30
22
  import { iconLink } from "@jx3box/jx3box-common/js/utils";
31
23
  export default {
32
24
  name: "Skill",
33
- props: ["client", "id", "level"],
25
+ props: {
26
+ client: {
27
+ type: String,
28
+ default: "std",
29
+ },
30
+ id: {
31
+ type: [String, Number],
32
+ default: "",
33
+ },
34
+ level: {
35
+ type: [String, Number],
36
+ default: "",
37
+ },
38
+ },
34
39
  data: () => ({
35
40
  data: null,
36
41
  show_parse: true,
42
+ requestVersion: 0,
37
43
  }),
38
44
  computed: {
39
45
  params: function () {
40
46
  return [this.client, this.id, this.level];
41
47
  },
42
48
  desc: function () {
43
- if (this.data.parse && this.show_parse) {
49
+ if (this.data?.parse && this.show_parse) {
44
50
  const result = this.data.parse.desc;
45
51
  return result.replace(/\\n/g, "\n");
46
52
  }
47
53
  return this.data?.Desc;
48
54
  },
49
55
  talent_desc: function () {
50
- if (this.data.parse && this.show_parse) {
56
+ if (this.data?.parse && this.show_parse) {
51
57
  return this.data.parse.talent_desc;
52
58
  }
53
59
  return "";
@@ -56,32 +62,36 @@ export default {
56
62
  watch: {
57
63
  params: {
58
64
  immediate: true,
59
- deep: true,
60
65
  handler(val) {
66
+ this.requestVersion += 1;
67
+ const currentVersion = this.requestVersion;
68
+
61
69
  if (val) {
62
70
  let [client, id, level] = val;
71
+ if (!id) {
72
+ this.data = null;
73
+ return;
74
+ }
63
75
  // 读取本地数据
64
- const cache = sessionStorage.getItem(
65
- `skill-${client}-${id}-${level}`
66
- );
76
+ const cache = sessionStorage.getItem(`skill-${client}-${id}-${level}`);
67
77
  if (cache) {
68
78
  try {
69
79
  this.data = JSON.parse(cache);
70
80
  return;
71
- } catch {}
81
+ } catch (e) {
82
+ console.log(e, "[Skill]无法解析本地缓存");
83
+ }
72
84
  // 没有缓存则发起请求获取数据
73
85
  }
74
- if (!id) return;
75
- getSkill(...this.params).then(res => {
86
+ getSkill(client, id, level).then((res) => {
87
+ if (currentVersion !== this.requestVersion) return;
88
+
76
89
  let data = res.data?.list?.[0];
77
90
  if (!data) data = null;
78
91
  this.data = data;
79
92
 
80
93
  // 将数据放入 sessionStorage
81
- sessionStorage.setItem(
82
- `skill-${client}-${id}-${level}`,
83
- JSON.stringify(data)
84
- );
94
+ sessionStorage.setItem(`skill-${client}-${id}-${level}`, JSON.stringify(data));
85
95
  });
86
96
  }
87
97
  },
@@ -96,5 +106,5 @@ export default {
96
106
  </script>
97
107
 
98
108
  <style lang="less">
99
- @import "../assets/css/module/skill.less";
109
+ @import "./assets/css/module/skill.less";
100
110
  </style>
package/src/Tinymce.vue CHANGED
@@ -3,17 +3,28 @@
3
3
  <slot name="prepend"></slot>
4
4
 
5
5
  <div class="c-editor-header">
6
+ <!-- 上传附件 -->
6
7
  <Upload v-if="attachmentEnable" @insert="insertAttachments" />
8
+ <!-- 剑三资源库 -->
7
9
  <Resource v-if="resourceEnable" @insert="insertResource" />
10
+ <!-- 魔盒资源库 -->
8
11
  <BoxResource v-if="resourceEnable" @insert="insertResource" :subtype="subtype" />
9
12
  </div>
10
- <Emotion class="c-editor-emotion" @selected="emotionSelected"></Emotion>
13
+
14
+ <Emotion v-if="emotionEnable" class="c-editor-emotion" @selected="emotionSelected"></Emotion>
11
15
 
12
16
  <slot></slot>
13
17
 
14
- <editor id="tinymce" v-model="data" :init="init" class="c-tinymce" placeholder="✔ 图片可右键粘贴或拖拽至编辑器内自动上传 ✔ 支持word/excel内容一键粘贴" />
18
+ <editor
19
+ id="tinymce"
20
+ v-model="data"
21
+ :init="init"
22
+ class="c-tinymce"
23
+ placeholder="✔ 图片可右键粘贴或拖拽至编辑器内自动上传 ✔ 支持word/excel内容一键粘贴"
24
+ />
15
25
  <el-alert class="u-tutorial" type="warning" show-icon
16
- >进入特殊区域(代码块,折叠块等等)脱离或使用工具栏触发后,请使用键盘方向 → ↓ 键进行脱离,回车只是正常在区块内换行。去掉样式点击第二行第一个&lt;清除格式&gt;即可复位。<a
26
+ >进入特殊区域(代码块,折叠块等等)脱离或使用工具栏触发后,请使用键盘方向 → ↓
27
+ 键进行脱离,回车只是正常在区块内换行。去掉样式点击第二行第一个&lt;清除格式&gt;即可复位。<a
17
28
  href="/collection/31"
18
29
  target="_blank"
19
30
  >[编辑器使用指南]</a
@@ -25,28 +36,75 @@
25
36
  </template>
26
37
 
27
38
  <script>
28
- import Vue from "vue";
29
- import Editor from "@tinymce/tinymce-vue";
39
+ import GlobalConf from "../config/global.js";
40
+ import JX3BOX from "@jx3box/jx3box-common/data/jx3box.json";
41
+ const { __cdn, __imgPath, __cms } = JX3BOX;
42
+ // 开发环境走 devServer proxy,避免跨域导致粘贴图片上传“看起来没反应”
43
+ const apiUrl = process.env.NODE_ENV === "development" ? "/api/cms/upload/tinymce" : __cms + "api/cms/upload/tinymce";
44
+
30
45
  import Upload from "./Upload";
31
46
  import Resource from "./Resource";
32
47
  import BoxResource from "./BoxResource";
33
- import { __cms } from "@jx3box/jx3box-common/data/jx3box.json";
34
- import { __imgPath } from "@jx3box/jx3box-common/data/jx3box.json";
35
48
  import Emotion from "@jx3box/jx3box-emotion/src/Emotion.vue";
36
- import hljs_languages from "../assets/js/item/hljs_languages.js";
37
- const API_Root = process.env.NODE_ENV === "production" ? __cms : "/";
38
- const API = API_Root + "api/cms/upload/tinymce";
39
49
 
40
- // directive
41
- import { draggable } from "../assets/js/drag";
42
- Vue.directive("draggable", draggable);
50
+ import axios from "axios";
51
+ import Editor from "@tinymce/tinymce-vue";
52
+ import hljs_languages from "./assets/js/item/hljs_languages.js";
53
+ // TODO:请求代理问题
43
54
 
44
55
  export default {
45
56
  name: "Tinymce",
46
- props: ["content", "height", "attachmentEnable", "resourceEnable", "subtype"],
57
+ components: {
58
+ Editor,
59
+ Upload,
60
+ Resource,
61
+ BoxResource,
62
+ Emotion,
63
+ },
64
+ props: {
65
+ // Vue3 默认 v-model
66
+ modelValue: {
67
+ type: String,
68
+ },
69
+
70
+ // 内容 兼容旧用法
71
+ content: {
72
+ type: String,
73
+ default: "",
74
+ },
75
+
76
+ // 默认高度
77
+ height: {
78
+ type: Number,
79
+ default: 800,
80
+ },
81
+
82
+ // 是否启用附件上传
83
+ attachmentEnable: {
84
+ type: Boolean,
85
+ default: true,
86
+ },
87
+ // 是否启用资源插入
88
+ resourceEnable: {
89
+ type: Boolean,
90
+ default: true,
91
+ },
92
+ // 是否启用表情插入
93
+ emotionEnable: {
94
+ type: Boolean,
95
+ default: true,
96
+ },
97
+
98
+ // 心法(技能连招使用)
99
+ subtype: {
100
+ type: String,
101
+ default: "通用",
102
+ },
103
+ },
104
+ emits: ["update:modelValue", "update:content", "update"],
47
105
  data: function () {
48
106
  return {
49
- data: this.content,
107
+ data: this.modelValue ?? this.content ?? "",
50
108
  init: {
51
109
  // 选择器
52
110
  selector: "#tinymce",
@@ -58,9 +116,10 @@ export default {
58
116
  convert_urls: false,
59
117
 
60
118
  // 样式
61
- // TODO:
62
- content_css: process.env.VUE_APP_DEV_COMPONENT == "true" ? "/css/article.css" : `https://cdn.jx3box.com/static/jx3box-editor/css/article.css`,
63
- // content_css: `http://localhost:3000/skins/content/default/content.min.css`,
119
+ content_css:
120
+ process.env.VUE_APP_TINYMCE_DEV === "true"
121
+ ? `http://localhost:5120/skins/content/default/content.min.css`
122
+ : `${__cdn}/static/tinymce/skins/content/default/content.min.css`,
64
123
  body_class: "c-article c-article-editor c-article-tinymce",
65
124
  height: this.height || 800,
66
125
  autosave_ask_before_unload: false,
@@ -71,131 +130,114 @@ export default {
71
130
  menubar: false,
72
131
  branding: false,
73
132
  contextmenu: "",
74
- plugins: [
75
- "link autolink",
76
- "hr lists advlist table codeinline codesample checklist foldtext latex anchor",
77
- "image emoticons media videox macro qixue talent2",
78
- "code fullscreen wordcount powerpaste pagebreak printpage pz audiox", // template anchor jx3icon autosave
79
- ],
80
- toolbar: [
81
- "undo | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough superscript subscript | link unlink | fullscreen code", //anchor restoredraft
82
- "removeformat | hr alignleft aligncenter alignright alignjustify indent outdent | bullist numlist checklist table blockquote foldtext codeinline codesample latex | emoticons image media videox audiox | macro pz qixue talent2 pagebreak printpage", // template anchor jx3icon
83
- ],
84
- mobile: {
85
- toolbar_drawer: true,
86
- toolbar: [
87
- "undo emoticons bold italic underline strikethrough superscript subscript link unlink forecolor backcolor removeformat pagebreak fullscreen code",
88
- "hr alignleft aligncenter alignright alignjustify indent outdent bullist numlist checklist table blockquote foldtext codeinline codesample latex macro pz qixue talent2 media videox audiox",
89
- ],
90
- },
133
+ plugins: GlobalConf.plugins,
134
+ toolbar: GlobalConf.toolbar,
135
+ mobile: GlobalConf.mobile,
91
136
  block_formats: "段落=p;一级标题=h1;二级标题=h2;三级标题=h3;四级标题=h4;五级标题=h5;六级标题=h6;",
92
137
  fontsize_formats: "12px 14px 16px 18px 22px 24px 26px 28px 32px 48px 72px",
93
- color_map: [
94
- "FF99CC",
95
- "浅粉",
96
- "FF3399",
97
- "深粉",
98
- "FF0000",
99
- "正红",
100
- "CC99FF",
101
- "紫色",
102
- "9933ff",
103
- "深紫",
104
- "FFFF99",
105
- "浅黄",
106
- "FFFF00",
107
- "金黄",
108
- "FFCC00",
109
- "亮黄",
110
- "FFCC99",
111
- "浅桃",
112
- "FF6600",
113
- "橘色",
114
- "CCFFCC",
115
- "浅绿",
116
- "9bf915",
117
- "荧光绿",
118
- "00FF00",
119
- "辣眼绿",
120
- "49c10f",
121
- "深绿",
122
- "008080",
123
- "深青",
124
- "CCFFFF",
125
- "浅蓝",
126
- "00FFFF",
127
- "参考线",
128
- "00CCFF",
129
- "天蓝",
130
- "99CCFF",
131
- "蔚蓝",
132
- "0000FF",
133
- "辣眼蓝",
134
- "CC0000",
135
- "深红",
136
- "000000",
137
- "黑色",
138
- ],
138
+ color_map: GlobalConf.color_map,
139
139
 
140
140
  codesample_languages: hljs_languages,
141
141
 
142
142
  // Image
143
143
  image_advtab: true,
144
- // paste_data_images: true,
145
144
  file_picker_types: "file image",
146
- images_upload_url: API,
145
+ // images_upload_url: this.uploadUrl,
147
146
  automatic_uploads: true,
148
- images_upload_credentials: true,
149
-
150
- // Hook
151
- // setup: this.setup,
152
- // init_instance_callback: this.ready,
153
-
154
- // Template
155
- // templates: [
156
- // {
157
- // title: "剑三宏",
158
- // description: "",
159
- // content: `
160
- // <pre class="e-jx3macro-area w-jx3macro">/cast 自绝经脉</pre>
161
- // `,
162
- // },
163
- // ],
147
+ // 允许直接粘贴图片(会以 blob 形式触发 images_upload_handler)
148
+ paste_data_images: true,
149
+ // images_upload_credentials: true,
150
+ images_upload_handler: this.imagesUploadHandler,
164
151
  valid_children: "+body[style]",
165
152
  },
166
153
  mode: "tinymce",
167
- style: "",
168
154
  };
169
155
  },
170
- model: {
171
- prop: "content",
172
- event: "update",
173
- },
174
156
  watch: {
175
- data: function (newval) {
176
- this.$emit("update", newval);
157
+ data: function (val) {
158
+ this.$emit("update:modelValue", val);
159
+ this.$emit("update:content", val);
160
+ this.$emit("update", val);
177
161
  },
178
- content: function (newval) {
179
- this.data = newval;
162
+ modelValue: {
163
+ immediate: true,
164
+ handler: function (val) {
165
+ // 当外部未使用默认 v-model(modelValue 未传入)时,走 :content / v-model:content
166
+ if (val !== undefined && val !== this.data) this.data = val ?? "";
167
+ },
180
168
  },
181
- style(val) {
182
- this.init.content_style = val;
169
+ content: {
170
+ immediate: true,
171
+ handler: function (val) {
172
+ if (this.modelValue === undefined && val !== this.data) this.data = val ?? "";
173
+ },
183
174
  },
184
175
  },
185
176
  methods: {
186
- setup: function (editor) {
187
- // console.log("ID为: " + editor.id + " 的编辑器即将初始化.");
177
+ setup(editor) {
178
+ console.log("ID为: " + editor.id + " 的编辑器即将初始化.");
188
179
  },
189
- ready: function (editor) {
190
- // console.log("ID为: " + editor.id + " 的编辑器已初始化完成.");
180
+ ready(editor) {
181
+ console.log("ID为: " + editor.id + " 的编辑器已初始化完成.");
191
182
  },
192
- insertAttachments: function (data) {
183
+ insertAttachments(data) {
184
+ // eslint-disable-next-line no-undef
193
185
  tinyMCE.editors["tinymce"].insertContent(data.html);
194
186
  },
195
- insertResource: function (data) {
187
+ insertResource(data) {
188
+ // eslint-disable-next-line no-undef
196
189
  tinyMCE.editors["tinymce"].insertContent(data);
197
190
  },
198
- emotionSelected: function (emotion) {
191
+ imagesUploadHandler(blobInfo, success, failure, progress) {
192
+ let fdata = new FormData();
193
+ fdata.append("file", blobInfo.blob(), blobInfo.filename());
194
+
195
+ axios
196
+ .post(apiUrl, fdata, {
197
+ headers: {
198
+ "Content-Type": "multipart/form-data",
199
+ },
200
+ withCredentials: true,
201
+ auth: {
202
+ username: (localStorage && localStorage.getItem("token")) || "",
203
+ password: "cms common request",
204
+ },
205
+ onUploadProgress: function (e) {
206
+ if (progress && e.total > 0) {
207
+ progress((e.loaded / e.total) * 100);
208
+ }
209
+ },
210
+ })
211
+ .then((res) => {
212
+ const payload = res.data || {};
213
+ if (payload.code) {
214
+ failure(payload.msg || payload.message || "上传失败");
215
+ return;
216
+ }
217
+
218
+ const url =
219
+ payload.location ||
220
+ payload.url ||
221
+ (payload.data &&
222
+ (Array.isArray(payload.data)
223
+ ? payload.data[0]
224
+ : payload.data.url || payload.data.location || payload.data));
225
+
226
+ if (!url) {
227
+ failure("上传成功但未返回图片地址");
228
+ return;
229
+ }
230
+
231
+ success(url);
232
+ })
233
+ .catch((err) => {
234
+ const message =
235
+ (err.response && err.response.data && (err.response.data.msg || err.response.data.message)) ||
236
+ "图片上传请求异常";
237
+ failure(message);
238
+ });
239
+ },
240
+ emotionSelected(emotion) {
199
241
  let src = emotion.filename;
200
242
  if (!emotion.filename.startsWith("http")) {
201
243
  src = `${__imgPath}emotion/output/${emotion.filename}`;
@@ -204,18 +246,12 @@ export default {
204
246
  tinyMCE.editors["tinymce"].insertContent(IMAGE);
205
247
  },
206
248
  },
207
- mounted: function () {},
208
- components: {
209
- Editor,
210
- Upload,
211
- Resource,
212
- Emotion,
213
- BoxResource,
249
+ mounted() {
250
+ // console.log(process.env.VUE_APP_TINYMCE_DEV)
214
251
  },
215
252
  };
216
253
  </script>
217
254
 
218
255
  <style lang="less">
219
- @import "../assets/css/tinymce.less";
220
- @import "../assets/css/tinymce/combo.less";
256
+ @import "./assets/css/tinymce.less";
221
257
  </style>