add.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. <script>
  2. // import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
  3. // Vue.use( CKEditor );
  4. import RoundedTitle from "../../../components/public/roundedTitle.vue";
  5. import PopCard from "../../../components/public/popCard.vue";
  6. import ImageTable from "../../../components/public/imageTable.vue";
  7. import Pop from "../../../components/public/pop.vue";
  8. import TableSelect from "../../../components/public/tableSelect.vue";
  9. import dbField_esm from "../../../map/dbField_esm";
  10. import {checkFormItem, initForm} from "../../../until/formTool";
  11. import InputRow from "../../../components/public/form/inputRow.vue";
  12. import ImageViewer from "../../../components/public/imageViewer.vue";
  13. import {handle} from "../../../until/handle";
  14. import {apiMap} from "../../../map/apiMap";
  15. import {rCode} from "../../../map/rcodeMap_esm";
  16. import {fieldCheck} from "../../../until/form/fieldVerify";
  17. import {FormVerify} from "kind-form-verify";
  18. import {escapeHtml, unescapeHtml} from "@/until/unescapeHtml";
  19. import {isEmpty} from "../../../until/typeTool";
  20. let ClassicEditor;
  21. // let MyCustomPlugin;
  22. if (process.client) {
  23. ClassicEditor = require('../../../model/ckeditor/ckeditor');
  24. // ClassicEditor = require('@ckeditor/ckeditor5-build-classic');
  25. console.log(ClassicEditor);
  26. // MyCustomPlugin = require('../../../until/customCkeditorPlugin');
  27. }
  28. let formVerify = null;
  29. export default {
  30. name: "add",
  31. components: {
  32. ImageViewer,
  33. InputRow,
  34. TableSelect,
  35. Pop,
  36. ImageTable,
  37. PopCard,
  38. RoundedTitle
  39. // Use the <ckeditor> component in this view.
  40. },
  41. props: ['article'],
  42. watch: {
  43. article(val){
  44. // 更新文章数据
  45. this.editModel()
  46. }
  47. },
  48. computed: {
  49. // 产品类型数据
  50. newsTypes(){
  51. let arr = [];
  52. if (this.form.pType.val === dbField_esm.db_base.newsType.all){
  53. arr = this.$store.getters.allNewsTypes;
  54. }else if (this.form.pType.val === dbField_esm.db_base.newsType.news){
  55. arr = this.$store.getters.newsTypes;
  56. }else if (this.form.pType.val === dbField_esm.db_base.newsType.solution){
  57. arr = this.$store.getters.solutionTypes;
  58. }
  59. if (arr[0].key !== 'all'){
  60. // 添加 all
  61. arr.unshift(
  62. {
  63. text: '全部',
  64. key: 'all',
  65. value: 'all',
  66. }
  67. );
  68. }
  69. return arr;
  70. },
  71. },
  72. mounted() {
  73. formVerify = new FormVerify(
  74. this.form,
  75. fieldCheck,
  76. )
  77. // fieldCheck.checkField('type',this.form.type.val)
  78. // formVerify.checkForm(this.form, true);
  79. console.log(formVerify);
  80. formVerify.onLog = (msg) => {
  81. console.log(msg);
  82. };
  83. // 判断是否为编辑文章
  84. if(isEmpty(this.article)){
  85. this.isEdit = true;
  86. console.log(this.article);
  87. console.log(this.form);
  88. }
  89. this.initForm();
  90. },
  91. beforeDestroy() {
  92. formVerify = null;
  93. },
  94. data(){
  95. return {
  96. isEdit: false,
  97. editId: null,
  98. editor: ClassicEditor,
  99. editorData: '<p>在此输入文章内容</p>',
  100. editorConfig: {
  101. language: 'zh',
  102. customText: "插入图片",
  103. },
  104. imagePopShow: false,
  105. imagePopLoading: false,
  106. isCoverSelect: false,
  107. form: {
  108. pType: {
  109. val: dbField_esm.db_base.newsType.all,
  110. oldVal: dbField_esm.db_base.newsType.all,
  111. init: dbField_esm.db_base.newsType.all,
  112. msg: '',
  113. state: 0,
  114. options: [
  115. {text: '全部', key: dbField_esm.db_base.newsType.all, value: dbField_esm.db_base.newsType.all},
  116. {text: '新闻', key: dbField_esm.db_base.newsType.news, value: dbField_esm.db_base.newsType.news},
  117. {text: '解决方案', key: dbField_esm.db_base.newsType.solution, value: dbField_esm.db_base.newsType.solution},
  118. ]
  119. },
  120. type: {
  121. val: 'all',
  122. init: '',
  123. msg: '',
  124. state: 0,
  125. options: this.$store.getters.allNewsTypes,
  126. disables: ['all'],
  127. },
  128. title: {
  129. val: '',
  130. init: '',
  131. msg: '',
  132. reCheckField: 'id',
  133. state: 0
  134. },
  135. author: {
  136. val: '',
  137. init: '',
  138. msg: '',
  139. state: 0
  140. },
  141. source: {
  142. val: '',
  143. init: '',
  144. msg: '',
  145. state: 0
  146. },
  147. cover: {
  148. val: '',
  149. init: '',
  150. msg: '',
  151. reCheckField: 'fileData',
  152. state: 0
  153. },
  154. remark: {
  155. val: '',
  156. init: '',
  157. msg: '',
  158. state: 0
  159. },
  160. }
  161. }
  162. },
  163. beforeMount() {
  164. // 插入toolbar
  165. this.editorConfig.customFunction = () => {
  166. console.log('自定义插入图片按钮');
  167. this.openImageSelect();
  168. };
  169. },
  170. methods:{
  171. initForm(){
  172. this.form.pType.val = dbField_esm.db_base.newsType.all;
  173. this.form.type.options = this.newsTypes;
  174. // 判断是否为编辑文章
  175. initForm(this.form);
  176. this.form.cover.showText = this.form.cover.init;
  177. // 强制更新页面
  178. this.$forceUpdate()
  179. },
  180. editModel(){
  181. this.isEdit = true;
  182. this.editId = this.article.id;
  183. // 查找对应的 类型
  184. this.form.title.init = this.article.title;
  185. this.form.author.init = this.article.author;
  186. this.form.source.init = this.article.source;
  187. this.form.cover.init = this.article.image;
  188. console.log(this.article.image)
  189. this.form.remark.init = this.article.remark;
  190. this.editorData = this.article.htmlContent;
  191. this.initForm();
  192. let type = this.form.type.options.find((item) => item.type_id === this.article.type_id)
  193. if(type){
  194. console.log(`find the article type`)
  195. this.form.type.init = type.key;
  196. this.form.type.val = type.key;
  197. this.form.pType.init = type.parent_type;
  198. this.form.pType.val = type.parent_type;
  199. }
  200. },
  201. openCoverSelect(){
  202. console.log('打开文章封面选择窗口');
  203. this.isCoverSelect = true;
  204. this.imagePopShow = true;
  205. },
  206. openImageSelect(){
  207. console.log('尝试打开图片选择窗口');
  208. this.isCoverSelect = false;
  209. this.imagePopShow = true;
  210. },
  211. selectImageHandle(fileData){
  212. console.log('okHandle');
  213. console.log(fileData);
  214. this.imagePopShow = false;
  215. if(this.isCoverSelect){
  216. // 选择封面图片
  217. this.form.cover.val = fileData.filePath;
  218. this.form.cover.init = fileData.filePath;
  219. this.form.cover.msg = '';
  220. this.form.cover.state = 0;
  221. this.form.cover.showText = fileData.filePath;
  222. return;
  223. }
  224. // 将图片新增至编辑器中,允许调整图片大小
  225. this.editorData += `<img src="${fileData.filePath}" alt="${fileData.fileName}">`;
  226. console.log(this.editorData);
  227. },
  228. onPTypeChange(){
  229. console.log('文章主类型改变');
  230. console.log(this.newsTypes);
  231. this.form.type.val = this.newsTypes[0].key;
  232. this.form.type.oldVal = this.newsTypes[0].key;
  233. this.form.type.init = this.newsTypes[0].key;
  234. this.form.type.options = this.newsTypes;
  235. },
  236. async onSubmitHandle(){
  237. // 提交文章
  238. console.log('提交文章');
  239. // console.log(this.editorData);
  240. // console.log(this.form);
  241. let isPass = formVerify.checkForm(this.form, true);
  242. if(!isPass){
  243. console.log(this.form);
  244. return console.log('数据验证不通过');
  245. }
  246. let formData = formVerify.getFormData();
  247. console.log('------');
  248. console.log(formData);
  249. console.log('------');
  250. // 将content的内容转换为安全字符
  251. formData.content = escapeHtml(this.editorData);
  252. console.log(formData);
  253. console.log(unescapeHtml(formData.content));
  254. // 发送请求至后台
  255. let queryPath = this.isEdit? apiMap.newsEdit : apiMap.newsAdd;
  256. let actionText = this.isEdit? '修改文章': '新增文章';
  257. if(this.isEdit){
  258. formData.id = this.editId;
  259. }
  260. let [err,res] = await handle(this.$axios.post(
  261. queryPath.path,
  262. formData
  263. ));
  264. if(err){
  265. console.log(err);
  266. return this.$message.error(`${actionText}失败`);
  267. }
  268. let result = res.data;
  269. if (result.code === rCode.OK){
  270. this.$message.success(`${actionText}成功`);
  271. }else{
  272. this.$message.error(`${actionText}失败,${result.msg}`);
  273. }
  274. }
  275. }
  276. }
  277. </script>
  278. <template>
  279. <div class="w-full p-2">
  280. <rounded-title class="text-xl">
  281. <span>{{ isEdit? "修改文章": "新增文章" }}</span>
  282. <a href="/manger/news"
  283. class="px-10 h-full ml-5 rounded bg-blue-400 text-white cursor-pointer
  284. hover:text-orange-500 ">文章中心</a>
  285. </rounded-title>
  286. <div class="page-content-box w-full mt-2 p-0.5 rounded bg-white">
  287. <div class="flex pb-1 border-b border-gray-300 border-dashed">
  288. <a-radio-group class="flex flex-shrink-0 items-center" v-model="form.pType.val" @change="onPTypeChange">
  289. <a-radio-button class="" :value="item.key" v-for="item in form.pType.options" :key="item.key">{{item.text}}</a-radio-button>
  290. </a-radio-group>
  291. <table-select
  292. class="w-48 !mx-3 flex-shrink-0"
  293. :options="form.type.options"
  294. v-model="form.type.val"
  295. />
  296. <div v-if="form.type.msg" class="flex items-center pl-2 text-red-500 font-bold border-l border-b-orange-700">
  297. {{form.type.msg}}
  298. </div>
  299. </div>
  300. <input-row class="mt-2" :msg="form.author.msg"
  301. label="作者">
  302. <a-input v-model="form.author.val" placeholder="请输入作者"></a-input>
  303. </input-row>
  304. <input-row class="mt-2" :msg="form.source.msg"
  305. label="来源">
  306. <a-input v-model="form.source.val" placeholder="请输入来源"></a-input>
  307. </input-row>
  308. <input-row class="mt-2" :msg="form.title.msg"
  309. label="标题">
  310. <a-input v-model="form.title.val" placeholder="请输入标题"></a-input>
  311. </input-row>
  312. <input-row class="mt-2" :msg="form.remark.msg"
  313. remark="文章的简介摘要部分,用于外部展示"
  314. label="摘要" >
  315. <a-input v-model="form.remark.val" placeholder="请输入摘要"></a-input>
  316. </input-row>
  317. <input-row class="my-2" :msg="form.cover.msg"
  318. label="文章封面">
  319. <div class="rounded relative" style="width: 524px;height: 360px" >
  320. <image-viewer class="" :src="form.cover.showText?form.cover.showText.charAt(0) == '/'? form.cover.showText : '/public/'+form.cover.showText : '' " :alt="form.cover.showText" ></image-viewer>
  321. <div class="absolute w-full h-full left-0 top-0
  322. justify-center text-white bg-gray-400
  323. items-center text-2xl flex opacity-0 hover:opacity-70"
  324. @click="openCoverSelect"
  325. >
  326. 点击选择封面图片
  327. </div>
  328. </div>
  329. </input-row>
  330. <ckeditor class="mt-2" ref="ckeditor" :editor="editor" v-model="editorData" :config="editorConfig"></ckeditor>
  331. <div class="mt-2">
  332. <a-button type="primary" @click="onSubmitHandle">
  333. {{isEdit?"保存修改":"新增文章"}}
  334. </a-button>
  335. </div>
  336. </div>
  337. <!-- 图片选择弹窗 -->
  338. <pop :show="imagePopShow" :loading="imagePopLoading">
  339. <pop-card>
  340. <template slot="header">
  341. <span>选择需要插入的图片</span>
  342. </template>
  343. <image-table
  344. class="w-full h-full"
  345. @cancel="imagePopShow = false"
  346. @ok="selectImageHandle">
  347. </image-table>
  348. </pop-card>
  349. </pop>
  350. </div>
  351. </template>
  352. <style scoped>
  353. .page-content-box{
  354. min-height: 500px;
  355. }
  356. </style>