Browse Source

新闻资讯

gzb
wangzhonglu 1 year ago
parent
commit
e57cfc6376
3 changed files with 380 additions and 5 deletions
  1. 7
    0
      src/App.vue
  2. 139
    5
      src/views/news/index.vue
  3. 234
    0
      src/views/news/newsEditor.vue

+ 7
- 0
src/App.vue View File

131
   padding: 16px 0;
131
   padding: 16px 0;
132
   text-align: right;
132
   text-align: right;
133
 }
133
 }
134
+.ivu-form-item-content {
135
+  line-height: 34px;
136
+}
137
+.ivu-modal-body {
138
+  max-height: calc(100vh - 260px) !important;
139
+  overflow: auto;
140
+}
134
 </style>
141
 </style>

+ 139
- 5
src/views/news/index.vue View File

91
             :accept="getPictureAccept()"
91
             :accept="getPictureAccept()"
92
             :show-upload-list="false"
92
             :show-upload-list="false"
93
           >
93
           >
94
-            <img v-if="addForm.newspic" :src="$api.showImageUrl" />
94
+            <img
95
+              style="width: 200px"
96
+              v-if="addForm.newspic"
97
+              :src="$api.showImageUrl + addForm.newspic"
98
+            />
95
             <Button v-else icon="ios-cloud-upload-outline">上传封面</Button>
99
             <Button v-else icon="ios-cloud-upload-outline">上传封面</Button>
96
           </Upload>
100
           </Upload>
97
         </FormItem>
101
         </FormItem>
115
         <FormItem label="摘要" prop="newssummary">
119
         <FormItem label="摘要" prop="newssummary">
116
           <Input
120
           <Input
117
             type="textarea"
121
             type="textarea"
118
-            :rows="3"
122
+            :rows="2"
119
             v-model="addForm.newssummary"
123
             v-model="addForm.newssummary"
120
             :maxlength="255"
124
             :maxlength="255"
121
             show-word-limit
125
             show-word-limit
122
             placeholder="请输入摘要"
126
             placeholder="请输入摘要"
123
           />
127
           />
124
         </FormItem>
128
         </FormItem>
125
-        <FormItem label="内容" prop="newscontent"></FormItem>
129
+        <FormItem label="内容" prop="newscontent">
130
+          <NewsEditor
131
+            :height="300"
132
+            @change="getNewsContent($event, addForm)"
133
+            :content="addForm.newscontent"
134
+          ></NewsEditor>
135
+        </FormItem>
126
       </Form>
136
       </Form>
127
       <div slot="footer" style="text-align: right">
137
       <div slot="footer" style="text-align: right">
128
         <Button @click="addForm.show = false">取消</Button>
138
         <Button @click="addForm.show = false">取消</Button>
129
         <Button @click="toSaveAdd()" type="primary">保存</Button>
139
         <Button @click="toSaveAdd()" type="primary">保存</Button>
130
       </div>
140
       </div>
131
     </Modal>
141
     </Modal>
142
+    <Modal
143
+      v-model="modifyForm.show"
144
+      class="modal1"
145
+      :mask-closable="false"
146
+      title="修改新闻资讯"
147
+    >
148
+      <Form
149
+        :label-width="60"
150
+        label-position="right"
151
+        ref="modifyForm"
152
+        :rules="formRules"
153
+        :model="modifyForm"
154
+      >
155
+        <FormItem label="封面" prop="newspic">
156
+          <Upload
157
+            :format="pictureFormat"
158
+            :max-size="10 * 1024"
159
+            action
160
+            :before-upload="
161
+              (file) => {
162
+                beforeUploadPicture(file, modifyForm);
163
+                return false;
164
+              }
165
+            "
166
+            :accept="getPictureAccept()"
167
+            :show-upload-list="false"
168
+          >
169
+            <img
170
+              style="width: 200px"
171
+              v-if="modifyForm.newspic"
172
+              :src="$api.showImageUrl + modifyForm.newspic"
173
+            />
174
+            <Button v-else icon="ios-cloud-upload-outline">上传封面</Button>
175
+          </Upload>
176
+        </FormItem>
177
+        <FormItem label="置顶" prop="newsup">
178
+          <RadioGroup v-model="modifyForm.newsup">
179
+            <Radio :label="1">置顶</Radio>
180
+            <Radio :label="2">不置顶</Radio>
181
+          </RadioGroup>
182
+        </FormItem>
183
+        <FormItem label="排序" prop="newsorder">
184
+          <InputNumber :min="1" v-model="modifyForm.newsorder" />
185
+        </FormItem>
186
+        <FormItem label="标题" prop="newstitle">
187
+          <Input
188
+            :maxlength="255"
189
+            show-word-limit
190
+            v-model="modifyForm.newstitle"
191
+            placeholder="请输入标题"
192
+          />
193
+        </FormItem>
194
+        <FormItem label="摘要" prop="newssummary">
195
+          <Input
196
+            type="textarea"
197
+            :rows="2"
198
+            v-model="modifyForm.newssummary"
199
+            :maxlength="255"
200
+            show-word-limit
201
+            placeholder="请输入摘要"
202
+          />
203
+        </FormItem>
204
+        <FormItem label="内容" prop="newscontent">
205
+          <NewsEditor
206
+            :height="400"
207
+            @change="getNewsContent($event, modifyForm)"
208
+            :content="modifyForm.newscontent"
209
+          ></NewsEditor>
210
+        </FormItem>
211
+      </Form>
212
+      <div slot="footer" style="text-align: right">
213
+        <Button @click="modifyForm.show = false">取消</Button>
214
+        <Button @click="toSaveModify()" type="primary">保存</Button>
215
+      </div>
216
+    </Modal>
217
+    <Modal
218
+      v-model="detailInfo.show"
219
+      class="modal1"
220
+      :mask-closable="false"
221
+      title="查看新闻资讯"
222
+    >
223
+      <Form :label-width="60" label-position="right" :model="detailInfo">
224
+        <FormItem label="语言">{{
225
+          detailInfo.ltype === 1 ? "中文" : "英文"
226
+        }}</FormItem>
227
+        <FormItem label="封面" prop="newspic">
228
+          <img
229
+            style="width: 200px"
230
+            v-viewer
231
+            v-if="detailInfo.newspic"
232
+            :src="$api.showImageUrl + detailInfo.newspic"
233
+          />
234
+        </FormItem>
235
+        <FormItem label="置顶" prop="newsup">{{
236
+          detailInfo.newsup === 1 ? "置顶" : "不置顶"
237
+        }}</FormItem>
238
+        <FormItem label="排序" prop="newsorder">{{
239
+          detailInfo.newsorder
240
+        }}</FormItem>
241
+        <FormItem label="标题" prop="newstitle">{{
242
+          detailInfo.newstitle
243
+        }}</FormItem>
244
+        <FormItem label="摘要" prop="newssummary">{{
245
+          detailInfo.newssummary
246
+        }}</FormItem>
247
+        <FormItem label="内容" prop="newscontent">
248
+          <div v-html="detailInfo.newscontent"></div>
249
+        </FormItem>
250
+      </Form>
251
+      <div slot="footer" style="text-align: center">
252
+        <Button @click="detailInfo.show = false">关闭</Button>
253
+      </div>
254
+    </Modal>
132
   </div>
255
   </div>
133
 </template>
256
 </template>
134
 
257
 
135
 <script>
258
 <script>
136
 import axios from "axios";
259
 import axios from "axios";
260
+import NewsEditor from "./newsEditor.vue";
137
 import { n_list, n_save, n_update, n_remove } from "@/api";
261
 import { n_list, n_save, n_update, n_remove } from "@/api";
138
 import { dateFormat } from "@/utils";
262
 import { dateFormat } from "@/utils";
139
 import { pictureFormat } from "@/utils/fileConfig";
263
 import { pictureFormat } from "@/utils/fileConfig";
140
 export default {
264
 export default {
265
+  components: {
266
+    NewsEditor
267
+  },
141
   data() {
268
   data() {
142
     return {
269
     return {
143
       dateFormat,
270
       dateFormat,
223
         ltype: [
350
         ltype: [
224
           {
351
           {
225
             required: true,
352
             required: true,
353
+            type: "number",
226
             message: "请选择语言",
354
             message: "请选择语言",
227
             trigger: "change"
355
             trigger: "change"
228
           }
356
           }
231
           {
359
           {
232
             required: true,
360
             required: true,
233
             message: "请选择是否置顶",
361
             message: "请选择是否置顶",
362
+            type: "number",
234
             trigger: "change"
363
             trigger: "change"
235
           }
364
           }
236
         ],
365
         ],
266
           {
395
           {
267
             required: true,
396
             required: true,
268
             message: "请输入排序",
397
             message: "请输入排序",
398
+            type: "number",
269
             trigger: "blur"
399
             trigger: "blur"
270
           }
400
           }
271
         ]
401
         ]
297
     this.getNewsList();
427
     this.getNewsList();
298
   },
428
   },
299
   methods: {
429
   methods: {
430
+    getNewsContent(html, formObj) {
431
+      formObj.newscontent = html;
432
+    },
300
     beforeUploadPicture(file, formObj) {
433
     beforeUploadPicture(file, formObj) {
301
       let formData = new FormData();
434
       let formData = new FormData();
302
-      formData.append("files", file);
435
+      formData.append("file", file);
303
       formData.append("savefolder", "news");
436
       formData.append("savefolder", "news");
304
       axios
437
       axios
305
         .post(this.$api.baseUrl + "file/upload", formData, {
438
         .post(this.$api.baseUrl + "file/upload", formData, {
371
         newsup: this.addForm.newsup,
504
         newsup: this.addForm.newsup,
372
         createid: this.userInfo.userid
505
         createid: this.userInfo.userid
373
       }).then((res) => {
506
       }).then((res) => {
507
+        this.addForm.show = false;
374
         if (res.code === 0) {
508
         if (res.code === 0) {
375
           this.$Message.success(res.msg);
509
           this.$Message.success(res.msg);
376
           this.searchList();
510
           this.searchList();
401
         newsup: this.modifyForm.newsup,
535
         newsup: this.modifyForm.newsup,
402
         newsid: this.modifyForm.newsid
536
         newsid: this.modifyForm.newsid
403
       }).then((res) => {
537
       }).then((res) => {
538
+        this.modifyForm.show = false;
404
         if (res.code === 0) {
539
         if (res.code === 0) {
405
           this.$Message.success(res.msg);
540
           this.$Message.success(res.msg);
406
           this.searchList();
541
           this.searchList();
427
       });
562
       });
428
     },
563
     },
429
     toViewDetail(row) {
564
     toViewDetail(row) {
430
-      console.log("toViewDetail", row);
431
       this.detailInfo = {
565
       this.detailInfo = {
432
         show: true,
566
         show: true,
433
         ltype: row.ltype,
567
         ltype: row.ltype,

+ 234
- 0
src/views/news/newsEditor.vue View File

1
+<template>
2
+  <div class="editor_root">
3
+    <textarea
4
+      :ref="`${editor_ref}_${randomNum}`"
5
+      :id="`${editor_ref}_${randomNum}`"
6
+      :style="`width: 100%;height: ${height}px;`"
7
+    ></textarea>
8
+  </div>
9
+</template>
10
+
11
+<script>
12
+import { pictureFormat } from "@/utils/fileConfig";
13
+export default {
14
+  props: {
15
+    content: {
16
+      type: String,
17
+      default: function () {
18
+        return "";
19
+      }
20
+    },
21
+    editor_ref: {
22
+      type: String,
23
+      default: function () {
24
+        return "myCkeditor";
25
+      }
26
+    },
27
+    content_index: {
28
+      type: Number,
29
+      default: 0
30
+    },
31
+    placeholder: {
32
+      type: String,
33
+      default: "请输入内容"
34
+    },
35
+    height: {
36
+      type: Number,
37
+      default: 150
38
+    }
39
+  },
40
+  data() {
41
+    return {
42
+      randomNum: `${Math.ceil(Math.random() * 10000)}_${Date.now()}`,
43
+      myCkeditor: null,
44
+      imgsObj: {},
45
+      editorHtml: ""
46
+    };
47
+  },
48
+  watch: {
49
+    content: {
50
+      handler(newHtml) {
51
+        if (this.editorHtml !== newHtml) {
52
+          this.setContent(newHtml);
53
+        }
54
+      },
55
+      immediate: true
56
+    }
57
+  },
58
+  mounted() {
59
+    this.initCkeditor();
60
+  },
61
+  beforeDestroy() {
62
+    if (this.myCkeditor) {
63
+      this.myCkeditor.destroy();
64
+    }
65
+    this.myCkeditor = null;
66
+  },
67
+  methods: {
68
+    setContent(content) {
69
+      if (content) {
70
+        if (this.myCkeditor && this.myCkeditor.status === "ready") {
71
+          this.myCkeditor.setData(content);
72
+          this.editorHtml = content;
73
+        }
74
+      } else {
75
+        setTimeout(() => {
76
+          if (this.myCkeditor && this.myCkeditor.status === "ready") {
77
+            this.myCkeditor.setData("");
78
+            this.editorHtml = "";
79
+          }
80
+        }, 100);
81
+      }
82
+    },
83
+    editorContentChange() {
84
+      this.$nextTick(() => {
85
+        if (this.myCkeditor && this.myCkeditor.document.getBody().$) {
86
+          let newHtml = this.myCkeditor.document.getBody().getHtml();
87
+          let newText = this.myCkeditor.document.getBody().getText();
88
+          this.editorHtml = newHtml;
89
+          this.$emit("change", newHtml, newText, this.content_index);
90
+        }
91
+      });
92
+    },
93
+    initCkeditor() {
94
+      let that = this;
95
+      that.myCkeditor = window.CKEDITOR.replace(
96
+        that.$refs[`${this.editor_ref}_${this.randomNum}`],
97
+        {
98
+          height: that.height,
99
+          filebrowserImageUploadUrl: that.$api.baseImageUrl,
100
+          editorplaceholder: that.placeholder // 占位文本
101
+        }
102
+      );
103
+      that.myCkeditor.on("instanceReady", function () {
104
+        that.setContent(that.content);
105
+        that.myCkeditor.dataProcessor.htmlFilter.addRules({
106
+          elements: {
107
+            img: function (el) {
108
+              let imgSrc = el.attributes.src;
109
+              if (imgSrc) {
110
+                if (
111
+                  imgSrc.indexOf("http://") > -1 ||
112
+                  imgSrc.indexOf("https://") > -1
113
+                ) {
114
+                  if (imgSrc.indexOf(that.$api.showImageUrl) == -1) {
115
+                    that.imgsObj[imgSrc] = "";
116
+                  }
117
+                }
118
+              }
119
+            }
120
+          }
121
+        });
122
+        that.myCkeditor.on("afterPaste", function () {
123
+          for (const imgSrc in that.imgsObj) {
124
+            if (!that.imgsObj[imgSrc]) {
125
+              that
126
+                .checkImgExists(imgSrc)
127
+                .then((imgUrl) => {
128
+                  that.changeImageUrl(imgUrl);
129
+                })
130
+                .catch((imgUrl) => {
131
+                  that.imgsObj[imgUrl] = "";
132
+                });
133
+            }
134
+          }
135
+        });
136
+        that.myCkeditor.on("fileUploadRequest", async function (evt) {
137
+          let fileLoader = evt.data.fileLoader,
138
+            formData = new FormData(),
139
+            xhr = fileLoader.xhr;
140
+          formData.append("savefolder", "news");
141
+          let filename = fileLoader.fileName;
142
+          let myFile = fileLoader.file;
143
+          if (myFile instanceof Blob) {
144
+            formData.append(
145
+              "file",
146
+              new window.File([myFile], filename, { type: myFile.type })
147
+            );
148
+          } else {
149
+            formData.append("file", myFile);
150
+          }
151
+          let strArr = filename.split(".");
152
+          filename = strArr[0];
153
+          let suffix = strArr[strArr.length - 1];
154
+          suffix = suffix.toLowerCase();
155
+          if (pictureFormat.includes(suffix)) {
156
+            xhr.open("POST", that.$api.baseUrl + "file/upload", true);
157
+            xhr.send(formData);
158
+          } else {
159
+            that.$Message.warning("请上传正确的图片格式");
160
+          }
161
+          evt.stop();
162
+        });
163
+        that.myCkeditor.on("fileUploadResponse", function (evt) {
164
+          let data = evt.data,
165
+            xhr = data.fileLoader.xhr;
166
+          let resolve = JSON.parse(xhr.responseText);
167
+          if (resolve.code === 0) {
168
+            data.url = that.$api.showImageUrl + resolve.obj;
169
+          } else {
170
+            data.message = resolve.msg;
171
+            evt.cancel();
172
+          }
173
+          that.editorContentChange();
174
+          evt.stop();
175
+        });
176
+        that.myCkeditor.on("change", function () {
177
+          that.editorContentChange();
178
+        });
179
+        that.myCkeditor.on("blur", function () {
180
+          that.editorContentChange();
181
+        });
182
+      });
183
+    },
184
+    // 验证图片连接是否有效
185
+    checkImgExists(imgUrl) {
186
+      return new Promise(function (resolve, reject) {
187
+        let ImgObj = new Image();
188
+        ImgObj.src = imgUrl;
189
+        ImgObj.setAttribute("crossOrigin", "Anonymous");
190
+        ImgObj.onload = function () {
191
+          resolve(imgUrl);
192
+        };
193
+        ImgObj.onerror = function () {
194
+          reject(imgUrl);
195
+        };
196
+      });
197
+    },
198
+    changeImageUrl(imgSrc) {
199
+      let that = this;
200
+      let formData = new FormData();
201
+      formData.append("newpath", "news");
202
+      formData.append("filepath", imgSrc);
203
+      that
204
+        .axios({
205
+          method: "POST",
206
+          timeout: 1000 * window._config.axiosFileTimeout,
207
+          url: that.$api.baseImageUrl + "file/down_webfile",
208
+          data: formData,
209
+          headers: {
210
+            "Content-Type": "multipart/form-data"
211
+          }
212
+        })
213
+        .then((res) => {
214
+          if (!res.data.code) {
215
+            that.imgsObj[imgSrc] = res.data.obj;
216
+          } else {
217
+            that.$Message.error(res.data.msg);
218
+          }
219
+        });
220
+    }
221
+  }
222
+};
223
+</script>
224
+
225
+<style>
226
+.ivu-message {
227
+  z-index: 999999 !important;
228
+}
229
+</style>
230
+<style scoped>
231
+.editor_root {
232
+  width: 100%;
233
+}
234
+</style>

Loading…
Cancel
Save