Karsa 6 meses atrás
pai
commit
ee6efc1803

+ 1 - 1
config/index.js

@@ -31,7 +31,7 @@ module.exports = {
 	//	原始配置
     env: require('./dev.env'),
     host: 'newadmin.brilliantstart.cn', // can be overwritten by process.env.HOST
-    port: '3030',
+    port: '3033',
     autoOpenBrowser: false,
     assetsSubDirectory: 'static',
     assetsPublicPath: '/',

+ 24 - 0
src/api/modules/knowledge.js

@@ -0,0 +1,24 @@
+import http from "@/api/http.js";
+
+export const eventInterface = {
+  /**
+   * 获取分类
+   * @param {*} params 
+   * @returns 
+   */
+  getClassify: params => {
+    return http.get("/report_approve/flow/list",params)
+  }
+}
+
+export const policyInterface = {
+
+}
+
+export const pointInterface = {
+
+}
+
+export const knowInterface = {
+
+}

BIN
src/assets/img/knowledge/tem_1.png


BIN
src/assets/img/knowledge/tem_2.png


BIN
src/assets/img/knowledge/tem_3.png


BIN
src/assets/img/knowledge/tem_4.png


+ 69 - 0
src/routes/modules/knowledgeRoutes.js

@@ -0,0 +1,69 @@
+/* 知识资源 */
+
+export default [{
+  path: '/',
+  component: () => import('@/views/Home.vue'),
+  name: '知识资源',
+  hidden: false,
+  meta:{
+    name_en:""
+  },
+  children: [{
+      path: "/knowledge_event",
+      name: "事件库",
+      component: () => import('@/views/knowledge_manage/list.vue'),
+      meta:{
+        name_en:""
+      },
+    },
+    {
+      path: "/knowledge_policy",
+      name: "政策库",
+      component: () => import('@/views/knowledge_manage/list.vue'),
+      meta:{
+        name_en:""
+      },
+    },
+    {
+      path: "/knowledge_viewpoint",
+      name: "观点库",
+      component: () => import('@/views/knowledge_manage/list.vue'),
+      meta:{
+        name_en:""
+      },
+    },
+    {
+      path: "/knowledge_know",
+      name: "知识库",
+      component: () => import('@/views/knowledge_manage/list.vue'),
+      meta:{
+        name_en:""
+      },
+    },
+    {
+      path: "/knowledgeEdit",
+      name: "编辑事件",
+      component: () => import('@/views/knowledge_manage/edit.vue'),
+      meta:{
+        name_en:""
+      },
+    },
+    {
+      path: "/knowledgeDetail",
+      name: "详情",
+      component: () => import('@/views/knowledge_manage/edit.vue'),
+      meta:{
+        name_en:""
+      },
+    },
+    {
+      path: "/knowledge_tag",
+      name: "标签管理",
+      component: () => import('@/views/knowledge_manage/tagSetting.vue'),
+      meta:{
+        name_en:""
+      },
+    },
+
+  ]
+}]

+ 34 - 0
src/utils/buttonConfig.js

@@ -865,6 +865,40 @@ export const chartThemePermission = {
     chartTheme_chartsource:'chartTheme:chartsource',//图表的数据来源
 }
 
+export const knowledgePermission = {
+    //事件库
+    event_add: 'event:add',//添加
+    event_import: 'event:import',//excel导入
+    event_classifyEdit: 'event:classifyEdit',//分类管理
+    event_tagEdit: 'event:tagEdit',//标签管理
+    event_edit: 'event:edit',
+    event_del: 'event:del',
+
+    //政策库
+    policy_add: 'policy:add',
+    policy_import: 'policy:import',
+    policy_classifyEdit: 'policy:classifyEdit',
+    policy_tagEdit: 'policy:tagEdit',
+    policy_edit: 'policy:edit',
+    policy_del: 'policy:del',
+
+    //观点库
+    viewpoint_add: 'viewpoint:add',
+    viewpoint_import: 'viewpoint:import',
+    viewpoint_classifyEdit: 'viewpoint:classifyEdit',
+    viewpoint_tagEdit: 'viewpoint:tagEdit',
+    viewpoint_edit: 'viewpoint:edit',
+    viewpoint_del: 'viewpoint:del',
+
+    //知识库
+    know_add: 'know:add',
+    know_import: 'know:import',
+    know_classifyEdit: 'know:classifyEdit',
+    know_tagEdit: 'know:tagEdit',
+    know_edit: 'know:edit',
+    know_del: 'know:del',
+}
+
 
 //创建了新的ManageBtn记得添加到这里
 const btnMap  = {

+ 308 - 0
src/views/knowledge_manage/components/classifyDia.vue

@@ -0,0 +1,308 @@
+<template>
+<div>
+    <el-dialog
+      :visible.sync="show"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      @close="cancelHandle"
+      custom-class="knowledge-classify"
+      top="10vh"
+      v-dialogDrag
+      title="分类设置"
+      width="650px"
+    >
+      <div class="main">
+        <el-tree
+          ref="treeRef"
+          class="classify-tree"
+          :data="classifyOptions"
+          node-key="Id"
+          :props="{
+            value: 'Id',
+            label: 'ClassifyName',
+            children: 'Children',
+          }"
+          :expand-on-click-node="false"
+          check-strictly
+          empty-text="暂无分类"
+          :allow-drag="canDragHandle"
+          :allow-drop="canDropHandle"
+          @node-drop="dropOverHandle"
+          @node-drag-leave="dropMouseLeave"
+          @node-drag-enter="dropMouseOver"
+        >
+          <div class="custom-tree-node" slot-scope="{ node, data }">
+            <span
+              class="text_oneLine node_label"
+            >
+              {{ data.ClassifyName  }}
+            </span>
+
+            <div>
+                <img
+									src="~@/assets/img/data_m/move_ico.png"
+									class="handle-icon"
+								/>
+								<!-- 添加子项 -->
+								<img
+									src="~@/assets/img/set_m/add.png"
+									class="handle-icon"
+									@click.stop="hadnleAddNode(node, data)"
+									v-if="node.level<3"
+								/>
+								<!-- 编辑目录 -->
+								<img
+									src="~@/assets/img/set_m/edit.png"
+                  class="handle-icon"
+									style="width: 15px; height: 14px; margin-right: 8px"
+									@click.stop="handleEditNode(node, data)"
+								/>
+								<!-- 删除目录 -->
+								<img
+									slot="reference"
+									src="~@/assets/img/set_m/del.png"
+									class="handle-icon"
+									style="width: 14px; height: 14px"
+									@click.stop="handleRemoveNode(node, data)"
+								/>
+            </div>
+          </div>
+        </el-tree>
+
+
+        <div class="clasify-add-cont" @click="handleAddNode(null)">
+          <img
+            src="~@/assets/img/set_m/add_ico.png"
+            alt=""
+          />
+          <span>添加一级目录</span>
+        </div>
+      </div>
+
+    </el-dialog>
+    
+    <!-- 分类编辑弹窗 -->
+    <el-dialog
+      :visible.sync="isClassifyEditDia"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      @close="isClassifyEditDia=false"
+      top="10vh"
+      v-dialogDrag
+      title="分类编辑"
+      width="650px"
+    >
+      <el-form
+          ref="classifyFormRef"
+          label-position="right"
+          label-width="120px"
+          hide-required-asterisk
+          :model="classifyForm"
+          :rules="formRules"
+      >
+          <el-form-item label="分类名称" prop="classifyName">
+              <el-input
+                v-model="classifyForm.classifyName"
+                style="width: 80%"
+                placeholder="请输入指标名称"
+              />
+          </el-form-item>
+          <el-form-item label="上级分类" prop="parentClassifyId">
+              <el-cascader
+                  :options="classifyOptions"
+                  v-model="classifyForm.parentClassifyId"
+                  :props="{
+                    value: 'Id',
+                    label: 'ClassifyName',
+                    children: 'Child'
+                  }"
+                  clearable
+                  placeholder="请选择上级分类"
+                  style="width:80%;"
+              ></el-cascader>
+          </el-form-item>
+      </el-form>
+
+      <div class="btn-bottom">
+				<el-button type="primary" plain @click="isClassifyEditDia=false">取消</el-button>
+        <el-button type="primary" @click="handleSaveClassify">确定</el-button>
+      </div>
+      
+    </el-dialog>
+</div>
+
+</template>
+<script>
+import { eventInterface,policyInterface,pointInterface,knowInterface } from '@/api/modules/knowledge';
+export default {
+  props: {
+    show: {
+      type: Boolean
+    }
+  },
+  watch: {
+    show(nval) {
+      nval && this.getClassify()
+    }
+  },
+  data() {
+    return {
+      classifyOptions: [],
+
+      //编辑分类弹窗
+      isClassifyEditDia:false,
+      classifyForm: {
+        classifyName: '',
+        classifyId: 0,
+        parentClassifyId: 0,
+      }
+    }
+  },
+  mounted(){
+
+  },
+  methods:{
+    async getClassify() {
+      
+    },
+
+    //添加
+    handleAddNode(data) {
+      if(data) {
+
+      }else { //一级目录
+        this.classifyForm = {
+          classifyName: '',
+          classifyId: 0,
+          parentClassifyId: 0,
+        }
+      }
+      this.isClassifyEditDia = true
+    },
+
+    //编辑
+    handleEditNode(data) {
+      this.classifyForm = {
+        classifyName: '',
+        classifyId: 0,
+        parentClassifyId: 0,
+      }
+      this.isClassifyEditDia = true
+    },
+
+    //删除
+    handleRemoveNode(data) {
+      this.$confirm(
+        '确定删除该分类吗?', 
+        '提示',
+        {
+        type: 'warning'
+      }).then(async() => {
+
+      })
+    },
+
+    //保存分类信息
+    async handleSaveClassify() {
+      // const res = a
+    },
+
+    cancelHandle() {
+      this.$emit('update:show',false)
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+  .main {
+    .classify-tree {
+      height: 50vh;
+      min-height: 300px;
+      overflow-y: auto;
+      .custom-tree-node {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+      }
+      .handle-icon {
+        width: 14px; height: 14px;
+      }
+    }
+    .clasify-add-cont {
+      margin: 30px 0;
+      display: flex;
+      justify-content: center;
+      color: #409eff;
+      cursor: pointer;
+      >img {
+        width: 16px;
+        height: 16px;
+        margin-right: 10px;
+      }
+    }
+
+  }
+  .btn-bottom {
+    display: flex;
+    justify-content: center;
+    gap: 20px;
+    margin: 40px 0;
+    >.el-button {
+      width: 120px;
+    }
+  }
+</style>
+<style lang="scss">
+.knowledge-classify{
+  .classify-tree {
+    .el-tree__drop-indicator {
+      height: 3px;
+      background-color: #409eff;
+    }
+
+    .el-tree-node__content {
+      margin-bottom: 14px !important;
+    }
+
+    .el-tree-node__children {
+      .el-tree-node {
+        margin-bottom: 0px !important;
+        padding-left: 18px;
+      }
+
+      .el-tree-node__content {
+        margin-bottom: 5px !important;
+        padding-left: 0 !important;
+      }
+    }
+
+    .expanded.el-icon-caret-right:before {
+      content: url('~@/assets/img/set_m/down.png') !important;
+    }
+
+    .el-icon-caret-right:before {
+      content: url('~@/assets/img/set_m/slide.png') !important;
+    }
+    .el-tree-node__expand-icon{
+      padding-top: 10px;
+    }
+
+    .el-tree-node__expand-icon.is-leaf.el-icon-caret-right:before {
+      content: '' !important;
+    }
+
+    .el-tree-node__expand-icon.expanded {
+      -webkit-transform: rotate(0deg);
+      transform: rotate(0deg);
+    }
+
+    .el-tree-node.is-current>.el-tree-node__content {
+      background-color: #f0f4ff !important;
+    }
+
+    .el-tree-node__content {
+      padding-right: 10px !important;
+    }
+  }
+}  
+</style>

+ 247 - 0
src/views/knowledge_manage/components/importExcelDia.vue

@@ -0,0 +1,247 @@
+<template>
+  <el-dialog
+    :title="$t('ManualEntryPage.tit_insert_data')"
+    :visible.sync="show"
+    :close-on-click-modal="false"
+    :modal-append-to-body="false"
+    center
+    v-dialogDrag
+    @close="cancelHandle"
+    custom-class="dialog-cont"
+    width="40%"
+  >
+    <div slot="title" style="display: flex; alignitems: center">
+      <img
+        :src="$icons.imp"
+        style="color: #fff; width: 16px; height: 16px; margin-right: 5px"
+      />
+      <span style="font-size: 16px">{{$t('ManualEntryPage.tit_insert_data')}}</span>
+    </div>
+    <div class="down-min">
+      <dataLoading :loading="isLoading"/>
+
+      <div class="section-item">
+        <div class="templete-wrap">
+          <div class="item" v-for="tem in templateList" :key="tem.name">
+            <a :href="tem.url" download="模板">
+              <el-button type="primary" icon="el-icon-download">下载导入模板</el-button>
+            </a>
+            <div>
+              <img :src="temImg" alt="" width="150" style="display:block;margin:10px 0;">
+              <span class="editsty" @click="handlePreviewImg"><!-- 查看大图 -->{{$t('ManualEntryPage.view_big_img')}}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="section-item">
+        <h3>上传导入模板</h3>
+        <el-upload
+          class="upload-demo"
+          :before-upload="beforeUploadFile"
+          multiple
+          :limit="3"
+          :headers="headerConfig"
+          :on-success="handleSuccess"
+          :on-progress="handleStarting"
+          :action="action"
+          accept=".xlsx"
+          :name="name"
+          :show-file-list="false"
+        >
+          <el-button type="primary" icon="el-icon-upload">{{$t('ManualEntryPage.tit_insert_data')}}</el-button>
+        </el-upload>
+      </div>
+    </div>
+    <div class="down-tip-txt">
+      <span>{{$t('ManualEntryPage.step_one')}}</span>
+      <span>{{$t('ManualEntryPage.step_two')}}</span>
+      <span>{{$t('ManualEntryPage.step_three')}}
+        <a
+          style="display: inline; color: #0052D9"
+          :href="downloadErrorlist"
+          download
+          >{{$t('ManualEntryPage.down_fail_list')}}</a
+        >。</span
+      >
+    </div>
+
+    <el-image-viewer 
+        v-if="showImgViewer" 
+        :on-close="()=>{this.previewList=[];this.showImgViewer = false}" 
+        :url-list="previewList" 
+    />
+  </el-dialog>
+</template>
+
+<script>
+import { dataInterence } from "api/api.js";
+import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
+export default {
+  name: "",
+  components: { ElImageViewer },
+  props: {
+    show: {
+      type: Boolean,
+    },
+  },
+  computed: {
+    temImg() {
+      const imgSourceMap = {
+        '/knowledge_event': require('@/assets/img/knowledge/tem_1.png'),
+        '/knowledge_policy': require('@/assets/img/knowledge/tem_2.png'),
+        '/knowledge_viewpoint': require('@/assets/img/knowledge/tem_3.png'),
+        '/knowledge_know': require('@/assets/img/knowledge/tem_4.png'),
+      }
+
+      return imgSourceMap[this.$route.path] && imgSourceMap[this.$route.path]
+    }
+  },
+  data() {
+    return {
+      action: process.env.VUE_APP_API_ROOT + "/entry/import/data", //上传文件
+      downloadErrorlist:
+        process.env.VUE_APP_API_ROOT +
+        "/entry/import/failList" +
+        `?${localStorage.getItem("auth")}`, //失败列表下载
+      name: "EntryFile",
+
+      templateList: [
+        {
+          name:/* "模板1"  */this.$t('ManualEntryPage.tem_msg',{index:1}),
+          url: process.env.VUE_APP_API_ROOT + "/entry/template?Source=1"
+        }
+      ],
+      headerConfig: {
+        Authorization: localStorage.getItem("auth"),
+      },
+      isLoading: false,
+
+      showImgViewer: false,
+      previewList: []
+    };
+  },
+  methods: {
+    cancelHandle() {
+      this.$emit('update:show',false)
+    },
+    // 校验文件和大小
+    beforeUploadFile(file) {
+      let extension = file.name.substring(file.name.lastIndexOf(".") + 1);
+      let size = file.size / 1024 / 1024; //M
+      if (extension !== "xlsx" && extension !== "xls") {
+        this.$message.warning("只能上传后缀是.xlsx和.xls的文件");
+        return false;
+      }
+      if (size > 10) {
+        this.$message.warning(/* "文件大小不得超过10M" */this.$t('ManualEntryPage.upload_size_msg'));
+        return false;
+      }
+    },
+    handleStarting() {
+      this.isLoading = true;
+    },
+    // 上传成功之后
+    handleSuccess(result) {
+      //兼容下结构
+      let res = this.$parseData({
+        headers: {
+          dk: sessionStorage.getItem('dk')||""
+        },
+        data: result
+      });
+      if (res.Ret === 200) {
+        // 0成功 1部分失败 -1全部失败
+        let str = `
+						<h2 style="margin-bottom:30px">导入成功</h2>
+						<p> 本次共成功导入${res.Data.SuccessCount}条数据</p>
+					`;
+        if (res.Data.Status === 1) {
+          // this.$message.warning('部分导入失败')
+          str = `
+							<h2 style="margin-bottom:30px">部分导入失败</h2>
+							<p>${this.$t('ManualEntryPage.upload_tip_msg2',{success_count:res.Data.SuccessCount,fail_count:res.Data.FailCount})}</p>
+							<a style="display:inline;color:#5882EF;" href="${this.downloadErrorlist}" download>${this.$t('ManualEntryPage.down_fail_list2')}</a>
+						`;
+        } else if (res.Data.Status === -1) {
+          // this.$message.success("导入成功!");
+          str = `
+							<h2 style="margin-bottom:30px">导入失败!</h2>
+							<a style="display:inline;color:#5882EF;" href="${this.downloadErrorlist}" download>${this.$t('ManualEntryPage.down_fail_list2')}</a>
+						`;
+        }
+        this.$alert(str, "", {
+          dangerouslyUseHTMLString: true,
+          center: true,
+          showConfirmButton: false,
+        });
+        this.$emit("importSuccess");
+      } else {
+        this.$message.warning(res.Msg);
+      }
+      this.isLoading = false;
+    },
+
+    handlePreviewImg() {
+      this.previewList=[this.temImg]
+      this.showImgViewer=true 
+    }
+  },
+};
+</script>
+<style lang="scss" scoped>
+.dialog-cont {
+  max-width: 800px;
+  .down-min {
+    position: relative;
+    margin: 20px 0 50px;
+    .arrow-ico {
+      width: 140px;
+      height: 14px;
+      display: block;
+      background: url("~@/assets/img/data_m/arrow_ico.png") no-repeat center;
+      background-size: 100%;
+      margin: 0 50px;
+    }
+    .icon {
+      width: 100px;
+      height: 100px;
+      display: block;
+      margin-bottom: 36px;
+      &.down_ico {
+        background: url("~@/assets/img/data_m/down_ico.png") no-repeat center;
+        background-size: cover;
+      }
+      &.up_ico {
+        background: url("~@/assets/img/data_m/up_ico.png") no-repeat center;
+        background-size: cover;
+      }
+    }
+  }
+  .down-tip-txt {
+    font-size: 14px;
+    color: #1f2e4d;
+    line-height: 25px;
+    padding-bottom: 10px;
+    span {
+      display: block;
+      margin-bottom: 18px;
+    }
+  }
+
+  .section-item {
+    padding: 20px 0;
+    &:first-child {
+      border-bottom: 1px solid #C8CDD9;
+    }
+    h3 {
+      font-size: 16px;
+      margin-bottom: 20px;
+    }
+    .templete-wrap {
+      display: flex;
+      gap: 20px;
+    }
+  }
+}
+</style>

+ 171 - 0
src/views/knowledge_manage/edit.vue

@@ -0,0 +1,171 @@
+<template>
+  <div class="knowledge-edit-box">
+    <header>
+      <el-form
+        ref="formRef"
+        label-position="left"
+        hide-required-asterisk
+        inline
+        label-width="0"
+        :model="eventForm"
+        :rules="formRules"
+        :disabled="!isEdit"
+      >
+        <el-form-item prop="title">
+          <el-input 
+            v-model="eventForm.title" 
+            placeholder="请输入标题"
+            />
+        </el-form-item>
+        <el-form-item prop="classifyId">
+          <el-cascader
+              :options="classifyOptions"
+              v-model="eventForm.classifyId"
+              :props="{
+                value: 'Id',
+                label: 'ClassifyName',
+                children: 'Child'
+              }"
+              clearable
+              placeholder="请选择分类"
+              style="width:100%;"
+          ></el-cascader>
+        </el-form-item>
+
+        <el-form-item prop="source">
+          <el-select
+              v-model="eventForm.source"
+              placeholder="请选择来源"
+              size="medium"
+              clearable
+              style="width:100%;"
+          >
+              <el-option 
+                v-for="item in sourcesOptions" 
+                :key="item"
+                :label="item" 
+                :value="item" 
+              />
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="tag">
+          <el-select
+              v-model="eventForm.tags"
+              placeholder="请选择标签"
+              size="medium"
+              clearable
+              style="width:100%;"
+              multiple
+              @change="filterChange"
+          >
+              <el-option 
+                v-for="item in tagsOptions" 
+                :key="item"
+                :label="item" 
+                :value="item" 
+              />
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="startTime">
+          <label>开始时间</label>
+          <el-date-picker
+            v-model="eventForm.startTime"
+            type="datetime"
+            placeholder="请选择开始时间"
+          />
+        </el-form-item>
+        <el-form-item prop="startTime">
+          <label>结束时间</label>
+          <el-date-picker
+            v-model="eventForm.endTime"
+            type="datetime"
+            placeholder="请选择结束时间"
+          />
+        </el-form-item>
+        
+        <el-form-item v-if="!isEdit">
+          <el-button type="primary" @click="handleSaveTarget">编辑</el-button>
+        </el-form-item>
+      </el-form>
+    </header>
+    <div class="main">
+      <template v-if="isEdit">
+        <editor 
+          ref="editorRef"
+        />
+
+        <div class="btn-bottom">
+          <el-button type="primary" plain @click="$router.replace({path: ''})">取消</el-button>
+          <el-button type="primary" @click="">确定</el-button>
+        </div>
+      </template>
+    </div>
+  </div>
+</template>
+<script>
+import editor from '@/views/semantics_manage/summery/components/editor.vue';
+export default {
+  components: { editor },
+  computed: {
+    isEdit() {
+      return this.$route.path==='/knowledgeEdit'
+    }
+  },
+  data() {
+    return {
+      eventForm: {
+        title: '',
+        classifyId: 0,
+        source:'',
+        tags:[],
+        startTime:'',
+        endTime:''
+      },
+      formRules:[],
+
+      sourcesOptions:[],
+      tagsOptions:[],
+    }
+  },
+  mounted(){
+
+  },
+  methods:{
+
+  },
+}
+</script>
+<style scoped lang='scss'>
+  .knowledge-edit-box {
+    height: calc(100vh - 120px);
+    display: flex;
+    flex-direction: column;
+    header,.main{
+      padding: 20px;
+      background: #fff;
+      border: 1px solid #C8CDD9;
+      border-radius: 4px;
+    }
+    .main {
+      flex: 1;
+      margin-top: 20px;
+      overflow-y: auto;
+      .btn-bottom {
+        display: flex;
+        gap: 20px;
+        justify-content: flex-end;
+        margin-top: 20px;
+        .el-button {
+          width: 130px;
+        }
+      }
+    }
+  }
+</style>
+<style lang="scss">
+  .knowledge-edit-box {
+    .fr-element {
+      height: calc(100vh - 500px);
+    }
+  }
+</style>

+ 354 - 0
src/views/knowledge_manage/list.vue

@@ -0,0 +1,354 @@
+<template>
+  <div class="knowledge-box">
+      <header>
+        <div class="left-filter">
+          <el-button type="primary" @click="$router.push({path:'/knowledgeEdit'})">添加事件</el-button>
+          <el-dropdown 
+            split-button
+            type="primary" 
+            @click="isImportExcelDia=true"
+          >
+            Excel导入
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item command="file">文件导入</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+          <el-button type="primary" plain @click="isOpenClassifyDia=true">分类管理</el-button>
+          <el-button type="primary" plain @click="handleGoTagSet">标签管理</el-button>
+        </div>
+
+        <div class="right-filter">
+          <el-popover 
+            placement="bottom" 
+            trigger="click" 
+            :visible-arrow="false"
+            popper-class="report-select-popover"
+            width="350" 
+            style="display: inline-block;"
+          >
+              <div class="select-wrap">
+                  <div class="select-top">
+                    <h4>筛选条件</h4>
+                    <span><i class="el-icon-delete"/>清空所选条件</span>
+                  </div>
+                  <div class="select-item">
+                    <el-cascader
+                        :options="classifyOptions"
+                        v-model="filterForm.classifys"
+                        :props="{
+                          value: 'Id',
+                          label: 'ClassifyName',
+                          children: 'Child'
+                        }"
+                        clearable
+                        placeholder="请选择分类"
+                        style="width:100%;"
+                        @change="filterChange"
+                    ></el-cascader>
+                  </div>
+                  <div class="select-item">
+                      <el-select
+                          v-model="filterForm.source"
+                          placeholder="请选择来源"
+                          size="medium"
+                          clearable
+                          style="width:100%;"
+                          @change="filterChange"
+                      >
+                          <el-option 
+                            v-for="item in sourcesOptions" 
+                            :key="item"
+                            :label="item" 
+                            :value="item" 
+                          />
+                      </el-select>
+                  </div>
+  
+                  <div class="select-item">
+                      <el-select
+                          v-model="filterForm.tags"
+                          placeholder="请选择标签"
+                          size="medium"
+                          clearable
+                          style="width:100%;"
+                          multiple
+                          @change="filterChange"
+                      >
+                          <el-option 
+                            v-for="item in tagsOptions" 
+                            :key="item"
+                            :label="item" 
+                            :value="item" 
+                          />
+                      </el-select>
+                  </div>
+                  <div class="select-item">
+                      <el-cascader
+                          @change="filterChange"
+                          :options="usersOptions"
+                          v-model="filterForm.users"
+                          clearable
+                          placeholder="请选择添加人"
+                          style="width:100%;"
+                      ></el-cascader>
+                  </div>
+              </div>
+              <div class="select-btn" slot="reference">
+                  <img src="~@/assets/icons/filter.svg">
+                  <span>筛选条件</span>
+                  <span class="select-num">+{{selectNum}}</span>
+              </div>
+          </el-popover>
+
+          <el-input
+            @input="filterChange"
+            placeholder="名称"
+            v-model="filterForm.keyWord"
+            clearable
+            style="width:300px"
+            prefix-icon="el-icon-search"
+          />
+        </div>
+      </header>
+
+      <div class="main">
+        <el-table
+          :data="tableData"
+          style="box-shadow: 0px 3px 6px rgba(155, 170, 219, 0.2);margin-top: 20px"
+          border
+          ref="table"
+        >
+          <el-table-column
+            v-for="item in tableColums"
+            :key="item.key"
+            :label="item.label"
+            :width="item.widthsty"
+            :min-width="item.minwidthsty"
+            align="center"
+          >
+            <template slot-scope="{row}">
+              <span v-if="item.key==='Title'" class="editsty" @click="lookDetailHandle(row,'look')">{{row[item.key]}}</span>
+              <span v-else>{{row[item.key]}}</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            :label="$t('Table.column_operations')"
+            align="center"
+            v-if="!isRise"
+          >
+            <template slot-scope="{row}">
+              <div>
+                <span class="editsty" @click="lookDetailHandle(row,'edit')" v-if="checkBtnAuth('edit')">{{$t('Table.edit_btn')}}</span>
+
+                <span class="deletesty" @click="handleDelItem(row)" v-if="checkBtnAuth('del')">{{$t('Table.delete_btn')}}</span>
+              </div>
+            </template>
+          </el-table-column>
+          <div class="nodata" slot="empty">
+            <tableNoData :text="$t('Table.prompt_slogan')" size="mini"/>
+          </div>
+        </el-table>
+
+        <div style="height:35px;margin: 20px 0;">
+          <m-page
+            :page_no="pageNo"
+            :pageSize="pageSize"
+            :total="total"
+            @handleCurrentChange="pageChange"
+          />
+        </div>
+      </div>
+
+      <!-- 分类管理弹窗 -->
+      <classifyDia
+        :show.sync="isOpenClassifyDia"
+      />
+
+      <!-- 导入excel弹窗 -->
+      <importExcelDia
+        :show.sync="isImportExcelDia"
+      />
+  </div>
+</template>
+<script>
+import { eventInterface,policyInterface,pointInterface,knowInterface } from '@/api/modules/knowledge';
+import classifyDia from './components/classifyDia.vue'
+import importExcelDia from './components/importExcelDia.vue';
+import mPage from '@/components/mPage.vue'
+export default {
+  components: { mPage,classifyDia,importExcelDia },
+  computed: {
+    api() {
+      const apiMap = {
+        '/knowledge_event': eventInterface,
+        '/knowledge_policy': policyInterface,
+        '/knowledge_viewpoint': pointInterface,
+        '/knowledge_know': knowInterface,
+      }
+
+      return apiMap[this.$route.path] && apiMap[this.$route.path]
+    },
+    tableColums() {
+      return [
+        { label: '开始时间',key: 'Createtime' },
+        { label: '标题',key: 'Title',minwidthsty:'150px' },
+        { label: '来源',key: 'Source' },
+        { label: '分类',key: 'ClassifyName' },
+        { label: '标签',key: 'Tag' },
+        { label: '添加人',key: 'Creator' },
+      ]
+    }
+  },
+  data() {
+    return {
+      filterForm: {
+        pageNo: 1,
+        pageSize:15,
+        classsifys: [],
+        source: '',
+        tags: [],
+        users: [],
+        keyWord:"",
+      },
+      classifyOptions:[],
+      sourcesOptions:[],
+      tagsOptions:[],
+      usersOptions:[],
+      total: 0,
+      tableData: [
+        {Title: 'dwdw',Source:'wind',ClassifyName:'分类1、分类2',Createtime:'2024/9/25',Tag:'多空',Creator:'DW'},
+        {Title: 'dwdw',Source:'wind',ClassifyName:'分类1、分类2',Createtime:'2024/9/25',Tag:'多空',Creator:'DW'},
+        {Title: 'dwdw',Source:'wind',ClassifyName:'分类1、分类2',Createtime:'2024/9/25',Tag:'多空',Creator:'DW'},
+        {Title: 'dwdw',Source:'wind',ClassifyName:'分类1、分类2',Createtime:'2024/9/25',Tag:'多空',Creator:'DW'},
+      ],
+
+      //分类弹窗
+      isOpenClassifyDia: false,
+      
+      //excel导入弹窗
+      isImportExcelDia: false,
+    }
+  },
+  mounted(){
+
+  },
+  methods:{
+    async getTableData() {
+
+    },
+
+    filterChange() {
+      this.filterForm.pageNo = 1;
+      this.getTableData()
+    },
+
+    pageChange(page) {
+      this.filterForm.pageNo = page;
+      this.getTableData()
+    },
+
+    lookDetailHandle(item,type) {
+      const { href } = this.$router.resolve({
+        path: type==='look'?'/knowledgeDetail':'/knowledgeEdit',
+        query: {
+          id: item.id
+        }
+      }) 
+
+      window.open(href,'_blank')
+    },
+
+    handleDelItem(item) {
+      this.$confirm(
+        '确定删除该事件吗?', 
+        '提示',
+        {
+        type: 'warning'
+      }).then(async() => {
+
+      })
+    },
+
+    handleGoTagSet() {
+      this.$router.push({
+        path: '/knowledge_tag',
+      })
+    },
+
+    checkBtnAuth(key) {
+       const authMap = {
+        '/knowledge_event': 'event',
+        '/knowledge_policy': 'policy',
+        '/knowledge_viewpoint': 'viewpoint',
+        '/knowledge_know': 'know',
+      }
+
+      return true
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+*{ box-sizing: border-box; }
+.knowledge-box {
+  padding: 20px;
+  background: #fff;
+  border: 1px solid #C8CDD9;
+  border-radius: 4px;
+  min-height: calc(100vh - 120px);
+
+  header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    >div {
+      display: flex;
+      gap: 10px;
+    }
+    .select-btn{
+        cursor: pointer;
+        width:130px;
+        height: 36px;
+        text-align: center;
+        background-color: #ECF2FE;
+        border-radius: 4px;
+        box-sizing: border-box;
+        line-height:36px;
+        img,span{
+          display: inline-block;
+          vertical-align: middle;
+        }
+        .select-num{
+          width:20px;
+          height:20px;
+          line-height: 20px;
+          border-radius: 50%;
+          background-color:#0052D9;
+          color:white;
+          font-size: 12px;
+      }
+    }
+  }
+}
+
+.select-wrap{
+  padding:8px;
+  margin:0 20px;
+  .select-top {
+    display: flex;
+    justify-content: space-between;
+    >span { color: #999;}
+  }
+  .select-item{
+      margin-top:20px;
+  }
+}
+</style>
+<style lang="scss">
+.knowledge-box {
+  .el-table td{
+    padding: 6px 0;
+  }
+}
+</style>

+ 271 - 0
src/views/knowledge_manage/tagSetting.vue

@@ -0,0 +1,271 @@
+<template>
+    <div class="knowledge-tag-page">
+        <div class="top-wrap">
+            <el-button 
+                type="primary"
+                @click="handleAddTag"
+            >添加标签</el-button>
+        </div>
+        <div class="content-box">
+            <el-tree
+			    :data="list"
+				node-key="ReportChapterTypeId"
+                :props="{
+                    label: 'ReportChapterTypeName',
+                    children: 'Child'
+                }"
+				check-strictly
+				empty-text="暂无标签"
+                draggable
+                :allow-drop="canDropHandle"
+                @node-drop="dropOverHandle"
+			>
+				<div
+					class="classify-item-wrap"
+					slot-scope="{ data }"
+				>
+                    <div>
+                        <span>{{data.ReportChapterTypeName}}</span>
+                    </div>
+					
+                    <div class="opt-box">
+                        <img class="icon-drag" src="~@/assets/img/data_m/move_ico2.png" alt="">
+                        <img class="icon-set" src="~@/assets/img/icons/variety_set.png" alt="" @click.stop="handleEditTag(data)">
+                        <img class="icon-del" src="~@/assets/img/set_m/del_icon.png"  @click="handleDelTag(data)"/>
+                    </div>
+				</div>
+			</el-tree>
+        </div>
+
+        <!-- 添加/编辑 -->
+    <el-dialog 
+        v-if="addDialogShow"
+        :title="tagForm.id?'编辑标签':'添加标签'" 
+        :modal-append-to-body='false' 
+        :visible.sync="addDialogShow" 
+        :close-on-click-modal="false" 
+        :center="true" 
+        v-dialogDrag 
+        width="620px" 
+        @close="addDialogShow=false"
+    >
+        <div style="display: flex;align-items: center;justify-content: center;">
+            <el-form :model="tagForm" label-width="auto" :rules="tagFormRules" ref="tagFormRef">
+                <!-- 名称 -->
+                <el-form-item label="标签名称" prop="ReportChapterTypeName">
+                    <el-input 
+                        v-model="tagForm.ReportChapterTypeName" 
+                        style="width: 317px;" 
+                        placeholder="请输入标签名称">
+                    </el-input>
+                </el-form-item>
+            </el-form>
+        </div>
+        <div solt="footer" style="padding: 20px 0;text-align: center;">
+            <el-button size="medium" style="width:130px;" @click="addDialogShow=false">{{ $t('Dialog.cancel_btn') }}</el-button>
+            <el-button type="primary" size="medium" style="margin-left: 16px;width:130px ;" @click="addChapterSave">{{ $t('Dialog.confirm_save_btn') }}</el-button>
+      </div>
+    </el-dialog>
+        
+    </div>
+</template>
+
+<script>
+import mDialog from '@/components/mDialog.vue';
+import { getchapterTypeList,addChapterType,editChapterType,} from 'api/api.js';
+import {setChapterEnable,setChapterSort} from '@/api/modules/oldApi.js'
+export default {
+    name:"tagSetting",
+    components:{ mDialog },
+    data() {
+        return {
+            list:[],
+            // 添加/编辑弹窗
+            addDialogShow:false,
+            tagForm:{
+                ReportChapterTypeName:"",
+                id:0
+            },
+            parentClassifyName: '',
+
+            reportVarietyList:[],//中文品种列表
+        }
+    },
+    mounted(){
+        this.parentClassifyName = this.$route.query.classifyName || ''
+        this.getList()
+    },
+    methods: {
+        getList(type){
+            getchapterTypeList({ClassifyId:198}).then(res=>{
+                if(res.Ret == 200){
+                    this.list=res.Data.List || []
+                }
+            })
+        },
+
+        handleAddTag(){
+            this.addDialogShow=true
+            this.tagForm = {
+                ReportChapterTypeName:"",
+                id:0
+            }
+        },
+
+        handleEditTag(row){
+
+            this.tagForm={
+                ReportChapterTypeName:row.ReportChapterTypeName,
+                ReportChapterTypeId:row.ReportChapterTypeId,
+                ChartPermissionIdList:row.ChartPermissionIdList||''
+            }
+            this.addDialogShow=true
+        },
+
+
+        handleDelTag() {
+            this.$confirm(
+                '确定删除该标签吗?', 
+                '提示',
+                {
+                type: 'warning'
+            }).then(async() => {
+
+            })
+        },
+
+        // 保存
+        async addChapterSave(){
+            await this.$refs.tagFormRef.validate()
+                // 添加小程序是否显示参数 0显示,1隐藏
+                let params={
+                    ...this.tagForm,
+                    ClassifyId: Number(this.$route.query.id),
+                    ChartPermissionIdList:this.tagForm.ChartPermissionIdList||[]
+                }
+                // 请求方法
+                let requestMethod;
+                // console.log(params);
+                if(params.ReportChapterTypeId){
+                // 编辑
+                requestMethod=editChapterType
+                }else{
+                // 新增
+                requestMethod=addChapterType
+                }
+                requestMethod(params).then(res=>{
+                    if(res.Ret == 200){
+                        this.$message.success(
+                            params.ReportChapterTypeId
+                            ?this.$t('ReportManage.CategoryList.edit_section_successful')
+                            :this.$t('ReportManage.CategoryList.add_section_successful')
+                        )
+                        this.addDialogShow=false
+                        this.getList()
+                    }
+                })
+        },
+
+
+        filterNodes(arr) {
+            arr.length && arr.forEach(item => {
+                item.Child && item.Child.length && this.filterNodes(item.Child)
+                if((item.Child && !item.Child.length)) {
+                    delete item.Child
+                }
+            })
+        },
+
+        //控制只能同级拖动
+        canDropHandle(draggingNode, dropNode, type){
+            if(type==='inner') return false //禁止向内部拖动
+            return true
+        },
+
+        //拖动结束
+        dropOverHandle(b,a,i,e) {
+            // 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置
+            const ReportChapterTypeId=b.data.ReportChapterTypeId
+            let index=this.list.findIndex(item=>item.ReportChapterTypeId===ReportChapterTypeId)
+            const PrevReportChapterTypeId=index==0?0:this.list[index-1].ReportChapterTypeId
+            const NextReportChapterTypeId=index==this.list.length-1?0:this.list[index+1].ReportChapterTypeId
+
+            
+            const params={
+                ReportChapterTypeId,
+                PrevReportChapterTypeId,
+                NextReportChapterTypeId
+            }
+            console.log(params);
+            setChapterSort(params).then(res=>{
+                if(res.Ret===200){
+                    this.$message.success(this.$t('ReportManage.CategoryList.move_successful'))
+                }else{
+                    this.getList()
+                }
+            })
+        },
+        
+    },
+}
+</script>
+
+<style lang="scss">
+.el-cascader .el-input{
+  width: 100%;
+}
+.knowledge-tag-page{
+    .content-box{
+        .el-tree-node__content{
+            padding-top: 10px;
+            padding-bottom: 10px;
+            border-bottom: 1px solid #C8CDD9;
+        }
+    }
+}
+
+</style>
+<style lang="scss" scoped>
+.top-wrap{
+    display: flex;
+    justify-content: space-between;
+    background: #FFFFFF;
+    border-radius: 4px;
+    padding: 20px;
+}
+.content-box{
+    padding: 20px;
+    margin-top: 20px;
+    height: calc(100vh - 260px);
+    overflow-y: auto;
+    background-color: #FFFFFF;
+    .classify-item-wrap{
+        flex: 1;
+        padding-right: 20px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        .tag{
+            display: inline-block;
+            min-width: 76px;
+            line-height: 30px;
+            text-align: center;
+            &.open{
+                background-color: #ECF2FE;
+                color: #0052D9;
+            }
+            &.close{
+                background-color: #0052D9;
+                color: #fff;
+            }
+        }
+        .opt-box{
+            .icon-drag,.icon-set,.icon-del{
+                width: 16px;
+                height: 16px;
+                margin-left: 10px;
+            }
+        }
+    } 
+}
+</style>