Browse Source

后台修改

1
mo 2 years ago
parent
commit
dc499d46f4

+ 243 - 0
src/views/contentManager/components/liveHelp.vue

@@ -0,0 +1,243 @@
+<template>
+  <div>
+    <!-- 搜索标题 -->
+    <auth auths="news/add">
+      <el-button
+        @click="openTeaching('create')"
+        type="primary"
+        style="margin-bottom: 20px"
+      >
+        新建
+      </el-button>
+    </auth>
+    <!-- 搜索标题 -->
+    <save-form
+      :inline="true"
+      class="searchForm"
+      saveKey="contentKnowledge"
+      @submit="search"
+      :model="searchForm"
+    >
+      <el-form-item prop="subType">
+        <el-select v-model="searchForm.subType" clearable placeholder="帮助类型">
+          <el-option
+            v-for="item in typeList"
+            :key="item.id"
+            :label="item.name"
+            :value="item.id"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button native-type="submit" type="danger">搜索</el-button>
+      </el-form-item>
+    </save-form>
+    <!-- 列表 -->
+    <div class="tableWrap">
+      <el-table
+        :data="tableList"
+        :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+      >
+        <el-table-column align="center" label="编号" prop="id"></el-table-column>
+
+        <el-table-column align="center" prop="title" label="标题"> </el-table-column>
+
+        <el-table-column align="center" prop="subType" label="类型">
+          <template slot-scope="scope">
+            {{ formatSubType(scope.row.subType) }}
+          </template>
+        </el-table-column>
+        <el-table-column align="center" prop="order" label="排序值"> </el-table-column>
+        <el-table-column align="center" label="操作">
+          <template slot-scope="scope">
+            <div>
+              <auth auths="news/update" style="margin-left: 10px">
+                <el-button
+                  @click="openTeaching('update', scope.row)"
+                  v-if="!scope.row.memo || permission('banner/copyrightbtn')"
+                  type="text"
+                  >修改</el-button
+                >
+              </auth>
+              <auth auths="news/del" style="margin-left: 10px">
+                <el-button
+                  @click="onDel(scope.row)"
+                  v-if="!scope.row.memo || permission('banner/copyrightbtn')"
+                  type="text"
+                  >删除</el-button
+                >
+              </auth>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        saveKey="contentKnowledge"
+        sync
+        :total.sync="pageInfo.total"
+        :page.sync="pageInfo.page"
+        :limit.sync="pageInfo.limit"
+        :page-sizes="pageInfo.page_size"
+        @pagination="getList"
+      />
+    </div>
+    <el-dialog
+      :title="formTitle[formActionTitle]"
+      :visible.sync="notifyStatus"
+      width="800px"
+    >
+      <livehelpModel
+        v-if="notifyStatus"
+        :options="systemOptions"
+        @submited="getList"
+        @close="notifyStatus = false"
+        :typeList="typeList"
+      />
+    </el-dialog>
+  </div>
+</template>
+<script>
+import { newsList, newsUpdate, newsDel, newsTypeList } from "@/api/contentManager";
+import pagination from "@/components/Pagination/index";
+import store from "@/store";
+import cleanDeep from "clean-deep";
+import { permission } from "@/utils/directivePage";
+import livehelpModel from "../model/livehelpModel.vue";
+export default {
+  name: "knowledge",
+  components: {
+    pagination,
+    livehelpModel,
+  },
+  data() {
+    return {
+      searchForm: {
+        organIdList: [],
+        subjectId: null,
+        subType: null,
+      },
+      tableList: [],
+      teacherId: this.$route.query.teacherId,
+      pageInfo: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 1, // 总条数
+        page_size: [10, 20, 40, 50], // 选择限制显示条数
+      },
+      typeList: [
+        { name: "帮助中心", id: 27 },
+        { name: "功能介绍", id: 28 },
+      ], // 子分类
+      formTitle: {
+        create: "新建帮助",
+        update: "修改帮助",
+      },
+      notifyStatus: false,
+      formActionTitle: "",
+    };
+  },
+  async mounted() {
+    this.$store.dispatch("setSubjects");
+    await newsTypeList({ parentId: 26 }).then((res) => {
+      if (res.code == 200) {
+        this.typeList = res.data;
+      }
+    });
+    this.$store.dispatch("setBranchs");
+    this.getList();
+  },
+  methods: {
+    search() {
+      this.pageInfo.page = 1;
+      this.getList();
+    },
+    permission(str) {
+      return permission(str);
+    },
+    getList() {
+      let params = {
+        subType: this.searchForm.subType,
+        rows: this.pageInfo.limit,
+        page: this.pageInfo.page,
+        type: 26,
+      };
+      newsList(cleanDeep(params)).then((res) => {
+        if (res.code == 200) {
+          this.tableList = res.data.rows;
+          this.pageInfo.total = res.data.total;
+        }
+      });
+    },
+    openTeaching(type, rows) {
+      let params = {};
+      if (type == "update") {
+        params.id = rows.id;
+      }
+      this.formActionTitle = type;
+      params.type = 26;
+      params.pageType = type;
+      this.systemOptions = params;
+      this.notifyStatus = true;
+    },
+    onDel(row) {
+      // 删除
+      this.$confirm("确定是否删除?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          newsDel({ id: row.id }).then((res) => {
+            if (res.code == 200) {
+              this.$message.success("删除成功");
+              this.getList();
+            } else {
+              this.$message.error(res.msg);
+            }
+          });
+        })
+        .catch(() => {});
+    },
+    onStop(row, status) {
+      // 停止
+      // newsUpdate
+      let tempStr = ["停用", "启用"];
+      newsUpdate({
+        id: row.id,
+        status: status,
+      }).then((res) => {
+        if (res.code == 200) {
+          this.$message.success(tempStr[status] + "成功");
+          this.getList();
+        } else {
+          this.$message.error(res.msg);
+        }
+      });
+    },
+    formatSubType(val) {
+      let tempName = null;
+      this.typeList.forEach((item) => {
+        if (item.id == val) {
+          tempName = item.name;
+        }
+      });
+      return tempName;
+    },
+  },
+  filters: {
+    // formatSubType(val) {
+    //   let template = {
+    //     27: "帮助中心",
+    //     28: "功能介绍",
+    //   };
+    //   return template[val];
+    // },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.bannerImg {
+  height: 60px;
+}
+</style>

+ 90 - 85
src/views/contentManager/components/systemNotify.vue

@@ -2,31 +2,38 @@
   <div>
     <!-- 搜索标题 -->
     <auth auths="news/add/system">
-       <el-button
+      <el-button
         @click="openTeaching('create')"
         type="primary"
-        style="margin-bottom:20px"
+        style="margin-bottom: 20px"
       >
         新建
       </el-button>
     </auth>
     <!-- 搜索标题 -->
-    <save-form :inline="true"
-             class="searchForm"
-             :saveKey="'contentAdvert'"
-             @submit="search"
-             :model="searchForm">
+    <save-form
+      :inline="true"
+      class="searchForm"
+      :saveKey="'contentAdvert'"
+      @submit="search"
+      :model="searchForm"
+    >
       <el-form-item prop="organIdList">
-        <select-all class="multiple" clearable
-                   filterable
-                   collapse-tags
-                   multiple
-                   v-model.trim="searchForm.organIdList"
-                   placeholder="请选择分部">
-          <el-option v-for="(item,index) in selects.branchs"
-                    :key="index"
-                    :label="item.name"
-                    :value="item.id"></el-option>
+        <select-all
+          class="multiple"
+          clearable
+          filterable
+          collapse-tags
+          multiple
+          v-model.trim="searchForm.organIdList"
+          placeholder="请选择分部"
+        >
+          <el-option
+            v-for="(item, index) in selects.branchs"
+            :key="index"
+            :label="item.name"
+            :value="item.id"
+          ></el-option>
         </select-all>
       </el-form-item>
       <el-form-item>
@@ -35,93 +42,89 @@
     </save-form>
     <!-- 列表 -->
     <div class="tableWrap">
-      <el-table :data="tableList"
-                :header-cell-style="{background:'#EDEEF0',color:'#444'}">
-        <el-table-column align="center"
-                         prop="title"
-                         label="标题"></el-table-column>
-        <el-table-column align="center"
-                         prop="remark"
-                         label="是否使用">
-          <template slot-scope="scope">{{ scope.row.status == 1 ? '是' : '否' }}</template>
+      <el-table
+        :data="tableList"
+        :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+      >
+        <el-table-column align="center" prop="title" label="标题"></el-table-column>
+        <el-table-column align="center" prop="remark" label="是否使用">
+          <template slot-scope="scope">{{
+            scope.row.status == 1 ? "是" : "否"
+          }}</template>
         </el-table-column>
-        <el-table-column align="center"
-                         prop="order"
-                         label="排序"></el-table-column>
-        <el-table-column align="center"
-                         label="外链地址">
+        <el-table-column align="center" prop="order" label="排序"></el-table-column>
+        <el-table-column align="center" label="外链地址">
           <template slot-scope="scope">
             <overflow-text :text="scope.row.linkUrl"></overflow-text>
           </template>
         </el-table-column>
-        <el-table-column align="center"
-                         prop="remark"
-                         label="适用分部">
+        <el-table-column align="center" prop="remark" label="适用分部">
           <template slot-scope="scope">
             <overflow-text :text="scope.row.organNameList"></overflow-text>
           </template>
         </el-table-column>
-        <el-table-column align="center"
-                         label="操作">
+        <el-table-column align="center" label="操作">
           <template slot-scope="scope">
-              <div>
+            <div>
               <auth auths="news/update/system" style="margin-left: 10px">
-                <el-button
-                  @click="openTeaching('update', scope.row)"
-                  type="text"
+                <el-button @click="openTeaching('update', scope.row)" type="text"
                   >修改</el-button
                 >
               </auth>
-              <auth v-if="scope.row.status == 1" auths="news/update/systemStop" style="margin-left: 10px">
-                <el-button
-                  @click="onStop(scope.row, 0)"
-                  type="text"
-                  >停用</el-button
-                >
+              <auth
+                v-if="scope.row.status == 1"
+                auths="news/update/systemStop"
+                style="margin-left: 10px"
+              >
+                <el-button @click="onStop(scope.row, 0)" type="text">停用</el-button>
               </auth>
               <auth v-else auths="news/update/systemStart" style="margin-left: 10px">
-                <el-button  @click="onStop(scope.row, 1)" type="text"
-                  >启用</el-button
-                >
+                <el-button @click="onStop(scope.row, 1)" type="text">启用</el-button>
               </auth>
               <auth auths="news/del/system" style="margin-left: 10px">
-                <el-button @click="onDel(scope.row)" type="text"
-                  >删除</el-button
-                >
+                <el-button @click="onDel(scope.row)" type="text">删除</el-button>
               </auth>
             </div>
           </template>
         </el-table-column>
       </el-table>
-      <pagination sync :total.sync="pageInfo.total"
-                  :page.sync="pageInfo.page"
-                  :limit.sync="pageInfo.limit"
-                  :page-sizes="pageInfo.page_size"
-                  @pagination="getList" />
+      <pagination
+        sync
+        :total.sync="pageInfo.total"
+        :page.sync="pageInfo.page"
+        :limit.sync="pageInfo.limit"
+        :page-sizes="pageInfo.page_size"
+        @pagination="getList"
+      />
     </div>
     <el-dialog
       :title="formTitle[formActionTitle]"
       :visible.sync="notifyStatus"
       width="800px"
     >
-      <system-notify-model v-if="notifyStatus" :options="systemOptions" @submited="getList" @close="notifyStatus = false" />
+      <system-notify-model
+        v-if="notifyStatus"
+        :options="systemOptions"
+        @submited="getList"
+        @close="notifyStatus = false"
+      />
     </el-dialog>
   </div>
 </template>
 <script>
 import { newsList, newsUpdate, newsDel } from "@/api/contentManager";
 import pagination from "@/components/Pagination/index";
-import systemNotifyModel from '../model/systemNotifyModel'
+import systemNotifyModel from "../model/systemNotifyModel";
 export default {
   name: "training",
   components: {
     pagination,
-    systemNotifyModel
+    systemNotifyModel,
   },
-  data () {
+  data() {
     return {
       searchForm: {
-        organIdList: []
+        organIdList: [],
       },
       tableList: [],
       teacherId: this.$route.query.teacherId,
@@ -130,61 +133,63 @@ export default {
         limit: 10, // 限制显示条数
         page: 1, // 当前页
         total: 1, // 总条数
-        page_size: [10, 20, 40, 50] // 选择限制显示条数
+        page_size: [10, 20, 40, 50], // 选择限制显示条数
       },
       formActionTitle: "create",
       formTitle: {
         create: "新建系统通知",
-        update: "修改系统通知"
+        update: "修改系统通知",
       },
       notifyStatus: false,
       systemOptions: null,
     };
   },
-  mounted () {
+  mounted() {
     this.$store.dispatch("setBranchs");
     this.getList();
   },
   methods: {
     search() {
-      this.pageInfo.page = 1
-      this.getList()
+      this.pageInfo.page = 1;
+      this.getList();
     },
-    getList () {
+    getList() {
       let params = {
-        clientName: 'manage',
-        organIdList: this.searchForm.organIdList ? this.searchForm.organIdList.join(',') : null,
+        clientName: "manage",
+        organIdList: this.searchForm.organIdList
+          ? this.searchForm.organIdList.join(",")
+          : null,
         rows: this.pageInfo.limit,
         page: this.pageInfo.page,
-        type: 19
+        type: 19,
       };
-      newsList(params).then(res => {
+      newsList(params).then((res) => {
         if (res.code == 200) {
           this.tableList = res.data.rows;
           this.pageInfo.total = res.data.total;
         }
       });
     },
-    openTeaching (type, rows) {
+    openTeaching(type, rows) {
       let params = {};
       if (type == "update") {
         params.id = rows.id;
       }
-      this.formActionTitle = type
+      this.formActionTitle = type;
       params.type = 19;
       params.pageType = type;
-      this.systemOptions = params
-      this.notifyStatus = true
+      this.systemOptions = params;
+      this.notifyStatus = true;
     },
-    onDel (row) {
+    onDel(row) {
       // 删除
       this.$confirm("确定是否删除?", "提示", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
-        type: "warning"
+        type: "warning",
       })
         .then(() => {
-          newsDel({ id: row.id }).then(res => {
+          newsDel({ id: row.id }).then((res) => {
             if (res.code == 200) {
               this.$message.success("删除成功");
               this.getList();
@@ -193,16 +198,16 @@ export default {
             }
           });
         })
-        .catch(() => { });
+        .catch(() => {});
     },
-    onStop (row, status) {
+    onStop(row, status) {
       // 停止
       // newsUpdate
       let tempStr = ["停用", "启用"];
       newsUpdate({
         id: row.id,
-        status: status
-      }).then(res => {
+        status: status,
+      }).then((res) => {
         if (res.code == 200) {
           this.$message.success(tempStr[status] + "成功");
           this.getList();
@@ -210,8 +215,8 @@ export default {
           this.$message.error(res.msg);
         }
       });
-    }
-  }
+    },
+  },
 };
 </script>
 <style lang="scss" scoped>

+ 58 - 66
src/views/contentManager/index.vue

@@ -1,22 +1,15 @@
 <template>
-  <div class='m-container'>
+  <div class="m-container">
     <h2>
-      <div class="squrt"></div> 内容管理
+      <div class="squrt"></div>
+      内容管理
     </h2>
     <div class="m-core">
-      <tab-router v-model.trim="activeName"
-               type="card"
-               @tab-click="handleClick">
-        <el-tab-pane label="精彩活动"
-                     v-if="permissionList.activity"
-                     lazy
-                     name="0">
+      <tab-router v-model.trim="activeName" type="card" @tab-click="handleClick">
+        <el-tab-pane label="精彩活动" v-if="permissionList.activity" lazy name="0">
           <activity v-if="activeName == 0" />
         </el-tab-pane>
-        <el-tab-pane label="热门资讯"
-                     v-if="permissionList.information"
-                     lazy
-                     name="1">
+        <el-tab-pane label="热门资讯" v-if="permissionList.information" lazy name="1">
           <information v-if="activeName == 1" />
         </el-tab-pane>
         <!-- <el-tab-pane label="专项训练"
@@ -25,17 +18,11 @@
                      name="2">
           <training v-if="activeName == 2" />
         </el-tab-pane> -->
-        <el-tab-pane label="闪页管理"
-                     v-if="permissionList.flashPage"
-                     lazy
-                     name="3">
+        <el-tab-pane label="闪页管理" v-if="permissionList.flashPage" lazy name="3">
           <flashPage v-if="activeName == 3" />
         </el-tab-pane>
-        <el-tab-pane label="BANNER管理"
-                     v-if="permissionList.banner"
-                     lazy
-                     name="4">
-          <banner  v-if="activeName == 4" />
+        <el-tab-pane label="BANNER管理" v-if="permissionList.banner" lazy name="4">
+          <banner v-if="activeName == 4" />
         </el-tab-pane>
         <!-- <el-tab-pane label="APP按钮管理"
                      v-if="permissionList.appPage"
@@ -44,39 +31,34 @@
           <appPage v-if="activeName == 5" />
         </el-tab-pane>
          -->
-         <el-tab-pane label="知识库管理"
-                     v-if="permissionList.knowledge"
-                     lazy
-                     name="6">
-          <knowledge  v-if="activeName == 6" />
+        <el-tab-pane label="知识库管理" v-if="permissionList.knowledge" lazy name="6">
+          <knowledge v-if="activeName == 6" />
         </el-tab-pane>
-        <el-tab-pane label="广告管理"
-                     v-if="permissionList.advert"
-                     lazy
-                     name="7">
+        <el-tab-pane label="广告管理" v-if="permissionList.advert" lazy name="7">
           <advert v-if="activeName == 7" />
         </el-tab-pane>
-        <el-tab-pane label="系统通知"
-                     v-if="permissionList.systemNotify"
-                     lazy
-                     name="8">
+        <el-tab-pane label="系统通知" v-if="permissionList.systemNotify" lazy name="8">
           <systemNotify v-if="activeName == 8" />
         </el-tab-pane>
+        <el-tab-pane label="直播帮助" lazy name="9">
+          <liveHelp v-if="activeName == 9" />
+        </el-tab-pane>
       </tab-router>
     </div>
   </div>
 </template>
 <script>
-import banner from './components/banner'
-import activity from './components/activity'
-import information from './components/information'
-import training from './components/training'
-import flashPage from './components/flashPage'
-import appPage from './components/appPage'
-import knowledge from './components/knowledge'
-import advert from './components/advert'
-import systemNotify from './components/systemNotify'
-import { permission } from '@/utils/directivePage'
+import banner from "./components/banner";
+import activity from "./components/activity";
+import information from "./components/information";
+import training from "./components/training";
+import flashPage from "./components/flashPage";
+import appPage from "./components/appPage";
+import knowledge from "./components/knowledge";
+import advert from "./components/advert";
+import systemNotify from "./components/systemNotify";
+import liveHelp from "./components/liveHelp.vue";
+import { permission } from "@/utils/directivePage";
 // 精彩活动 1 0
 // 热门资讯 2 1
 // 专项训练 4 2
@@ -87,30 +69,40 @@ import { permission } from '@/utils/directivePage'
 // 广告管理 8 7
 // 系统通知 19 8
 export default {
-  components: { banner, activity, information, training, flashPage, appPage, knowledge, advert, systemNotify },
-  name: 'contentManager',
-  data () {
+  components: {
+    banner,
+    activity,
+    information,
+    training,
+    flashPage,
+    appPage,
+    knowledge,
+    advert,
+    systemNotify,
+    liveHelp,
+  },
+  name: "contentManager",
+  data() {
     return {
       activeName: "0",
       permissionList: {
-        banner: permission('/contentManager/banner'),
-        activity: permission('/contentManager/activity'),
-        information: permission('/contentManager/information'),
-        training: permission('/contentManager/training'),
-        flashPage: permission('/contentManager/flashPage'),
-        appPage: permission('/contentManager/appPage'),
-        knowledge: permission('/contentManager/knowledge'),
-        advert: permission('/contentManager/advert'),
-        systemNotify: permission('/contentManager/systemNotify'),
-      }
-    }
+        banner: permission("/contentManager/banner"),
+        activity: permission("/contentManager/activity"),
+        information: permission("/contentManager/information"),
+        training: permission("/contentManager/training"),
+        flashPage: permission("/contentManager/flashPage"),
+        appPage: permission("/contentManager/appPage"),
+        knowledge: permission("/contentManager/knowledge"),
+        advert: permission("/contentManager/advert"),
+        systemNotify: permission("/contentManager/systemNotify"),
+      },
+    };
   },
   methods: {
-    handleClick (val, event) {
-      this.activeName = val.name
-    }
-  }
-}
+    handleClick(val, event) {
+      this.activeName = val.name;
+    },
+  },
+};
 </script>
-<style lang="scss">
-</style>
+<style lang="scss"></style>

+ 842 - 0
src/views/contentManager/model/livehelpModel.vue

@@ -0,0 +1,842 @@
+<template>
+  <div class="systemNotifyModel">
+    <div class="m-core">
+      <el-form
+        :model="form"
+        :rules="rules"
+        ref="form"
+        label-width="110px"
+        style="width: 100%"
+      >
+        <el-form-item label="标题" prop="title">
+          <el-input v-model.trim="form.title" placeholder="请输入标题"></el-input>
+        </el-form-item>
+        <el-form-item label="排序值">
+          <el-input
+            v-model.trim="form.order"
+            placeholder="请输入排序值"
+            type="number"
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="subType" label="类型">
+          <el-select v-model="form.subType" clearable placeholder="帮助类型">
+            <el-option
+              v-for="item in typeList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <!-- <el-form-item label="自动开启时间" prop="actionTime" :rules="[{required: true, message: '请选择自动开启时间范围', trigger: 'change'}]">
+          <el-date-picker style="width:400px;"
+                        v-model="form.actionTime"
+                        :clearable="false"
+                        type="datetimerange"
+                        range-separator="至"
+                        :picker-options="{ firstDayOfWeek: 1 }"
+                        start-placeholder="开始日期"
+                        end-placeholder="结束日期">
+                    </el-date-picker>
+        </el-form-item> -->
+
+        <el-form-item
+          label="内容"
+          prop="content"
+          v-if="outUrlRadio == 0"
+          :rules="[{ required: true, message: '请编辑内容', trigger: 'blur' }]"
+        >
+          <quill-editor
+            class="ql-editor"
+            style="margin-top: -17px"
+            v-model="form.content"
+            ref="myQuillEditor"
+            :options="editorOption"
+            @change="onEditorChange($event)"
+          ></quill-editor>
+
+          <el-upload
+            class="ivu-upload"
+            :show-upload-list="false"
+            :on-success="handleSuccess"
+            accept=".jpg, .jpeg, .png, .gif"
+            :max-size="2048"
+            multiple
+            :action="ossUploadUrl"
+            :data="dataObj"
+            :before-upload="beforeImgUpload"
+          >
+            <Button icon="ios-cloud-upload-outline"></Button>
+          </el-upload>
+        </el-form-item>
+        <el-form-item>
+          <el-button @click="onSubmit('form')" type="primary"
+            >立即{{ pageType == "create" ? "创建" : "修改" }}</el-button
+          >
+          <el-button @click="onReSet('form')">重置</el-button>
+          <!-- <el-button @click="onLook">预览</el-button> -->
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <el-dialog
+      title="插入视频"
+      :append-to-body="true"
+      width="500px"
+      @close="onDialogClose('diologForm')"
+      :visible.sync="dialogFormVisible"
+    >
+      <el-form :model="dialogForm" ref="diologForm" :rules="dialogFormRules">
+        <el-form-item
+          label="封面图地址"
+          prop="poster"
+          :rules="[
+            {
+              required: uploadType == 2 ? true : false,
+              message: '请上传封面图',
+              trigger: 'blur',
+            },
+          ]"
+          label-width="120px"
+        >
+          <el-upload
+            class="avatar-uploader"
+            style="line-height: 0; display: inline-block"
+            :action="ossUploadUrl"
+            :data="dataObj"
+            :show-file-list="false"
+            v-loading="uploadImgLoading"
+            accept=".jpg, .jpeg, .png, .gif"
+            :on-success="handleImgSuccess"
+            :on-error="handleUploadImgError"
+            :before-upload="beforeImgUpload"
+          >
+            <img v-if="dialogForm.poster" :src="dialogForm.poster" class="avatar" />
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+        </el-form-item>
+        <el-form-item label="视频类型" label-width="120px">
+          <el-radio-group v-model="formRadio">
+            <el-radio :label="1">外部链接</el-radio>
+            <el-radio :label="2">上传</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item
+          v-if="formRadio == 1"
+          label="视频地址"
+          label-width="120px"
+          prop="url"
+        >
+          <el-input
+            v-model="dialogForm.url"
+            style="width: 100%"
+            autocomplete="off"
+          ></el-input>
+        </el-form-item>
+        <el-form-item
+          v-if="formRadio == 2"
+          label="上传视频"
+          label-width="120px"
+          prop="videoUrl"
+        >
+          <el-upload
+            class="upload-demo"
+            style="display: inline-block"
+            v-loading="uploadLoading"
+            :action="ossUploadUrl"
+            :data="dataObj"
+            :before-upload="beforeUpload"
+            :on-success="handleUploadSuccess"
+            :on-error="handleUploadError"
+            :show-file-list="false"
+            accept=".mp4"
+            :file-list="fileList"
+            :on-exceed="handleExceed"
+          >
+            <video
+              style="width: 120px; height: 120px"
+              v-if="dialogForm.videoUrl"
+              type="video/mp4"
+              preload="auto"
+              :src="dialogForm.videoUrl"
+            ></video>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+          <p class="imageSize">
+            <!-- 广告管理 & 广告类型为 视频 -->
+            <span v-if="uploadType == 2 && type == 8"
+              >上传视频尺寸建议:1242px * 2208px;</span
+            ><br />
+            只能上传mp4文件, 且不超过100M
+          </p>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">取 消</el-button>
+        <el-button type="primary" @click="onVideoComfirm('diologForm')">确 定</el-button>
+      </div>
+    </el-dialog>
+
+    <el-dialog
+      width="375px"
+      title="预览"
+      :append-to-body="true"
+      :visible.sync="lookVisible"
+    >
+      <div class="sd-container">
+        <h2>{{ dataInfo.title }}</h2>
+        <div class="titleInfo">
+          <p>{{ typeCheck(dataInfo.type) }}</p>
+          <p>{{ dataInfo.updateTime }}</p>
+        </div>
+        <div class="msgWrap quill-editor ql-editor" v-html="dataInfo.content"></div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import { policy } from "@/api/appTenant";
+import { newsQueryId, newsAdd, newsUpdate } from "@/api/contentManager";
+import { getToken } from "@/utils/auth";
+import { vaildStudentUrl } from "@/utils/validate";
+import "quill/dist/quill.core.css";
+import "quill/dist/quill.snow.css";
+import "quill/dist/quill.bubble.css";
+import Quill from "quill";
+import { quillEditor } from "vue-quill-editor";
+// 工具栏配置
+const toolbarOptions = [
+  ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
+  ["blockquote", "code-block"], // 引用  代码块
+  [{ header: 1 }, { header: 2 }], // 1、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"], // 清除文本格式
+  ["image", "video"], // 链接、图片、视频
+  // ["link", "image", "video"] // 链接、图片、视频
+];
+// 标题
+const titleConfig = {
+  "ql-bold": "加粗",
+  "ql-color": "颜色",
+  "ql-font": "字体",
+  "ql-code": "插入代码",
+  "ql-italic": "斜体",
+  // 'ql-link': '添加链接',
+  "ql-background": "背景颜色",
+  "ql-size": "字体大小",
+  "ql-strike": "删除线",
+  "ql-script": "上标/下标",
+  "ql-underline": "下划线",
+  "ql-blockquote": "引用",
+  "ql-header": "标题",
+  "ql-indent": "缩进",
+  "ql-list": "列表",
+  "ql-align": "文本对齐",
+  "ql-direction": "文本方向",
+  "ql-code-block": "代码块",
+  "ql-formula": "公式",
+  "ql-image": "图片",
+  "ql-video": "视频",
+  "ql-clean": "清除字体样式",
+  "ql-upload": "文件",
+};
+
+// 这里引入修改过的video模块并注册
+import Video from "../../quill/video.js";
+import dayjs from "dayjs";
+Quill.register(Video, true);
+export default {
+  props: ["options", "typeList"],
+  name: "contentOperation",
+  components: {
+    quillEditor,
+  },
+  data() {
+    let that = this;
+    const query = this.options;
+    return {
+      uploadType: 1, // 上传类型
+      uploadStatus: false,
+      type: query.type,
+      pageType: query.pageType,
+      organId: null,
+      // headers: {
+      //     Authorization: getToken()
+      // },
+      content: null,
+      dialogFormVisible: false,
+      formRadio: 1,
+      lookVisible: false,
+      dataInfo: {
+        title: "",
+        type: query.type,
+        updateTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
+        content: null,
+      },
+      editorIndex: 0, // 光标位置
+      editorOption: {
+        placeholder: "请输入内容",
+        modules: {
+          toolbar: {
+            container: toolbarOptions,
+            handlers: {
+              image: function (value) {
+                if (value) {
+                  // 调用iview图片上传
+                  document.querySelector(".ivu-upload .el-upload").click();
+                } else {
+                  this.quill.format("image", false);
+                }
+              },
+              video: function (value) {
+                if (value) {
+                  that.dialogFormVisible = true;
+                  let editor = that.$refs.myQuillEditor.quill;
+                  // 光标所在位置
+                  that.editorIndex = editor.getSelection().index;
+                } else {
+                  this.quill.format("image", false);
+                }
+              },
+            },
+          },
+        },
+      },
+      dialogForm: {
+        poster: null,
+        url: null,
+        videoUrl: null,
+      },
+      uploadLoading: false,
+      uploadImgLoading: false,
+      fileList: [],
+      dialogFormRules: {
+        url: [{ required: true, message: "请输入视频地址", trigger: "blur" }],
+        videoUrl: [{ required: true, message: "请上传视频", trigger: "blur" }],
+      },
+      outUrlRadio: 0, // 是否使用外部连接,默认不使用
+      form: {
+        title: null,
+        order: null,
+        linkUrl: null,
+        type: query.type,
+        status: 0,
+        content: null,
+        organIdList: [],
+      },
+      rules: {
+        title: [
+          { required: true, message: "请输入标题", trigger: "blur" },
+          {
+            min: 2,
+            max: 30,
+            message: "长度在 2 到 30 个字符",
+            trigger: "blur",
+          },
+        ],
+        organIdList: [{ required: true, message: "请选择分部", trigger: "change" }],
+      },
+      imageSize: null,
+      dataObj: {
+        policy: "",
+        signature: "",
+        key: "",
+        KSSAccessKeyId: "",
+        // dir: "",
+        acl: "public-read",
+        name: "",
+        // bucket_name: props.bucket_name
+      },
+      // ossUploadUrl: "https://ks3-cn-beijing.ksyuncs.com/" + "news-info",
+      ossUploadUrl: `https://gyt.ks3-cn-beijing.ksyuncs.com`,
+      bucket_name: "gyt",
+    };
+  },
+  mounted() {
+    this.$store.dispatch("setBranchs");
+    this.init();
+  },
+  methods: {
+    init() {
+      this.getList();
+      this.addQuillTitle();
+
+      // this.form.type
+      let tempTitle = {
+        1: "468px * 552px;图片不能超过 2M;",
+        2: "456px * 288px; 图片不能超过 2M;",
+        3: "686px * 140px; 图片不能超过 2M;",
+        4: "图片不能超过 2M;",
+        5: "图片不能超过 2M;",
+        6: "图片不能超过 2M;",
+        7: "图片不能超过 2M;",
+        8: "1242px * 2208px; 图片不能超过 2M;",
+      };
+      this.imageSize = tempTitle[this.form.type];
+
+      this.$refs["form"].clearValidate();
+    },
+    onVideoComfirm(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          let dialogForm = this.dialogForm;
+          // 编辑器输入视频
+          // 获取富文本组件实例
+          let quill = this.editor;
+          // 插入图片,res为服务器返回的图片链接地址
+          const params = {
+            poster: dialogForm.poster,
+            url: this.formRadio == 1 ? dialogForm.url : dialogForm.videoUrl,
+          };
+          quill.insertEmbed(this.editorIndex, "video", params);
+          // 调整光标到最后
+          quill.setSelection(this.editorIndex + 1, { preload: false });
+
+          this.dialogFormVisible = false;
+          this.dialogForm = {
+            poster: null,
+            url: null,
+            videoUrl: null,
+          };
+        } else {
+          return false;
+        }
+      });
+    },
+    onDialogClose(diologForm) {
+      this.dialogForm = {
+        poster: null,
+        url: null,
+        videoUrl: null,
+      };
+      this.$refs[diologForm].resetFields();
+    },
+    addQuillTitle() {
+      const oToolBar = document.querySelector(".ql-toolbar"),
+        aButton = oToolBar.querySelectorAll("button"),
+        aSelect = oToolBar.querySelectorAll("select");
+      aButton.forEach(function (item) {
+        if (item.className === "ql-script") {
+          item.value === "sub" ? (item.title = "下标") : (item.title = "上标");
+        } else if (item.className === "ql-indent") {
+          item.value === "+1" ? (item.title = "向右缩进") : (item.title = "向左缩进");
+        } else {
+          item.title = titleConfig[item.classList[0]];
+        }
+      });
+      aSelect.forEach(function (item) {
+        item.parentNode.title = titleConfig[item.classList[0]];
+      });
+    },
+    onSubmit(formName) {
+      this.$refs[formName].validate(async (valid) => {
+        if (valid) {
+          let { organIdList, linkUrl, content, ...rest } = this.form;
+          if (this.outUrlRadio == 1) {
+            content = null;
+          } else {
+            linkUrl = null;
+          }
+          let form = {
+            ...rest,
+            linkUrl,
+            content,
+            organIdList: organIdList ? organIdList.join(",") : null,
+          };
+          if (this.pageType == "create") {
+            if (form.id) {
+              // 判断有没有Id,如果有则删除
+              delete form.id;
+            }
+            // return false
+            await newsAdd(form).then((res) => {
+              this.messageTips("添加", res);
+            });
+          } else if (this.pageType == "update") {
+            await newsUpdate(form).then((res) => {
+              this.messageTips("修改", res);
+            });
+          }
+        } else {
+          this.$nextTick(() => {
+            let isError = document.getElementsByClassName("is-error");
+            isError[0].scrollIntoView({
+              block: "center",
+              behavior: "smooth",
+            });
+          });
+          return false;
+        }
+      });
+    },
+    messageTips(title, res) {
+      if (res.code == 200) {
+        this.$message.success(title + "成功");
+        this.$listeners.submited();
+        this.$listeners.close();
+      } else {
+        this.$message.error(res.msg);
+      }
+    },
+    handleSuccess(res) {
+      // 获取富文本组件实例
+      this.uploadImgLoading = false;
+      let quill = this.editor;
+      // 如果上传成功
+      let url = this.ossUploadUrl + "/" + this.dataObj.key;
+      if (url) {
+        // 获取光标所在位置
+        let length = quill.getSelection().index;
+
+        // 插入图片,res为服务器返回的图片链接地址
+        quill.insertEmbed(length, "image", url);
+        // 调整光标到最后
+        quill.setSelection(length + 1);
+      } else {
+        // 提示信息,需引入Message
+        this.$message.error("图片插入失败");
+      }
+    },
+    onReSet(formName) {
+      this.form = {
+        title: null,
+        order: null,
+        linkUrl: null,
+        type: this.type,
+        status: 1,
+        content: null,
+        organIdList: [],
+      };
+      this.$refs[formName].resetFields();
+    },
+    onLook() {
+      // 预览
+      let dataInfo = this.dataInfo;
+      dataInfo.title = this.form.title;
+      dataInfo.content = this.form.content;
+      // 处理图片显示问题
+      setTimeout(() => {
+        let imgNode = document.querySelectorAll(".msgWrap img");
+        if (imgNode.length > 0) {
+          imgNode.forEach((item) => {
+            item.style.width = "100%";
+          });
+        }
+
+        let videoNode = document.querySelectorAll(".msgWrap .ql-video");
+        if (videoNode.length > 0) {
+          videoNode.forEach((item) => {
+            item.style.width = "100%";
+            item.style.height = "195px";
+          });
+        }
+      }, 500);
+      this.lookVisible = true;
+    },
+    async getList() {
+      if (this.pageType == "create") {
+        return;
+      } else {
+        await newsQueryId({ id: this.options.id }).then((res) => {
+          if (res.code == 200) {
+            let result = res.data;
+            let organ = result.organIdList ? result.organIdList.split(",") : [];
+            // 是否使用外部链接
+            if (result.linkUrl) {
+              this.outUrlRadio = 1;
+            } else {
+              this.outUrlRadio = 0;
+            }
+            this.form = {
+              id: result.id,
+              title: result.title,
+              order: result.order,
+              linkUrl: result.linkUrl,
+              type: result.type,
+              status: result.status,
+              organIdList: organ.map((item) => {
+                return +item;
+              }),
+              content: result.content,
+              subType: result.subType,
+            };
+            this.dataInfo.updateTime = result.updateTime;
+          }
+        });
+      }
+    },
+    handleUploadImgError(file) {
+      this.uploadImgLoading = false;
+      this.$message.error("上传失败");
+    },
+    handleImgSuccess(res, file) {
+      this.uploadImgLoading = false;
+      let url = this.ossUploadUrl + "/" + this.dataObj.key;
+      if (url) {
+        this.dialogForm.poster = url;
+      } else {
+        this.$message.error("上传失败");
+      }
+    },
+    async beforeImgUpload(file) {
+      const imageType = {
+        "image/png": true,
+        "image/jpeg": true,
+      };
+      const isImage = imageType[file.type];
+      const isLt2M = file.size / 1024 / 1024 < 2;
+      isImage, isLt2M;
+      if (!isImage) {
+        this.$message.error("只能上传图片格式!");
+      }
+      if (!isLt2M) {
+        this.$message.error("上传图片大小不能超过 2MB!");
+      }
+      if (isImage && isLt2M) {
+        this.uploadImgLoading = true;
+      }
+
+      try {
+        let fileName = file.name.replaceAll(" ", "_");
+        let key = new Date().getTime() + fileName;
+        let obj = {
+          filename: fileName,
+          bucketName: this.bucket_name,
+          postData: {
+            filename: fileName,
+            acl: "public-read",
+            key: key,
+            unknowValueField: [],
+          },
+        };
+
+        const res = await policy(obj);
+        this.dataObj = {
+          policy: res.data.policy,
+          signature: res.data.signature,
+          key: key,
+          KSSAccessKeyId: res.data.kssAccessKeyId,
+          // dir: "",
+          acl: "public-read",
+          name: fileName,
+          // bucket_name: props.bucket_name
+        };
+      } catch (e) {
+        console.log(e);
+        return false;
+      }
+      return isImage && isLt2M;
+    },
+    typeCheck(type) {
+      let params = {
+        1: "精彩活动",
+        2: "热门资讯",
+        4: "专项训练",
+        7: "知识库",
+        19: "系统通知",
+      };
+      return params[type] ? params[type] : "管乐迷";
+    },
+    typeIndex(type) {
+      let tempTitle = {
+        1: 0,
+        2: 1,
+        3: 4,
+        4: 2,
+        5: 3,
+        6: 5,
+        7: 6,
+        8: 7,
+        19: 8,
+      };
+      return tempTitle[type];
+    },
+    onEditorChange({ quill, html, text }) {
+      this.form.content = html;
+    },
+    async beforeUpload(file) {
+      // const isJPG = file.type === 'image/jpeg';
+      const isLt2M = file.size / 1024 / 1024 < 100;
+
+      //   if (!isJPG) {
+      //     this.$message.error('上传头像图片只能是 JPG 格式!');
+      //   }
+      if (!isLt2M) {
+        this.$message.error("上传视频大小不能超过 100MB!");
+      }
+      this.uploadLoading = true;
+      try {
+        let fileName = file.name.replaceAll(" ", "_");
+        let key = new Date().getTime() + fileName;
+        let obj = {
+          filename: fileName,
+          bucketName: this.bucket_name,
+          postData: {
+            filename: fileName,
+            acl: "public-read",
+            key: key,
+            unknowValueField: [],
+          },
+        };
+
+        const res = await policy(obj);
+        this.dataObj = {
+          policy: res.data.policy,
+          signature: res.data.signature,
+          key: key,
+          KSSAccessKeyId: res.data.kssAccessKeyId,
+          // dir: "",
+          acl: "public-read",
+          name: fileName,
+          // bucket_name: props.bucket_name
+        };
+      } catch (e) {
+        console.log(e);
+        return false;
+      }
+      return isLt2M;
+    },
+    handleUploadError(file) {
+      this.uploadLoading = false;
+      this.$message.error("上传视频失败");
+    },
+    handleUploadSuccess(file, fileList) {
+      this.uploadLoading = false;
+      let url = this.ossUploadUrl + "/" + this.dataObj.key;
+      if (url) {
+        this.$message.success("上传视频成功");
+        this.dialogForm.videoUrl = url;
+      } else {
+        this.$message.error("上传视频失败");
+      }
+    },
+    handleExceed(files, fileList) {
+      this.$message.error("您已上传过视频");
+    },
+  },
+  computed: {
+    editor() {
+      return this.$refs.myQuillEditor.quill;
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.systemNotifyModel {
+  min-width: 100%;
+}
+.el-input {
+  width: 400px;
+}
+::v-deep .el-select {
+  width: 400px !important;
+  .el-input {
+    width: 400px;
+  }
+  .el-select-dropdown {
+    width: 400px;
+  }
+}
+::v-deep .ql-editor {
+  min-height: 300px;
+  padding: 0;
+}
+::v-deep .ql-container .ql-editor {
+  max-height: 500px;
+  padding: 15px;
+}
+.el-row {
+  margin-top: 40px;
+}
+.el-col {
+  display: flex;
+  align-items: center;
+  margin-bottom: 20px;
+  justify-content: flex-end;
+  margin-right: 50%;
+}
+.el-input-group {
+  width: 200px;
+  margin: 0 20px;
+}
+::v-deep .el-tree-node__content {
+  height: 40px !important;
+}
+::v-deep .avatar-uploader .el-upload,
+::v-deep .upload-demo .el-upload {
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+.avatar-uploader .el-upload:hover {
+  border-color: #409eff;
+}
+.avatar-uploader-icon {
+  border: 1px dashed #d9d9d9;
+  font-size: 28px;
+  color: #8c939d;
+  width: 120px;
+  height: 120px;
+  line-height: 120px;
+  text-align: center;
+}
+.avatar {
+  width: 120px;
+  height: 120px;
+  display: block;
+}
+.ivu-upload {
+  display: none;
+}
+
+.sd-container {
+  // padding: 15px;
+  h2 {
+    height: auto;
+    font-weight: 500;
+    color: rgba(68, 68, 68, 1);
+    line-height: 37px;
+    font-size: 26px;
+    margin-bottom: 10px;
+  }
+
+  .titleInfo {
+    height: 15px;
+    line-height: 15px;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    color: #444;
+    margin-bottom: 25px;
+  }
+  .imgWrap {
+    /* width: 100;
+    height: 1.45rem; */
+    margin-bottom: 0.15rem;
+    p {
+      font-size: 0.16rem;
+      font-family: PingFangSC;
+      font-weight: 400;
+      color: rgba(68, 68, 68, 1);
+      line-height: 0.28rem;
+      text-indent: 0.32rem;
+    }
+    img {
+      width: 100%;
+    }
+  }
+}
+.imageSize {
+  color: red;
+  line-height: 1.5;
+}
+</style>

+ 2 - 2
vue.config.js

@@ -15,13 +15,13 @@ const name = defaultSettings.title || "管乐迷后台管理系统"; // page tit
 // const port = process.env.port || process.env.npm_config_port || 9528 // dev port
 // http://47.99.212.176:8000
 //  https://online.dayaedu.com
-let target = "https://online.dayaedu.com"; //线上
+// let target = "https://online.dayaedu.com"; //线上
 // let target = 'http://192.168.3.251:8000' // 何国威
 // let target = 'http://192.168.3.20:8000' //邹璇
 // let target = 'http://192.168.3.161:8000' //勇哥
 // let target = 'http://192.168.3.146:8000' //王昭
 // let target = 'http://dev.dayaedu.com' // 开发环境
-// let target = "https://test.dayaedu.com"; //测试环境
+let target = "https://test.dayaedu.com"; //测试环境
 // All configuration item explanations can be find in https://cli.vuejs.org/config/
 module.exports = {
   /**