zhanghua
6 天以前 61a844ab928b51c33b18a51ddacde8274ef35e29
manager/src/views/news/index.vue
@@ -53,7 +53,7 @@
      <!-- 操作按钮 -->
      <Row class="operation">
        <Button @click="openAdd" type="primary" icon="md-add">新增活动</Button>
        <Button @click="openAdd" type="primary" icon="md-add">新增新闻</Button>
        <Button @click="delBatch" type="error" icon="md-trash" :disabled="selectCount === 0">批量删除</Button>
      </Row>
@@ -134,8 +134,29 @@
              </FormItem>
            </Col>
            <Col span="24">
              <FormItem label="新闻内容:" prop="content">
                <editor ref="editor" @input="getReason" />
              <FormItem label="快讯内容:" prop="content">
                <Upload
                  :show-upload-list="false"
                  ref="upload"
                  style="display: none"
                  :before-upload="handleUploadEdit"
                  :format="['jpg','jpeg','png','gif','mp4','mov']"
                  :max-size="20480"
                  action=""
                  accept="image/*,video/*"
                >
                </Upload>
                <!-- 基于elementUi的上传组件 el-upload end-->
                <quill-editor
                  v-model="newsForm.content"
                  ref="QuillEditor"
                  class="editor"
                  :options="editorOption"
                  @blur="onEditorBlur($event)"
                  @focus="onEditorFocus($event)"
                  @ready="onEditorReady($event)"
                >
                </quill-editor>
              </FormItem>
            </Col>
          </Row>
@@ -202,11 +223,87 @@
  </div>
</template>
<script>
import Editor from '@/components/editor/index.vue'
import { getNews,editNews,addNews,publish,delById } from '@/api/news.js'
import { uploadFileByLmk, delByKey } from "@/api/common.js"
import { quillEditor } from 'vue-quill-editor'
import 'quill/dist/quill.core.css';
import 'quill/dist/quill.snow.css';
import 'quill/dist/quill.bubble.css';
import * as Quill from 'quill' //引入编辑器
import VideoBlot from './video.js';
const toolbarOptions = [
  ['bold', 'italic', 'underline', 'strike'],        // 加粗,斜体,下划线,删除线
  ['blockquote', 'code-block'],                     //引用,代码块
  [{ 'header': 1 }, { 'header': 2 }],               // 几级标题
  [{ 'list': 'ordered' }, { 'list': 'bullet' }],    // 有序列表,无序列表
  [{ 'script': 'sub' }, { 'script': 'super' }],     // 下角标,上角标
  [{ 'indent': '-1' }, { 'indent': '+1' }],         // 缩进
  [{ 'direction': 'rtl' }],                         // 文字输入方向
  [{ 'size': ['small', false, 'large', 'huge'] }],  // 字体大小
  [{ 'header': [1, 2, 3, 4, 5, 6, false] }],        // 标题
  [{ 'color': [] }, { 'background': [] }],          // 颜色选择
  // [{ 'font': [] }], // 字体
  [{ 'align': [] }],    // 居中
  ['clean'],            // 清除样式,
  ['link'],
  ['myUploadBtn'],
]
// toolbar标题
const titleConfig = [
  { Choice: '.ql-insertMetric', title: '跳转配置' },
  { Choice: '.ql-bold', title: '加粗' },
  { Choice: '.ql-italic', title: '斜体' },
  { Choice: '.ql-underline', title: '下划线' },
  { Choice: '.ql-header', title: '段落格式' },
  { Choice: '.ql-strike', title: '删除线' },
  { Choice: '.ql-blockquote', title: '块引用' },
  { Choice: '.ql-code', title: '插入代码' },
  { Choice: '.ql-code-block', title: '插入代码段' },
  { Choice: '.ql-font', title: '字体' },
  { Choice: '.ql-size', title: '字体大小' },
  { Choice: '.ql-list[value="ordered"]', title: '编号列表' },
  { Choice: '.ql-list[value="bullet"]', title: '项目列表' },
  { Choice: '.ql-direction', title: '文本方向' },
  { Choice: '.ql-header[value="1"]', title: 'h1' },
  { Choice: '.ql-header[value="2"]', title: 'h2' },
  { Choice: '.ql-align', title: '对齐方式' },
  { Choice: '.ql-color', title: '字体颜色' },
  { Choice: '.ql-background', title: '背景颜色' },
  { Choice: '.ql-image', title: '图像' },
  { Choice: '.ql-video', title: '视频' },
  { Choice: '.ql-link', title: '添加链接' },
  { Choice: '.ql-formula', title: '插入公式' },
  { Choice: '.ql-clean', title: '清除字体格式' },
  { Choice: '.ql-script[value="sub"]', title: '下标' },
  { Choice: '.ql-script[value="super"]', title: '上标' },
  { Choice: '.ql-indent[value="-1"]', title: '向左缩进' },
  { Choice: '.ql-indent[value="+1"]', title: '向右缩进' },
  { Choice: '.ql-header .ql-picker-label', title: '标题大小' },
  { Choice: '.ql-header .ql-picker-item[data-value="1"]', title: '标题一' },
  { Choice: '.ql-header .ql-picker-item[data-value="2"]', title: '标题二' },
  { Choice: '.ql-header .ql-picker-item[data-value="3"]', title: '标题三' },
  { Choice: '.ql-header .ql-picker-item[data-value="4"]', title: '标题四' },
  { Choice: '.ql-header .ql-picker-item[data-value="5"]', title: '标题五' },
  { Choice: '.ql-header .ql-picker-item[data-value="6"]', title: '标题六' },
  { Choice: '.ql-header .ql-picker-item:last-child', title: '标准' },
  { Choice: '.ql-size .ql-picker-item[data-value="small"]', title: '小号' },
  { Choice: '.ql-size .ql-picker-item[data-value="large"]', title: '大号' },
  { Choice: '.ql-size .ql-picker-item[data-value="huge"]', title: '超大号' },
  { Choice: '.ql-size .ql-picker-item:nth-child(2)', title: '标准' },
  { Choice: '.ql-align .ql-picker-item:first-child', title: '居左对齐' },
  { Choice: '.ql-align .ql-picker-item[data-value="center"]', title: '居中对齐' },
  { Choice: '.ql-align .ql-picker-item[data-value="right"]', title: '居右对齐' },
  { Choice: '.ql-align .ql-picker-item[data-value="justify"]', title: '两端对齐' }
]
export default {
  name: "newsManagement",
  components: {Editor},
  components: {quillEditor},
  data(){
    return{
      // 图片预览
@@ -316,13 +413,183 @@
          value:1
        }
      ]
      ],
      file: null,
      Quill:'',
      defaultValue: '',
      editorOption: {
        placeholder: '请在这里输入',
        theme: 'snow', //主题 snow/bubble
        modules: {
          history: {
            delay: 1000,
            maxStack: 50,
            userOnly: false
          },
          toolbar: {
            container: toolbarOptions,
            handlers: {
              myUploadBtn: this.myMethod,
            }
          }
        }
      }
    }
  },
  // 在组件创建前注册
  beforeCreate() {
    Quill.register(VideoBlot, true);
  },
  mounted() {
    this.getNewsList();
    //初始化
    this.$nextTick(() => {
      if (this.$refs.QuillEditor) {
        this.Quill=this.$refs.QuillEditor.quill
        this.getNewsList();
        this.initTitle();
        this.initButton();
      }
    })
  },
  methods:{
    onEditorBlur(editor) {
    },
    // 获得焦点
    onEditorFocus(editor) {
    },
    // 开始
    onEditorReady(editor) {
    },
    myMethod(){
      this.$refs.upload.handleClick();
    },
    initButton(){
      const editorButton = document.querySelector('.ql-myUploadBtn')
      editorButton.innerHTML = '<svg t="1751966766109" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1530" fill="currentColor"  style="width: 1em; height: 1em; vertical-align: middle;"><path d="M1024 693.248q0 25.6-8.704 48.128t-24.576 40.448-36.864 30.208-45.568 16.384l1.024 1.024-17.408 0-4.096 0-4.096 0-675.84 0q-5.12 1.024-16.384 1.024-39.936 0-74.752-15.36t-60.928-41.472-40.96-60.928-14.848-74.752 14.848-74.752 40.96-60.928 60.928-41.472 74.752-15.36l1.024 0q-1.024-8.192-1.024-15.36l0-16.384q0-72.704 27.648-137.216t75.776-112.128 112.128-75.264 136.704-27.648 137.216 27.648 112.64 75.264 75.776 112.128 27.648 137.216q0 37.888-8.192 74.24t-22.528 69.12q5.12-1.024 10.752-1.536t10.752-0.512q27.648 0 52.736 10.752t43.52 29.696 29.184 44.032 10.752 53.76zM665.6 571.392q20.48 0 26.624-4.608t-8.192-22.016q-14.336-18.432-31.744-48.128t-36.352-60.416-38.4-57.344-37.888-38.912q-18.432-13.312-27.136-14.336t-25.088 12.288q-18.432 15.36-35.84 38.912t-35.328 50.176-35.84 52.224-36.352 45.056q-18.432 18.432-13.312 32.768t25.6 14.336l16.384 0q9.216 0 19.968 0.512t20.992 0.512l17.408 0q14.336 1.024 18.432 9.728t4.096 24.064q0 17.408-0.512 30.72t-0.512 25.6-0.512 25.6-0.512 30.72q0 7.168 1.536 15.36t5.632 15.36 12.288 11.776 21.504 4.608l23.552 0q9.216 0 27.648 1.024 24.576 0 28.16-12.288t3.584-38.912q0-23.552 0.512-42.496t0.512-51.712q0-23.552 4.608-36.352t19.968-12.8q11.264 0 32.256-0.512t32.256-0.512z" p-id="1531"></path></svg>'
    },
    initTitle() {
      document.getElementsByClassName('ql-editor')[0].dataset.placeholder = ''
      for (let item of titleConfig) {
        let tip = document.querySelector('.quill-editor ' + item.Choice)
        if (!tip) continue
        tip.setAttribute('title', item.title)
      }
    },
    handleUploadEdit(file){
      const fileType = file.type
      const isImage = fileType.includes('image')
      const isVideo = fileType.includes('video')
      if (!isImage && !isVideo) {
        this.$Message.error('请上传图片或视频文件')
        return false
      }
      if (file.size > 20 * 1024 * 1024) {
        this.$Message.error('文件大小不能超过20MB')
        return false
      }
      this.file = file
      this.uploadFile2()
      return false
    },
    getFileType(file) {
      // 获取文件类型或扩展名
      let type, extension;
      if (file instanceof File) {
        // 如果是File对象
        type = file.type;
        const name = file.name.toLowerCase();
        extension = name.substring(name.lastIndexOf('.') + 1);
      } else if (typeof file === 'string') {
        // 如果是字符串(文件名或URL)
        const name = file.toLowerCase();
        extension = name.substring(name.lastIndexOf('.') + 1);
        // 尝试从URL中提取MIME类型(如果有)
        const mimeMatch = file.match(/^data:(.+?);/);
        if (mimeMatch) {
          type = mimeMatch[1];
        }
      } else {
        return 'unknown';
      }
      // 常见图片和视频的MIME类型
      const imageTypes = [
        'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/bmp', 'image/svg+xml'
      ];
      const videoTypes = [
        'video/mp4', 'video/webm', 'video/ogg', 'video/quicktime', 'video/x-msvideo', 'video/x-matroska'
      ];
      // 检查MIME类型
      if (type) {
        if (imageTypes.includes(type)) return 'image';
        if (videoTypes.includes(type)) return 'video';
      }
      // 常见图片和视频的扩展名
      const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg'];
      const videoExtensions = ['mp4', 'webm', 'ogg', 'mov', 'avi', 'mkv'];
      // 检查文件扩展名
      if (extension) {
        if (imageExtensions.includes(extension)) return 'image';
        if (videoExtensions.includes(extension)) return 'video';
      }
      return 'unknown';
    },
    uploadFile2() {
      if (!this.file) return
      this.submitLoading = true
      const formData = new FormData()
      formData.append('file', this.file)
      uploadFileByLmk(formData).then(res => {
        this.submitLoading = false
        if (res.code === 200) {
          let url = res.data.url;
          let fileKey = res.data.fileKey;
          let fileType = this.getFileType(this.file);
          console.log("打印")
          console.log(this.Quill);
          const range = this.Quill.getSelection();
          const index = range ? range.index : this.Quill.getLength();
          console.log(fileType);
          if (fileType === 'video') {
            this.Quill.insertEmbed(index, 'video', {
              url:url,
              controls:'controls',
              width:'100%',
              height:'auto'
            });
          } else if (fileType === 'image') {
            this.Quill.insertEmbed(index, "image", url);
          } else {
            // 如果不是图片或视频,可以处理其他类型或给出提示
            this.$Message.warning('不支持的文件类型');
            return;
          }
          console.log("--------");
          console.log(this.newsForm.content)
          this.Quill.setSelection(index + 1);
          this.$Message.success('上传成功')
        }else{
          this.$Message.error(res.msg)
        }
      }).catch(() => {
        this.submitLoading = false
      })
    },
    getNewsList(){
      this.loading = true
      getNews(this.searchForm).then(res =>{
@@ -338,10 +605,9 @@
        this.loading = false
      })
    },
    getReason(content) {
      this.newsForm.content = content
    },
    saveOrUpdate(){
      console.log(this.newsForm)
      this.$refs.form.validate(valid => {
        if (valid) {
          this.submitLoading = true
@@ -376,16 +642,20 @@
        }
      })
    },
    infoModelClose(){
      this.infoModelShow = false;
    },
    modelClose(){
      this.modelShow = false;
    },
    changePage(page) {
      this.searchForm.pageNumber = page
      this.getNewsList()
    },
    // 改变每页条数
    changePageSize(pageSize) {
      this.searchForm.pageNumber = 1
@@ -402,27 +672,33 @@
      })
    },
    openEdit(row){
      this.modelTitle = '修改新闻';
      this.modelTitle = '修改快讯';
      this.modelShow = true;
      this.$refs.form.resetFields();
      this.newsForm.title = row.title;
      this.newsForm.content = row.content;
      this.newsForm.id = row.id;
      this.$refs.editor.setContent(this.newsForm.content)
      // this.$refs.editor.setContent(this.newsForm.content)
    },
    openAdd(){
      this.modelTitle = '新增新闻';
      this.modelTitle = '新增快讯';
      this.modelShow = true;
      this.$refs.form.resetFields()
      this.newsForm.id = '';
      this.newsForm.content = '';
      this.newsForm.publish = 0;
    },
    detail(row){
      this.modelTitle = '活动详情'
      this.infoModelShow = true
      this.newsInfo = row
    },
    changeStatus(row,action){
      row.statusLoading = true;
@@ -436,6 +712,7 @@
        row.statusLoading = false
      })
    },
    // 表格选择变化
    showSelect(selection) {
      this.selectList = selection.map(item => item.id)
@@ -449,6 +726,7 @@
      this.searchForm.pageNumber = 1
      this.getNewsList()
    },
    resetSearch(){
      this.$refs.searchForm.resetFields()
      this.searchForm.pageNumber = 1
@@ -460,12 +738,19 @@
</script>
<style scoped lang="scss">
.activity-management {
.ql-editor .ql-video {
  width: 50%;
  height: auto; /* 根据你的需求调整高度 */
  max-width: 100%;
}
.news-management {
  .search-form {
    padding: 16px;
    background: #f8f8f9;
    border-radius: 4px;
    margin-bottom: 16px;
    .ivu-form-item {
      margin-bottom: 16px;
@@ -475,6 +760,13 @@
    .search-btn {
      margin-left: 8px;
    }
  }
}
.operation {
  margin-bottom: 16px;
  .ivu-btn {
    margin-right: 8px;
  }
}
.detail-container {
@@ -540,4 +832,86 @@
    }
  }
}
/*
  文字大小
*/
.ql-snow .ql-picker.ql-size{
  width: 70px;  // 菜单栏占比宽度
}
/*
  字体
*/
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
  content: "黑体";
  font-family: "SimHei";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
  content: "微软雅黑";
  font-family: "Microsoft YaHei";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
  content: "楷体";
  font-family: "KaiTi";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]::before {
  content: "仿宋";
  font-family: "FangSong";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
  content: "Arial";
  font-family: "Arial";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
  content: "Times New Roman";
  font-family: "Times New Roman";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]::before {
  content: "sans-serif";
  font-family: "sans-serif";
}
.ql-font-SimSun {
  font-family: "SimSun";
}
.ql-font-SimHei {
  font-family: "SimHei";
}
.ql-font-Microsoft-YaHei {
  font-family: "Microsoft YaHei";
}
.ql-font-KaiTi {
  font-family: "KaiTi";
}
.ql-font-FangSong {
  font-family: "FangSong";
}
.ql-font-Arial {
  font-family: "Arial";
}
.ql-font-Times-New-Roman {
  font-family: "Times New Roman";
}
.ql-font-sans-serif {
  font-family: "sans-serif";
}
</style>