Selaa lähdekoodia

Merge branch 'master' into cygx_11.1.1

bding 1 vuosi sitten
vanhempi
commit
89c863b67d
47 muutettua tiedostoa jossa 3135 lisäystä ja 153 poistoa
  1. 2 0
      package.json
  2. 5 1
      src/api/api.js
  3. 105 0
      src/api/modules/assistanceDoc.js
  4. 17 0
      src/api/modules/businessCustom.js
  5. 4 0
      src/api/modules/rai/lableApi.js
  6. 4 0
      src/api/modules/rai/pointsApi.js
  7. 4 0
      src/api/modules/rai/raiApi.js
  8. 5 0
      src/api/modules/rai/reportApi.js
  9. 42 0
      src/api/modules/updateLogApi.js
  10. 2 0
      src/main.js
  11. 10 0
      src/routes/modules/customRoutes.js
  12. 82 5
      src/routes/modules/cygxRoutes.js
  13. 67 5
      src/routes/modules/operateRoutes.js
  14. 1 1
      src/styles/index.scss
  15. 2 1
      src/views/Home.vue
  16. 201 0
      src/views/business_ETA_manage/businessAuth.vue
  17. 12 0
      src/views/business_ETA_manage/businessList.vue
  18. 22 6
      src/views/custom_manage/customList/components/deductDetailDlg.vue
  19. 11 4
      src/views/custom_manage/customList/customDetail.vue
  20. 12 2
      src/views/custom_manage/customList/customList.vue
  21. 1 1
      src/views/custom_manage/customList/customListEn.vue
  22. 14 2
      src/views/custom_manage/customList/limitContactListEn.vue
  23. 2 1
      src/views/ficc_manage/userApplication.vue
  24. 70 52
      src/views/rai_manage/activityManage/activityManage.vue
  25. 20 9
      src/views/rai_manage/activityManage/applyManage.vue
  26. 86 7
      src/views/rai_manage/activityManage/components/addActivity.vue
  27. 6 0
      src/views/rai_manage/activityManage/components/addComopnents/ResearchDeduct.vue
  28. 80 0
      src/views/rai_manage/activityManage/components/addComopnents/modifyImgDlg.vue
  29. 124 0
      src/views/rai_manage/activityManage/components/imgMeeting.vue
  30. 519 0
      src/views/rai_manage/activityManage/meetingManagement.vue
  31. 1 1
      src/views/rai_manage/activityManage/roadShow/tableTabs.js
  32. 1 1
      src/views/rai_manage/activityManage/roadShowList.vue
  33. 51 47
      src/views/rai_manage/components/addChoiceness.vue
  34. 20 0
      src/views/rai_manage/components/apply/applyTableColums.js
  35. 17 2
      src/views/rai_manage/components/reportComponents/CompanyDetail.vue
  36. 13 3
      src/views/rai_manage/cygxManage/applyUserList.vue
  37. 67 0
      src/views/rai_manage/reportManage/components/roadshowApplyDlg.vue
  38. 15 1
      src/views/rai_manage/reportManage/reportChoiceness.vue
  39. 1 0
      src/views/roadshow_manage/statistics/index.scss
  40. 1 1
      src/views/roadshow_manage/statistics/researcher.vue
  41. 209 0
      src/views/system_manage/assistance_center/assistanceCenter.vue
  42. 369 0
      src/views/system_manage/assistance_center/assistanceDocAdd.vue
  43. 45 0
      src/views/system_manage/assistance_center/assistanceDocDetail.vue
  44. 472 0
      src/views/system_manage/assistance_center/docClassifyManage.vue
  45. 10 0
      src/views/system_manage/assistance_center/utils/common.js
  46. 136 0
      src/views/system_manage/components/logSetDialog.vue
  47. 175 0
      src/views/system_manage/updateLogManage.vue

+ 2 - 0
package.json

@@ -28,6 +28,7 @@
     "crypto-js": "^3.1.9-1",
     "dependencies": "^0.0.1",
     "dll": "^0.2.0",
+    "drag-tree-table": "^2.2.0",
     "element-resize-detector": "^1.2.2",
     "element-ui": "2.13.0",
     "font-awesome": "^4.7.0",
@@ -38,6 +39,7 @@
     "js-md5": "^0.7.3",
     "less-loader": "^4.1.0",
     "lodash": "^4.17.21",
+    "opencc-js": "^1.0.5",
     "pptxgenjs": "^3.10.0",
     "qrcode": "^1.4.4",
     "sortablejs": "^1.15.0",

+ 5 - 1
src/api/api.js

@@ -73,6 +73,9 @@ import {reportVarietyENInterence} from './modules/reportVariety'
 //商家管理
 import {businessCustomInterence} from './modules/businessCustom'
 
+//帮助中心
+import {assistanceDocInterence} from './modules/assistanceDoc'
+
 export {
   dataBaseInterface,
   mychartInterface,
@@ -110,7 +113,8 @@ export {
   cloudDiskInterface,
   businessTripInterence,
   reportVarietyENInterence,
-  businessCustomInterence
+  businessCustomInterence,
+  assistanceDocInterence
 };
 
 //老接口 研报 ppt等

+ 105 - 0
src/api/modules/assistanceDoc.js

@@ -0,0 +1,105 @@
+/**
+ * 帮助中心api
+ */
+import http from "@/api/http.js"
+
+export const assistanceDocInterence = {
+    /**
+     * 获取文章列表
+     * @param Keyword String 文章标题
+     * @param PageSize number 每页数据条数
+     * @param CurrentIndex number 当前页面
+     * @param ClassifyId number 分类id
+     * @returns 
+     */
+    getAssistanceDocList:(params)=>{
+      return http.get('/help_doc/list',params)
+    },
+    /**
+     * 新增文章
+     * @param ClassifyId number 分类Id
+     * @param Title string 题目
+     * @param Author string 作者
+     * @param Status number 1
+     * @param Content string 正文
+     * @param AnchorData array 锚点数组
+     * @param AnchorData[0].AnchorId string 锚点Id
+     * @param AnchorData[0].Anchor string 锚点名称
+     * @param AnchorData[0].Child array 子锚点数组
+     */
+    addAssistanceDoc:(params)=>{
+      return http.post('/help_doc/add',params)
+    },
+    /**
+     * 文章详情
+     * @param DocId string 文章Id
+     */
+    getAssistanceDoc:(params)=>{
+      return http.get('/help_doc/detail',params)
+    },
+    /**
+     * 文章发布/取消发布
+     * @param DocId number 文章Id
+     * @param Status number 状态
+     */
+    assistanceDocPublish:(params)=>{
+      return http.post('/help_doc/publish',params)
+    },
+    /**
+     * 文章发布/取消发布
+     * @param DocId number 文章Id
+     */
+    assistanceDocDelete:(params)=>{
+      return http.post('/help_doc/delete',params)
+    },
+    /**
+     * 获取分类列表
+     * @param Keyword String分类名称
+     * @returns 
+     */
+    getAssistanceClassifyList:(params)=>{
+      return http.get('/help_doc/classify/list',params)
+    },
+    /**
+     * 新增分类
+     * @param ParentId number 父节点Id
+     * @param HelpDocClassifyName string 添加的目录名称
+     */
+    addAssistanceClassify:(params)=>{
+      return http.post('/help_doc/classify/add',params)
+    },
+    /**
+     * 编辑分类
+     * @param HelpDocClassifyId number 节点Id
+     * @param ParentId number 父节点Id
+     * @param HelpDocClassifyName string 添加的目录名称
+     */
+    editAssistanceClassify:(params)=>{
+      return http.post('/help_doc/classify/edit',params)
+    },
+    /**
+     * 修改分类可见权限
+     * @param HelpDocClassifyId number 文章Id
+     * @param VisibleBusinessIds number 商家Id 多选 ,拼接
+     */
+    editAssistanceClassifyVisible:(params)=>{
+      return http.post('help_doc/classify/visible/edit',params)
+    },
+    /**
+     * 删除分类
+     * @param ClassifyId number 节点Id
+     */
+    deleteAssistanceClassify:(params)=>{
+      return http.get('/help_doc/classify/delete',params)
+    },
+    /**
+     * 移动分类
+     * @param ClassifyId number 节点Id
+     * @param ParentClassifyId number 父节点Id
+     * @param PrevClassifyId number 上一个节点Id 没有为0
+     * @param NextClassifyId number 下一个节点Id 没有为0
+     */
+    moveAssistanceClassify:(params)=>{
+      return http.post('/help_doc/classify/move',params)
+    },
+}

+ 17 - 0
src/api/modules/businessCustom.js

@@ -104,5 +104,22 @@ export const businessCustomInterence = {
      */
     addBusiness:(params)=>{
         return http.post('/eta_business/add',params)
+    },
+    /**
+     * 获取商家权限详情
+     * @param EtaBusinessId 商家ID
+     * @returns
+     */
+    getAuthList:(params)=>{
+        return http.get('/eta_business/menu/list',params)
+    },
+    /**
+     * 设置商家权限
+     * @param EtaBusinessId 商家ID
+     * @param MenuIds 权限的ID列表
+     * @returns 
+     */
+    setAuthList:(params)=>{
+        return http.post('/eta_business/menu/relate/save',params)
     }
 }

+ 4 - 0
src/api/modules/rai/lableApi.js

@@ -29,6 +29,10 @@ const lableApi = {
   postLableTagMove: (params) => {
     return http.post("/cygx/tag/move", params);
   },
+  /* 微路演视频留言列表 */
+  video_and_voiceImgActivityVideo: (params) => {
+    return http.get("/cygx/activityVideo/video_and_voice/img", params);
+  },
 };
 
 export default lableApi;

+ 4 - 0
src/api/modules/rai/pointsApi.js

@@ -13,6 +13,10 @@ const raiPoints = {
   activityPointsBill: (params) => {
     return http.get("/custom/company/activity/points/bill", params);
   },
+  // 专项调研次数明细
+  specialPointsBill: (params) => {
+    return http.get("/custom/company/activity/special/points/bill", params);
+  },
   // 扣点的截至时间
   activityDeadlineSet: (params) => {
     return http.get("/cygx/activity/deadlineSet", params);

+ 4 - 0
src/api/modules/rai/raiApi.js

@@ -1216,6 +1216,10 @@ const raiInterface = {
   activityTripSendGroupList: (params) => {
     return http.get("/cygx/special/trip/tempMsg/sendGroupList", params);
   },
+  // 根据图片获取建会信息接口
+  activityImgToText: (params) => {
+    return http.post("/cygx/activity/imgToText", params);
+  },
 };
 
 /* 权益小程序管理 专项调研模块*/

+ 5 - 0
src/api/modules/rai/reportApi.js

@@ -29,6 +29,11 @@ const raiReport = {
   reportChartPermissionFirstProduct: (params) => {
     return http.get("/cygx/chartPermission/firstProduct", params);
   },
+  // 报告精选申请记录接口
+  reportSelectionTarryList: (params) => {
+    return http.get("/cygx/reportSelection/tarryList", params);
+  },
+  
 };
 
 export default raiReport;

+ 42 - 0
src/api/modules/updateLogApi.js

@@ -0,0 +1,42 @@
+/* ETA版本更新日志api */
+import http from "@/api/http.js"
+
+export const updateLogInterface = {
+    /**
+     * 版本更新日志列表
+     * @param Keyword String
+     * @param SortType  Number
+     * @param PageSize Number
+     * @param CurrentIndex Number
+     * @param {*} params 
+     */
+    getLogList:(params)=>{
+        return http.get('/eta_version_update_log/page_list',params)
+    },
+    /**
+     * 新增更新日志
+     * @param Version String
+     * @param Content String
+     * @param UpdateDate String
+     */
+    addLogData:(params)=>{
+        return http.post('/eta_version_update_log/add',params)
+    },
+    /**
+     * 编辑更新日志
+     * @param Id Number 
+     * @param Version String
+     * @param Content String
+     * @param UpdateDate String
+     */
+    editLogData:(params)=>{
+        return http.post('/eta_version_update_log/edit',params)
+    },
+    /**
+     * 删除更新日志
+     * @param Id Number
+     */
+    deleteLogData:(params)=>{
+        return http.post('/eta_version_update_log/del',params)
+    }
+}

+ 2 - 0
src/main.js

@@ -35,6 +35,8 @@ require('froala-editor/css/froala_style.min.css');
 // Import Froala Editor css files.
 import 'froala-editor/css/froala_editor.pkgd.min.css';
 import 'froala-editor/css/plugins/quick_insert.css';
+// froala-editor 预览时的样式,如需使用在展示富文本的节点上加上 .fr-view 的类
+import 'froala-editor/css/froala_style.min.css'
 
 // Import and use Vue Froala lib.
 import VueFroala from 'vue-froala-wysiwyg';

+ 10 - 0
src/routes/modules/customRoutes.js

@@ -415,6 +415,16 @@ export default [
           pathFrom: "businessETAList",
           pathName: "商家管理",
         }
+      },
+      {
+        path:'businessETAAuth',
+        name:"商家权限",
+        component: () => import('@/views/business_ETA_manage/businessAuth.vue'),
+        hidden: false,
+        meta:{
+          pathFrom: "businessETAList",
+          pathName: "商家管理",
+        }
       }
     ],
   },

+ 82 - 5
src/routes/modules/cygxRoutes.js

@@ -346,11 +346,11 @@ export default [
     ],
   },
 
-  /* 查研观向活动 */
+  /* 弘则活动管理 */
   {
     path: "/",
     component: home,
-    name: "查研观向活动",
+    name: "弘则活动管理",
     hidden: false,
     icon_path: require("@/assets/img/home/rai_activity.png"),
     children: [
@@ -391,7 +391,12 @@ export default [
         name: "报名管理",
         hidden: false,
       },
-
+      {
+        path: "meetingManagement",
+        component: () => import("@/views/rai_manage/activityManage/meetingManagement.vue"),
+        name: "到会管理",
+        hidden: false,
+      },
       {
         path: "practicalMeeting",
         component: () => import("@/views/rai_manage/activityManage/practicalMeeting.vue"),
@@ -405,7 +410,7 @@ export default [
         hidden: true,
         meta: {
           pathFrom: "practicalMeeting",
-          pathName: "线下到会管理",
+          pathName: "到会管理",
           keepAlive: false,
         },
       },
@@ -433,7 +438,7 @@ export default [
         hidden: true,
         meta: {
           pathFrom: "onLineManage",
-          pathName: "线上到会管理",
+          pathName: "到会管理",
           keepAlive: false,
         },
       },
@@ -495,4 +500,76 @@ export default [
       },
     ],
   },
+  /* 研选活动管理 */
+  {
+    path: "/",
+    component: home,
+    name: "研选活动管理",
+    hidden: false,
+    icon_path: require("@/assets/img/home/rai_activity.png"),
+    children: [
+      {
+        path: "purchaserActivityManage",
+        component: () => import("@/views/rai_manage/activityManage/activityManage.vue"),
+        name: "活动管理",
+        hidden: false
+      },
+      {
+        path: "addPurchaserActivity",
+        component: () => import("@/views/rai_manage/activityManage/components/addActivity.vue"),
+        name: "添加活动",
+        hidden: true,
+        meta: {
+          pathFrom: "purchaserActivityManage",
+          pathName: "活动管理",
+          keepAlive: false,
+        },
+      },
+      {
+        path: "editPurchaserActivity",
+        component: () => import("@/views/rai_manage/activityManage/components/addActivity.vue"),
+        name: "编辑活动",
+        hidden: true,
+        meta: {
+          pathFrom: "purchaserActivityManage",
+          pathName: "活动管理",
+          keepAlive: false,
+        },
+      },
+      {
+        path: "purchaserApplyManage",
+        component: () => import("@/views/rai_manage/activityManage/applyManage.vue"),
+        name: "报名管理",
+        hidden: false,
+      },
+      {
+        path: "purchaserMeetingManagement",
+        component: () => import("@/views/rai_manage/activityManage/meetingManagement.vue"),
+        name: "到会管理",
+        hidden: false,
+      },
+      {
+        path: "purchaserAppointment",
+        component: () => import("@/views/rai_manage/activityManage/components/appointment.vue"),
+        name: "爽约记录",
+        hidden: true,
+        meta: {
+          pathFrom: "practicalMeeting",
+          pathName: "到会管理",
+          keepAlive: false,
+        },
+      },
+      {
+        path: "attendMeeting",
+        component: () => import("@/views/rai_manage/activityManage/components/attendMeeting.vue"),
+        name: "到会详情",
+        hidden: true,
+        meta: {
+          pathFrom: "onLineManage",
+          pathName: "到会管理",
+          keepAlive: false,
+        },
+      }
+    ],
+  },
 ];

+ 67 - 5
src/routes/modules/operateRoutes.js

@@ -8,8 +8,8 @@ export default [
 		name: '运营管理',
 		hidden: false,
 		icon_path: require('@/assets/img/home/custom_ico.png'),
-        children:[
-            {
+		children:[
+			{
 				path:'daynews',
 				component:()=> import('@/views/report_manage/dayilyNews.vue'),
 				name:'每日资讯',
@@ -49,12 +49,74 @@ export default [
 				name: '留言管理员',
 				hidden: false,
 			},
-            {
+			{
 				path:"voiceManage",
 				component: () => import('@/views/system_manage/voiceManage.vue'),
 				name: '语音播报管理',
 				hidden: false,
 			},
-        ]
-    }
+			{
+				path:"updateLogManage",
+				component: () => import('@/views/system_manage/updateLogManage.vue'),
+				name: '更新日志配置',
+				hidden: false,
+			},
+			{
+				path:"assistanceCenter",
+				component: () => import('@/views/system_manage/assistance_center/assistanceCenter.vue'),
+				name: '帮助中心配置',
+				hidden: false,
+			},
+			{
+				path:"assistanceDocDetail",
+				component: () => import('@/views/system_manage/assistance_center/assistanceDocDetail.vue'),
+				name: '查看文章',
+				hidden: true,
+				meta: {
+					pathFrom: 'assistanceCenter',
+					pathName: '帮助中心配置'
+				}
+			},
+			{
+				path:"assistanceDocAdd",
+				component: () => import('@/views/system_manage/assistance_center/assistanceDocAdd.vue'),
+				name: '添加文章',
+				hidden: true,
+				meta: {
+					pathFrom: 'assistanceCenter',
+					pathName: '帮助中心配置'
+				}
+			},
+			{
+				path:"assistanceDocEdit",
+				component: () => import('@/views/system_manage/assistance_center/assistanceDocAdd.vue'),
+				name: '编辑文章',
+				hidden: true,
+				meta: {
+					pathFrom: 'assistanceCenter',
+					pathName: '帮助中心配置'
+				}
+			},
+			{
+				path:"assistanceDocEdit",
+				component: () => import('@/views/system_manage/assistance_center/assistanceDocAdd.vue'),
+				name: '编辑文章',
+				hidden: true,
+				meta: {
+					pathFrom: 'assistanceCenter',
+					pathName: '帮助中心配置'
+				}
+			},
+			{
+				path:"docClassifyManage",
+				component: () => import('@/views/system_manage/assistance_center/docClassifyManage.vue'),
+				name: '分类管理',
+				hidden: true,
+				meta: {
+					pathFrom: 'assistanceCenter',
+					pathName: '帮助中心配置'
+				}
+			},
+		]
+	}
 ]

+ 1 - 1
src/styles/index.scss

@@ -28,4 +28,4 @@ $color_green:#67C23A;
   border-radius: 5px;
   color: #3994fb;
   background-color: #dcecfc;
-}
+}

+ 2 - 1
src/views/Home.vue

@@ -256,7 +256,8 @@
           <el-row class="grid-content bg-purple-light contentc" style="min-width:900px;">
             <el-col :span="24" class="content-wrapper" :style="!isHaveAside ? 'padding: 0 30px 0 0;' : ''">
               <transition name="fade" mode="out-in">
-                <router-view></router-view>
+                <!-- 加入key 解决不同路由到同一个文件时的缓存问题 -->
+                <router-view :key="$route.path"></router-view>
               </transition>
             </el-col>
           </el-row>

+ 201 - 0
src/views/business_ETA_manage/businessAuth.vue

@@ -0,0 +1,201 @@
+<template>
+    <div class="business-auth-wrap">
+        <div class="header">
+            <div class="name">{{$route.query.name||''}}</div>
+            <div class="btn-wrap">
+                <el-button @click="handleBtnClik('cancel')">取消</el-button>
+                <el-button type="primary" @click="handleBtnClik('save')">保存</el-button>
+            </div>
+        </div>
+        <div class="auth-wrap">
+            <el-tree 
+                v-loading="treeLoading"
+                ref="checkboxTree"
+                :data="authList" 
+                :props="{label:'Name',children:'Children'}" 
+                :default-expand-all="false"
+                show-checkbox 
+                node-key="MenuId"
+                :default-checked-keys="defaultCheckedKeys">
+            </el-tree>
+        </div>
+    </div>
+</template>
+
+<script>
+import {businessCustomInterence} from '@/api/api.js'
+export default {
+    data() {
+        return {
+            authList:[],
+            defaultCheckedKeys:[],
+            treeLoading:false
+        };
+    },
+    methods: {
+        getBusinessAuthList(){
+            const EtaBusinessId = this.$route.query.id
+            if(!EtaBusinessId) return 
+            this.treeLoading = true
+            businessCustomInterence.getAuthList({
+                EtaBusinessId:Number(EtaBusinessId)
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.treeLoading = false
+                if(!res.Data) return
+                const {List,ChoiceList=[],HalfChoiceList=[]} = res.Data
+                this.authList = List||[]
+                this.defaultCheckedKeys = ChoiceList.filter((item)=>!HalfChoiceList.some((halfItem)=>item===halfItem))
+            })
+        },
+        async handleBtnClik(type){
+            if(type==='save'){
+                //获取树形列表选择的项 getCheckedKeys getHalfCheckedKeys
+                const keys = this.$refs.checkboxTree.getCheckedKeys()
+                const halfKeys = this.$refs.checkboxTree.getHalfCheckedKeys()
+                if(!keys.length&&!halfKeys.length){
+                    this.$message.warning('请至少选择一个权限')
+                    return
+                }
+                //合成一个数组并去重
+                const ChoiceList = Array.from(new Set([...keys,...halfKeys]))
+                //请求接口
+                const res = await businessCustomInterence.setAuthList({
+                    EtaBusinessId:Number(this.$route.query.id),
+                    MenuIds:ChoiceList,
+                    HalfMenuIds:halfKeys
+                })
+                if(res.Ret!==200) return 
+                this.$message.success('权限设置成功')
+            }
+            this.$router.push('/businessETAList')
+        }
+    },
+    mounted(){
+        this.getBusinessAuthList()
+    }
+};
+</script>
+
+<style lang="scss">
+.business-auth-wrap{
+    .el-tree {
+        border-top: 1px solid #E5E7ED;
+        border-left: 1px solid #E5E7ED;
+        border-right: 1px solid #E5E7ED;
+        width: 98%;
+        margin-bottom: 40px;
+        .el-tree-node__label{
+            margin:10px;
+        }
+        .el-tree-node__content{
+            min-width: 200px;
+            width: 200px;
+            white-space: normal;
+            box-sizing: border-box;
+        }
+        .el-tree-node{
+            .el-tree-node{
+                .el-tree-node__children{
+                    width: 100%;
+                }
+                .el-tree-node{
+                    &:not(:first-child){
+                    /* .el-tree-node__content{
+                        border-right: 1px solid #E5E7ED;
+                    } */
+                        border-top: 1px solid #E5E7ED;
+                    }
+                    .el-tree-node__content{
+                        border-right: 1px solid #E5E7ED;
+                    }
+                }
+    
+            }
+        }
+        .el-tree-node__content {
+            padding: 5px 10px !important;
+            height: auto;
+            .el-tree-node__expand-icon.el-icon-caret-right {
+            //display: none;
+            }
+        }
+        > .el-tree-node {
+            padding: 0 !important;
+            display: flex;
+            border-bottom: 1px solid #E5E7ED;
+
+            > .el-tree-node__children {
+            width: 100%;
+            > .el-tree-node {
+                &:not(:first-child) {
+                border-top: 1px solid #E5E7ED;
+                }
+                >.el-tree-node__content{
+                    border-left: 1px solid #E5E7ED;
+                    border-right: 1px solid #E5E7ED;
+                }
+            }
+            }
+        }
+        .el-tree-node__children {
+            display: flex;
+            flex-direction: column;
+            .el-tree-node {
+                display: flex;
+                flex: 1;
+                padding: 0px !important;
+                .el-tree-node__content {
+                    border-bottom: none;
+                    .custom-tree-node {
+                    height: 24px;
+                    display: flex;
+                    align-items: center;
+                    .tree-btn {
+                        margin-left: 10px;
+                        display: none;
+                    }
+                    .el-button {
+                        padding: 0px !important;
+                        border-radius: 4px;
+                        background: #363554;
+                        color: #ffffff;
+                    }
+                    }
+                }
+                .el-tree-node__children {
+                    .el-tree-node {
+                    &:not(:first-child) {
+                        .el-tree-node__content {
+                        //border-left: none;
+                        }
+                    }
+                    }
+                }
+            }
+        }
+    }
+
+}
+</style>
+<style scoped lang="scss">
+.business-auth-wrap{
+    border: 1px solid #ECECEC;
+    padding: 20px 30px;
+    background: #fff;
+    border-radius: 4px;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+    .header{
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        .name{
+            font-size: 18px;
+            font-weight: bold;
+        }
+    }
+    .auth-wrap{
+        margin-top:20px;
+    }
+}
+</style>

+ 12 - 0
src/views/business_ETA_manage/businessList.vue

@@ -99,6 +99,7 @@
                     </el-table-column>
                     <el-table-column
                         label="操作"
+                        min-width="100"
                         align="center"
                     >
                         <template slot-scope="scope">
@@ -113,6 +114,7 @@
                                     <span class="el-dropdown-link">
                                         <i class="el-icon-more el-icon--right"></i>
                                         <el-dropdown-menu slot="dropdown">
+                                            <el-dropdown-item command="setAuth">权限设置</el-dropdown-item>
                                             <el-dropdown-item command="modifySale">修改销售</el-dropdown-item>
                                             <el-dropdown-item command="disable">{{scope.row.Enable?'禁用':'启用'}}</el-dropdown-item>
                                         </el-dropdown-menu>
@@ -394,6 +396,16 @@ export default {
                 this.showModifySaller=true
             }else if (type==='disable'){
                 this.changeBusinessStatus(data)
+            }else if(type==='setAuth'){
+                /* let {href} = this.$router.resolve({path:`/businessETAAuth`,query:{id:EtaBusinessId}});
+                 window.open(href,'_blank'); */
+                 this.$router.push({
+                    path:'/businessETAAuth',
+                    query:{
+                        id:data.EtaBusinessId,
+                        name:data.BusinessName
+                    }
+                })
             }
         },
 

+ 22 - 6
src/views/custom_manage/customList/components/deductDetailDlg.vue

@@ -1,17 +1,27 @@
 <template>
   <div class="">
     <!-- banner 详情的弹框 -->
-    <el-dialog title="研选服务点数明细" :visible.sync="isShowResearchNumber" width="80%" v-dialogDrag :close-on-click-modal="false" :modal-append-to-body="false" center @close="handleClose">
+    <el-dialog
+      :title="isShowDlgType == '专项调研' ? '专项调研次数明细' : '研选服务点数明细'"
+      :visible.sync="isShowResearchNumber"
+      width="1200px"
+      v-dialogDrag
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      center
+      @close="handleClose"
+    >
       <el-table style="margin-bottom: 30px" :data="tableList" border height="500">
         <el-table-column align="center" prop="Content" label="事项"></el-table-column>
-        <el-table-column align="center" prop="CreateTime" label="时间"></el-table-column>
-        <el-table-column align="center" prop="RealName" label="参会人" width="150"></el-table-column>
-        <el-table-column align="center" prop="minNumber" label="小计" width="100">
+        <el-table-column align="center" prop="CreateTime" label="时间" width="180"></el-table-column>
+        <el-table-column align="center" prop="ChartPermissionName" label="行业" width="100" v-if="isShowDlgType == '专项调研'"></el-table-column>
+        <el-table-column align="center" prop="RealName" label="参会人" width="100"></el-table-column>
+        <el-table-column align="center" prop="minNumber" label="小计" width="80">
           <template slot-scope="{ row }">
             <span :style="{ color: row.BillDetailed > 0 ? '#31c640' : '#ec808d' }"> {{ row.BillDetailed > 0 ? "+" + row.BillDetailed : row.BillDetailed }}</span>
           </template>
         </el-table-column>
-        <el-table-column align="center" prop="Points" label="合计" width="100"></el-table-column>
+        <el-table-column align="center" :prop="isShowDlgType == '专项调研' ? 'Total' : 'Points'" label="合计" :width="isShowDlgType == '专项调研' ? '300' : '100'"></el-table-column>
       </el-table>
     </el-dialog>
   </div>
@@ -30,6 +40,10 @@ export default {
       type: Object,
       default: {},
     },
+    isShowDlgType: {
+      type: String,
+      default: "",
+    },
   },
   watch: {
     isShowResearchNumber: {
@@ -48,10 +62,12 @@ export default {
     // 关闭弹框
     handleClose() {
       this.$emit("update:isShowResearchNumber", false);
+      this.$emit("update:isShowDlgType", "");
     },
     // 获取表格数据
     async getDataList() {
-      const res = await raiInterface.activityPointsBill({ CompanyId: this.dataForm.CompanyId });
+      const res =
+        this.isShowDlgType == "专项调研" ? await raiInterface.specialPointsBill({ CompanyId: this.dataForm.CompanyId }) : await raiInterface.activityPointsBill({ CompanyId: this.dataForm.CompanyId });
       if (res.Ret === 200) {
         this.tableList = res.Data.List || [];
       }

+ 11 - 4
src/views/custom_manage/customList/customDetail.vue

@@ -63,7 +63,7 @@
 							</li>
 							<li v-if="raiform.SpecialSurplus">
 								<label class="label-num" >专项调研剩余次数</label>
-								<span class="con">{{raiform.SpecialSurplus}}</span>
+								<span class="con">{{raiform.SpecialSurplus}} <span class="editsty" @click="clickDlgNumberHandler('专项调研')">明细>></span></span>
 							</li>
 							<li v-if="RoleType==='admin'" style="width:100%">
 								<label class="label"
@@ -73,7 +73,7 @@
 							<li  style="width:100%" v-if="raiform.Points">
 								<label class="label-num">研选服务点数</label>
 								<span class="con" style="word-break: break-word;">{{raiform.Points}}</span>
-								<span v-if="raiform.Points" @click="isShowResearchNumber = true" class="con" style="word-break: break-word;color:#409EFF;padding-left:10px;cursor: pointer;">明细>></span>
+								<span v-if="raiform.Points" @click="clickDlgNumberHandler('研选服务')" class="con" style="word-break: break-word;color:#409EFF;padding-left:10px;cursor: pointer;">明细>></span>
 							</li>
 						</ul>
 						<el-collapse v-model="raiCollapseOpen" accordion>
@@ -634,7 +634,8 @@
 		@close="productReadInfoShow=false"
 		></product-read-info>
 		<!-- 研选服务点数明细 弹框 -->
-		<DeductDetailDlg :isShowResearchNumber.sync="isShowResearchNumber" :dataForm="raiform"/>
+
+		<DeductDetailDlg :isShowResearchNumber.sync="isShowResearchNumber" :isShowDlgType.sync="isShowDlgType" :dataForm="raiform"/>
 		<!-- 历史签约弹窗 新版 -->
 		<HistoryContract 
 			:isPreview="isPreview"
@@ -787,6 +788,7 @@ export default {
 			IsSubscribe:[],//是否关注公众号
 
 			isShowResearchNumber:false,// 研选服务点数明细 弹框
+			isShowDlgType:'',
 		};
 	},
 	methods: {
@@ -1530,7 +1532,12 @@ export default {
 		changeSubscribe(){
 			this.search_txt = '';
 			this.getuserTable();
-		}
+		},
+	// 研选服务、专项调研明细
+	clickDlgNumberHandler(type){
+		this.isShowDlgType = type
+		this.isShowResearchNumber =true
+	},
 	},
 	mounted() {
 		this.getDetail();

+ 12 - 2
src/views/custom_manage/customList/customList.vue

@@ -411,7 +411,11 @@
 					</el-table-column>
 					<el-table-column
 					prop="createTime"
-					:label="act_status=='冻结'?'冻结时间':act_status=='正式'?'转正时间':act_status=='流失'?'流失时间':'创建时间'"
+					:label="
+						act_status=='冻结'?'冻结时间'
+						:act_status=='正式'?'转正时间'
+						:act_status=='流失'?'流失时间'
+						:act_status=='关闭'?'关闭时间':'创建时间'"
 					sortable="custom"
 					align="center" min-width="6.14%">
 						<template slot-scope="scope">
@@ -431,6 +435,9 @@
                                         ? `/${scope.row.LossTime.split('/')[1].substr(0,10)}`
                                         :''}}
 								</template>
+								<template v-else-if="act_status=='关闭'">
+									{{$moment(scope.row.CloseTime).format('YYYY.MM.DD')}}
+								</template>
 								<template v-else>
 									{{$moment(scope.row.CreatedTime).format('YYYY.MM.DD')}}
 								</template>
@@ -2033,7 +2040,10 @@ ShareListDialog},
 				}else{
 					this.SortByTodo = false
 					this.sort_type = item.order === 'ascending' ? 'asc':item.order === 'descending' ? 'desc' : '';
-					this.sort_param = item.column.label=='转正时间'?'formalTime':item.column.label=='冻结时间'?'freezeTime':item.column.label=='流失时间'?'lossTime':item.prop;
+					this.sort_param = item.column.label=='转正时间'?'formalTime'
+									:item.column.label=='冻结时间'?'freezeTime'
+									:item.column.label=='流失时间'?'lossTime'
+									:item.column.label=='关闭时间'?'closeTime':item.prop;
 				}
 				this.page_no = 1;
 				this.getTableData();

+ 1 - 1
src/views/custom_manage/customList/customListEn.vue

@@ -281,7 +281,7 @@ import reportVarietyEnSet from '@/components/reportVarietyEnSet.vue'
       },
       handleShowSetVariety(item){
         this.activeItem=item
-        this.checkedVariety=item.EnPermissions||[]
+        this.checkedVariety=_.cloneDeep(item.EnPermissions||[]) 
         this.showSetVariety=true
       },
       handleChangeVariety(){

+ 14 - 2
src/views/custom_manage/customList/limitContactListEn.vue

@@ -75,6 +75,11 @@
     <!-- 添加/编辑联系人 -->
     <contact-save-en-dia :contactsSubmitForm="contactsSubmitForm" title="编辑联系人" :showAddDia.sync="showAddDia"
     :companyId="0" @updateList="getList"></contact-save-en-dia>
+
+    <el-image-viewer 
+        v-if="showViewer" 
+        :on-close="()=>{this.showViewer = false}" 
+        :url-list="[imgUrl]" />
   </div>
 </template>
 
@@ -82,12 +87,13 @@
 import clickNumberDetail from "../compontents/clickNumberDetailDia.vue"
 import ContactSaveEnDia from './components/ContactSaveEnDia.vue';
 import mPage from '@/components/mPage.vue';
+import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
 import { customInterence } from '@/api/api.js'
 
   export default {
     name:'contactLimitList',
     components:{
-      mPage,clickNumberDetail,ContactSaveEnDia
+      mPage,clickNumberDetail,ContactSaveEnDia,ElImageViewer
     },
     data() {
       return {
@@ -110,7 +116,9 @@ import { customInterence } from '@/api/api.js'
           contactsId:""
         },
         showAddDia:false,
-        contactsSubmitForm:{}
+        contactsSubmitForm:{},
+        showViewer:false,
+        imgUrl:''
       }
     },
     watch: {
@@ -208,6 +216,10 @@ import { customInterence } from '@/api/api.js'
           })
         }).catch(() => {});
       },
+      reviewCard(url){
+        this.imgUrl = url
+        this.showViewer = true
+      }
     }
   }
 </script>

+ 2 - 1
src/views/ficc_manage/userApplication.vue

@@ -70,7 +70,7 @@
           <template slot-scope="{ row }">
             <div v-if="activeName == 1">
              <!--  <span class="editsty" v-if="row.OpStatus === 0 && row.IsMove === 0&&!(row.Status==='潜在用户'||row.Status==='流失')" @click="dealHandle(row)">标记处理</span> -->
-              <span class="editsty" v-if="row.OpStatus === 0 && row.IsMove === 0&&!(row.Status==='潜在用户'||row.Status==='流失')" @click="handleChooseGroup(row)">标记</span>
+              <span class="editsty" v-if="row.OpStatus === 0 && row.IsMove === 0" @click="handleChooseGroup(row)">标记</span>
             </div>
             <div v-else>
               <!-- <span class="editsty" v-if="row.Status==='待处理'" @click="dealHandle(row)">标记处理</span> -->
@@ -331,6 +331,7 @@ export default {
     //打开标记分组弹窗
     handleChooseGroup(row){
         this.choosed_row = row
+        this.choosed_group=''
         this.isChooseGroupDialogShow = true
     },
     //标记分组

+ 70 - 52
src/views/rai_manage/activityManage/activityManage.vue

@@ -5,16 +5,13 @@
     <el-card style="margin-bottom: 20px">
       <div class="top-card-box">
         <div class="tabs-box">
-          <span
-            v-for="(item, index) in listTitle"
-            :key="item.ChartPermissionId"
-            @click="tabsBoxBtn(item, index)"
-            :class="index == tabsPitchon ? 'pitch' : ''"
-            >{{ item.PermissionName }}</span
-          >
+          <span v-for="(item, index) in listTitle" :key="item.ChartPermissionId" @click="tabsBoxBtn(item, index)" :class="index == tabsPitchon ? 'pitch' : ''">{{ item.PermissionName }}</span>
         </div>
-        <div>
-          <el-button type="primary" @click="$router.push('/addActivity')">添加活动</el-button>
+        <div style="display: flex">
+          <el-upload ref="imgUpload" action="#" :http-request="handleUploadImg" :show-file-list="false" accept="image/*">
+            <el-button type="primary">识图建会</el-button>
+          </el-upload>
+          <el-button style="margin-left: 20px" type="primary" @click="$router.push(!isResearch ? '/addActivity' : '/addPurchaserActivity')">添加活动</el-button>
         </div>
       </div>
     </el-card>
@@ -23,45 +20,18 @@
       <!-- 选择部分 -->
       <div class="screen-box">
         <div>
-          <el-select placeholder="行业" clearable v-model="industry" @change="conditionChange" style="margin-bottom: 20px">
-            <el-option
-              v-for="item in chartPermissionList"
-              :label="item.PermissionName"
-              :key="item.ChartPermissionId"
-              :value="item.ChartPermissionId"
-            ></el-option>
+          <el-select placeholder="行业" clearable v-model="industry" @change="conditionChange" style="margin-bottom: 20px" v-if="!isResearch">
+            <el-option v-for="item in chartPermissionList" :label="item.PermissionName" :key="item.ChartPermissionId" :value="item.ChartPermissionId"></el-option>
           </el-select>
           <el-select placeholder="活动类型" clearable v-model="cactivityTypeVal" @change="conditionChange">
-            <el-option
-              v-for="item in cactivityTypeList"
-              :label="item.ActivityTypeName"
-              :key="item.ActivityTypeId"
-              :value="item.ActivityTypeId"
-            ></el-option>
+            <el-option v-for="item in cactivityTypeList" :label="item.ActivityTypeName" :key="item.ActivityTypeId" :value="item.ActivityTypeId"></el-option>
           </el-select>
-          <el-date-picker
-            v-model="publishDate"
-            type="date"
-            placeholder="发布时间"
-            format="yyyy 年 MM 月 dd 日"
-            value-format="yyyy-MM-dd"
-            @change="conditionChange"
-          >
-          </el-date-picker>
-          <date-picker
-            style="margin-bottom: 20px"
-            v-model="issueTime"
-            type="date"
-            range
-            placeholder="活动时间"
-            value-type="format"
-            @change="conditionChange"
-          >
-          </date-picker>
+          <el-date-picker v-model="publishDate" type="date" placeholder="发布时间" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd" @change="conditionChange"> </el-date-picker>
+          <date-picker style="margin-bottom: 20px" v-model="issueTime" type="date" range placeholder="活动时间" value-type="format" @change="conditionChange"> </date-picker>
           <el-select placeholder="发布状态" clearable v-model="status" @change="conditionChange" style="margin-bottom: 20px">
             <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id"></el-option>
           </el-select>
-          <el-input v-model="activityLabel" @input="titleInput" placeholder="请输入活动标签" clearable style="display: inline-block; width: 220px">
+          <el-input v-model="activityLabel" @input="titleInput" placeholder="请输入活动标签" clearable style="display: inline-block; width: 220px; margin-bottom: 20px">
             <i slot="prefix" class="el-input__icon el-icon-search"></i>
           </el-input>
         </div>
@@ -94,13 +64,13 @@
         <el-table-column align="center" width="146" label="操作">
           <template slot-scope="{ row }">
             <span v-if="row.PublishStatus == 0 && tabsPitchon == 0" class="editsty" @click="operationBtn(row.ActivityId, '发布')">发布</span>
-            <span v-if="row.PublishStatus == 3 && tabsPitchon == 0" class="editsty" @click="operationBtn(row.ActivityId, '重新发布')">重新发布</span>
-            <span v-if="row.PublishStatus == 1 && tabsPitchon == 0" class="editsty" @click="operationBtn(row.ActivityId, '取消发布')">取消发布</span>
+            <span v-if="row.PublishStatus == 3" class="editsty" @click="operationBtn(row.ActivityId, '重新发布')">重新发布</span>
+            <span v-if="row.PublishStatus == 1" class="editsty" @click="operationBtn(row.ActivityId, '取消发布')">取消发布</span>
             &nbsp;&nbsp;
             <span class="editsty" @click="editBtn(row.ActivityId, row.PublishStatus)">编辑</span>
             &nbsp;&nbsp;
             <span class="deletesty" v-if="row.PublishStatus == 0 && tabsPitchon == 0" @click="operationBtn(row.ActivityId, '删除')">删除</span>
-            <span class="editsty" v-if="row.IsShowSigninButton " @click="handleDownLoadImg(row)">下载签到码</span>
+            <span class="editsty" v-if="row.IsShowSigninButton" @click="handleDownLoadImg(row)">下载签到码</span>
           </template>
         </el-table-column>
       </el-table>
@@ -110,17 +80,28 @@
       </el-col>
     </el-card>
     <atc-particulars :dialogVisible.sync="dialogVisible" :detailData.sync="detailData" />
+    <imgMeeting :isShowImgMeetingDlg.sync="isShowImgMeetingDlg" :imgMeetingData.sync="imgMeetingData" @childrenImgMeetingHandler="childrenImgMeetingHandler" />
   </div>
 </template>
 
 <script>
+import * as OpenCC from "opencc-js";
+// 将繁体中文(香港)转换为简体中文(中国大陆)
+const converter = OpenCC.Converter({ from: "hk", to: "cn" });
 import mPage from "@/components/mPage.vue";
-import { raiInterface } from "@/api/api.js";
+import { raiInterface, sealInterence } from "@/api/api.js";
 import AtcParticulars from "../components/atcParticulars.vue";
+import imgMeeting from "./components/imgMeeting.vue";
 export default {
   name: "",
-  components: { mPage, AtcParticulars },
-  props: {},
+  components: { mPage, AtcParticulars, imgMeeting },
+  props: {
+    Type: {
+      type: String,
+      emnu: ["hongze", "purchaser"], // 弘则,研选
+      default: "hongze",
+    },
+  },
   data() {
     return {
       listTitle: [
@@ -159,12 +140,19 @@ export default {
       detailData: {}, //
       activityLabel: "",
       publishDate: "",
+      baseApi: process.env.API_ROOT,
+      isShowImgMeetingDlg: false,
+      imgMeetingData: [],
     };
   },
   computed: {
     sta() {
       return this.status >= 0 && typeof this.status == "number" ? this.status : 2;
     },
+    // 弘则 研选 是否是研选
+    isResearch() {
+      return this.$route.path.indexOf("purchaser") != -1 ? true : false;
+    },
   },
   created() {},
   mounted() {
@@ -180,7 +168,8 @@ export default {
       this.activityLabel = initialize.activityLabel;
       this.publishDate = initialize.publishDate;
     }
-    this.chartPermission();
+    // 研选下 没有行业的搜索框
+    !this.isResearch && this.chartPermission();
     this.activityType();
     this.getsummaryManageList();
   },
@@ -247,7 +236,7 @@ export default {
     //编辑
     editBtn(id, show) {
       this.$router.push({
-        path: "/editActivity",
+        path: !this.isResearch ? "/editActivity" : "/editPurchaserActivity",
         query: {
           id: id,
           isShow: show,
@@ -261,7 +250,7 @@ export default {
     },
     //获取行业
     chartPermission() {
-      raiInterface.chartPermission().then((res) => {
+      raiInterface.chartPermission({ IsHideResearch: !this.isResearch }).then((res) => {
         if (res.Ret === 200) {
           this.chartPermissionList = res.Data.List;
         }
@@ -269,7 +258,7 @@ export default {
     },
     //活动类型
     activityType() {
-      raiInterface.getActivityType().then((res) => {
+      raiInterface.getActivityType({ IsResearch: this.isResearch }).then((res) => {
         if (res.Ret === 200) {
           this.cactivityTypeList = res.Data.List;
         }
@@ -290,6 +279,7 @@ export default {
           ActiveState: this.activeStateId,
           ActivityLabel: this.activityLabel,
           PublishStartDate: this.publishDate,
+          IsResearch: this.isResearch,
         })
         .then((res) => {
           if (res.Ret !== 200) return;
@@ -331,6 +321,34 @@ export default {
         a.click();
       };
     },
+    async handleUploadImg(params) {
+      if (!params.file) return;
+      const fd = new FormData();
+      fd.append("file", params.file);
+      try {
+        const res = await sealInterence.resourceUpload(fd);
+        if (res.Ret === 200) {
+          const resImg = await raiInterface.activityImgToText({
+            ImgUrl: res.Data.ResourceUrl,
+          });
+          if (resImg.Ret === 200) {
+            this.isShowImgMeetingDlg = true;
+            this.imgMeetingData = resImg.Data.List.map((item) => {
+              return {
+                ...item,
+                Company: converter(item.Company),
+              };
+            });
+          }
+        }
+      } catch (err) {
+        console.log(err);
+      }
+    },
+    // 点击取消的回调事件
+    childrenImgMeetingHandler() {
+      this.$refs.imgUpload.clearFiles();
+    },
   },
   /* 页面跳转前记录参数 */
   beforeRouteLeave(to, form, next) {

+ 20 - 9
src/views/rai_manage/activityManage/applyManage.vue

@@ -37,8 +37,14 @@
           <el-button type="primary" @click="sendMessage">发送模板消息</el-button>
         </div>
         <div>
-          <el-select placeholder="行业" clearable v-model="industry" @change="conditionChange" style="margin-bottom: 20px">
-            <el-option v-for="item in chartPermissionList" :label="item.PermissionName" :key="item.ChartPermissionId" :value="item.ChartPermissionId"></el-option>
+          <el-select placeholder="行业" clearable v-model="industry" @change="conditionChange" style="margin-bottom: 20px"
+          v-if="!isResearch">
+            <el-option
+              v-for="item in chartPermissionList"
+              :label="item.PermissionName"
+              :key="item.ChartPermissionId"
+              :value="item.ChartPermissionId"
+            ></el-option>
           </el-select>
           <el-select placeholder="活动类型" clearable @focus="activityType" v-model="cactivityTypeVal" @change="conditionChange" style="margin-bottom: 20px">
             <el-option v-for="item in cactivityTypeList" :label="item.ActivityTypeName" :key="item.ActivityTypeId" :value="item.ActivityTypeId"></el-option>
@@ -112,7 +118,7 @@ import ParticularsDialog from "../components/apply/particularsDialog.vue";
 import AtcParticulars from "../components/atcParticulars.vue";
 import GenerationAsk from "../components/generationAsk.vue";
 import SummaryRemind from "../components/apply/summaryRemind.vue";
-import { ListTitle, TableApplyColums, StatusSelect, PublishSelect } from "../components/apply/applyTableColums";
+import { ListTitle , purchaserListTitle , TableApplyColums, StatusSelect, PublishSelect } from "../components/apply/applyTableColums";
 import TemplateMessage from "../components/apply/templateMessage.vue";
 export default {
   name: "",
@@ -159,8 +165,12 @@ export default {
     };
   },
   computed: {
+    // 弘则 研选 是否是研选
+    isResearch(){
+      return this.$route.path.indexOf("purchaser")!=-1?true:false
+    },
     listTitle() {
-      return ListTitle;
+      return !this.isResearch?ListTitle:purchaserListTitle;
     },
     statusSelect() {
       return StatusSelect;
@@ -177,12 +187,12 @@ export default {
       this.page_no = 1;
       this.init();
       this.getsDataList();
-    },
+    }
   },
   created() {},
   mounted() {
     this.tableApplyColums = TableApplyColums(1);
-    this.chartPermission();
+    !this.isResearch && this.chartPermission();
     this.getsDataList();
   },
   methods: {
@@ -197,7 +207,7 @@ export default {
       this.tableApplyColums = TableApplyColums(item.ChartPermissionId);
       this.cactivityTypeVal = "";
       this.isResearchPoints = false;
-      this.tabsSelectionOne = item.ChartPermissionId == 2 ? false : true;
+      this.tabsSelectionOne = item.ChartPermissionId == 2 || item.ChartPermissionId == 5 ? false : true;
       this.page_no = 1;
       this.getsDataList();
     },
@@ -215,6 +225,7 @@ export default {
           ActivityTypeId: this.cactivityTypeVal,
           ActiveState: this.cactivityStatus,
           PublishStatus: this.publishStatus ? Number(this.publishStatus) : 2,
+          IsResearch:this.isResearch
         })
         .then((res) => {
           if (res.Ret !== 200) return;
@@ -304,7 +315,7 @@ export default {
     },
     //获取行业
     chartPermission() {
-      raiInterface.chartPermission().then((res) => {
+      raiInterface.chartPermission({IsHideResearch:!this.isResearch}).then((res) => {
         if (res.Ret === 200) {
           this.chartPermissionList = res.Data.List;
         }
@@ -392,7 +403,7 @@ export default {
         let status = row[key] == 1 ? "未开始" : row[key] == 2 ? "进行中" : "已结束";
         return status;
       } else if (key == "PublishStatus") {
-        let status = row["PublishStatus"] == 1 ? "已发布" : "未发布";
+        let status = row["PublishStatus"] == 1 ? "已发布" : row["PublishStatus"] == 2 ?"未发布":"已取消";
         return status;
       } else {
         return row[key];

+ 86 - 7
src/views/rai_manage/activityManage/components/addActivity.vue

@@ -11,6 +11,7 @@
             clearable
             v-model="optionFormregion"
             style="width: 360px; margin-right: 30px"
+            v-if="!isResearch"
           >
             <el-option v-for="item in chartPermissionList" :label="item.PermissionName" :key="item.PermissionName" :value="item.PermissionName"></el-option>
           </el-select>
@@ -75,7 +76,7 @@
         </div>
         <!-- 复选 模块 -->
         <div style="margin-top: 20px">
-          <research-deduct ref="researchSelect" :cactivityType="cactivityType" :optionFormregion="optionFormregion" />
+          <research-deduct ref="researchSelect" :cactivityType="cactivityType" :optionFormregion="optionFormregion" :isResearch="isResearch" />
         </div>
         <div style="margin: 20px 0 0 98px" class="add-delete" v-for="(item, index) in addSubjectLabel" :key="index">
           <template v-if="subjectRadio == 2">
@@ -207,6 +208,13 @@
           </el-upload>
           <el-progress type="circle" :percentage="percentage" width="40" style="margin-left: 10px" v-if="startUpload"></el-progress>
         </div>
+        <div class="audio-content cover-content" style="margin-top: 10px" v-if="(fileListAudio.length || addEditVideo.length) && defaultImage">
+          <span class="text" style="width: 70px; text-align: right">封面:</span>
+          <div class="img-content">
+            <img :src="defaultImage" alt="" />
+            <div class="modify" @click="modifyImgHandler">修改</div>
+          </div>
+        </div>
       </template>
       <div style="text-align: center; margin-top: 30px">
         <el-button type="primary" @click="submitForm('保存')">保存</el-button>
@@ -262,6 +270,7 @@
       </template>
       <p style="padding-bottom: 50px"></p>
     </el-dialog>
+    <modify-img-dlg :modifyImgVisible.sync="modifyImgVisible" :videoAndVoiceList.sync="videoAndVoiceList" />
   </div>
 </template>
 
@@ -273,10 +282,11 @@ import AddIndustryMark from "../../components/addIndustryMark.vue";
 import richTextMixins from "../../components/apply/RichTextMixins";
 import MD5 from "js-md5";
 import ResearchDeduct from "./addComopnents/ResearchDeduct.vue";
+import ModifyImgDlg from "./addComopnents/modifyImgDlg.vue";
 
 export default {
   name: "",
-  components: { AddIndustryMark, ResearchDeduct },
+  components: { AddIndustryMark, ResearchDeduct, ModifyImgDlg },
   props: {},
   data() {
     return {
@@ -343,9 +353,18 @@ export default {
       startUpload: false, //开始上传
       percentage: 0,
       isShowAddIcon: true, //主题标签的添加的iocn 是否显示
+      modifyImgVisible: false,
+      defaultImage: "",
+      shareImg:'',
+      videoAndVoiceList: [],
     };
   },
-  computed: {},
+  computed: {
+    // 弘则 研选 是否是研选
+    isResearch(){
+      return this.$route.path.indexOf("Purchaser")!=-1?true:false
+    }
+  },
   mixins: [richTextMixins],
   watch: {
     radio: {
@@ -374,10 +393,20 @@ export default {
         this.isCheckAllType(newval === 4 ? true : false);
       },
     },
+    '$route.path':{
+      handler(value){
+        console.log(value,'value');
+      },
+      immediate:true
+    }
   },
   created() {},
   mounted() {
-    this.chartPermission();
+    if(!this.isResearch){
+      this.chartPermission();
+    }else{
+      this.optionFormregion="买方研选"
+    }
     this.getActivityType();
     this.customerTypelist();
     this.getIndustry();
@@ -392,6 +421,7 @@ export default {
     }
   },
   methods: {
+    // 上传音频
     async handleUploadAudio(e) {
       const loading = this.$loading({
         lock: true,
@@ -403,6 +433,7 @@ export default {
       form.append("file", e.file);
       const res = await resourceVoiceupload(form);
       if (res.Ret === 200) {
+        this.getVideoAndImg(1);
         let obj = {
           name: res.Data.ResourceName,
           url: res.Data.ResourceUrl,
@@ -476,6 +507,8 @@ export default {
       raiInterface.activityDetail({ ActivityId: Number(this.$route.query.id) }).then((res) => {
         if (res.Ret !== 200) return;
         const { Data } = res;
+        this.defaultImage = Data.BackgroundImg
+        this.shareImg = Data.ShareImg
         this.activeIsState = Data.ActiveState;
         this.cactivityType = Data.ActivityTypeId;
         this.optionFormregion = Data.ChartPermissionName;
@@ -506,6 +539,7 @@ export default {
           RefPage.SiginupDeadline = Data.SiginupDeadline;
           RefPage.PointsSet = Data.PointsSet;
           RefPage.institutionName = Data.PointsSet.CompanyName;
+          RefPage.isShowHz = !!Data.IsShowHz
         });
         this.addEditVideo = Data.VideoDetail
           ? [Data.VideoDetail].map((item) => {
@@ -613,7 +647,7 @@ export default {
         Body: this.content,
         PermissionName: this.optionFormregion,
         CustomerTypeIds: this.checkedCitiesTwo,
-        IsAllCustomerType:this.checkAll?1:0,
+        IsAllCustomerType: this.checkAll ? 1 : 0,
         LimitPeopleNum: Number(this.astrict) || 0,
         IndustrialManagementIdS: arr.length ? arr.join(",") : "",
         IndustrialSubjectIdS: this.markValue.length ? this.markValue.join(",") : "",
@@ -633,6 +667,10 @@ export default {
         IsBClass: RefPage.isBClass ? 1 : 0,
         SiginupDeadline: RefPage.SiginupDeadline,
         PointsSet,
+        BackgroundImg:this.defaultImage,
+        ShareImg:this.shareImg,
+        IsResearch:this.optionFormregion.includes('研选')?true:false,
+        IsShowHz:RefPage.isShowHz?1:0
       });
 
       if (res.Ret !== 200) return;
@@ -641,7 +679,7 @@ export default {
     },
     //获取行业
     chartPermission() {
-      raiInterface.chartPermissionList().then((res) => {
+      raiInterface.chartPermissionList({IsHideResearch:!this.isResearch}).then((res) => {
         if (res.Ret === 200) {
           this.chartPermissionList = res.Data.List;
         }
@@ -649,7 +687,7 @@ export default {
     },
     //获取活动类型
     getActivityType() {
-      raiInterface.getActivityType().then((res) => {
+      raiInterface.getActivityType({IsResearch:this.isResearch}).then((res) => {
         if (res.Ret === 200) {
           this.isShowAddIcon = res.Data.IsShowAddIcon;
           this.cactivityTypeList = res.Data.List;
@@ -948,6 +986,7 @@ export default {
         const res = await ALOSSINS.multipartUpload(temName, file, { ...options });
         console.log("上传结果", res);
         if (res.res.status === 200) {
+          this.getVideoAndImg(2);
           let VideoUrl = "https://hzstatic.hzinsights.com/" + res.name;
           this.addEditVideo[0].url = VideoUrl;
           this.startUpload = false;
@@ -981,6 +1020,23 @@ export default {
         this.checkAll = false;
       }
     },
+    // 点击修改图片的弹框
+    modifyImgHandler() {
+      let type = this.addEditVideo.length > 0 ? 2 : 1;
+      this.getVideoAndImg(type, "修改");
+      this.modifyImgVisible = true;
+    },
+    // video_and_voiceImgActivityVideo()
+    async getVideoAndImg(type, isOne = "") {
+      const res = await raiInterface.video_and_voiceImgActivityVideo({
+        FileType: type,
+        ActivityId: Number(this.$route.query.id),
+      });
+      if (res.Ret === 200) {
+        isOne == "修改" ? "" : (this.defaultImage = res.Data.List[0].ImgUrl);
+        this.videoAndVoiceList = res.Data.List;
+      }
+    },
   },
 };
 </script>
@@ -1085,6 +1141,29 @@ export default {
       }
     }
   }
+  .cover-content {
+    align-items: stretch;
+    vertical-align: bottom;
+    .img-content {
+      position: relative;
+      height: 200px;
+      width: 200px;
+      border: 1px solid #ccc;
+      img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .modify {
+      position: absolute;
+      bottom: 0;
+      right: -50px;
+      height: 20px;
+      cursor: pointer;
+      color: #409eff;
+    }
+  }
+
   .el-upload-list__item.is-success.focusing .el-icon-close-tip {
     display: none !important;
   }

+ 6 - 0
src/views/rai_manage/activityManage/components/addComopnents/ResearchDeduct.vue

@@ -6,6 +6,7 @@
         <i class="el-icon-info" />
       </el-tooltip>
     </el-checkbox>
+    <el-checkbox v-if="isResearch && [1,3,5].includes(cactivityType)" v-model="isShowHz"> 同时在弘则活动页展示 </el-checkbox>
     <el-checkbox v-if="cactivityType == 3" v-model="isExternalLabel"> 外部资源 </el-checkbox>
     <template v-if="cactivityType == 7 || cactivityType == 2">
       <el-checkbox v-model="isYidongConduct">
@@ -85,6 +86,10 @@ export default {
       type: String,
       default: "",
     },
+    isResearch: {
+      type:Boolean,
+      default: false,
+    },
   },
   data() {
     return {
@@ -109,6 +114,7 @@ export default {
         CancelDeadlineType: "", //截至报名时间
       },
       dataDeadlineSet: [],
+      isShowHz:false
     };
   },
   computed: {

+ 80 - 0
src/views/rai_manage/activityManage/components/addComopnents/modifyImgDlg.vue

@@ -0,0 +1,80 @@
+<template>
+  <div class="container">
+    <!-- 选择图片的弹框 -->
+    <el-dialog title="选择图片" :visible.sync="modifyImgVisible" width="80%" v-dialogDrag :close-on-click-modal="false" :modal-append-to-body="false" center>
+      <div class="seleect-img-box">
+        <div class="content-img" @click="clickSelectImg(item)" v-for="(item, index) in videoAndVoiceList" :key="index">
+          <img :src="item.ImgUrl" alt="" class="item-img" />
+        </div>
+      </div>
+      <!-- <el-col :span="24" class="toolbar">
+        <m-page :total="total" :page_no="page_no" :pageSize="10" @handleCurrentChange="handleCurrentChangeSelectImg" />
+      </el-col> -->
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { raiInterface } from "@/api/api.js";
+
+export default {
+  name: "",
+  components: {},
+  props: {
+    modifyImgVisible: {
+      type: Boolean,
+      default: false,
+    },
+    videoAndVoiceList: {
+      type: Array,
+      default: [],
+    },
+  },
+  data() {
+    return {
+      imgListArr: [],
+      total: 0,
+      page_no: 1,
+    };
+  },
+  computed: {},
+  watch: {},
+  created() {},
+  mounted() {
+    // this.getSelectImgListAll();
+  },
+  methods: {
+    // 选择图片的分页
+    handleCurrentChangeSelectImg(page) {
+      this.page_no = page;
+      this.getSelectImgList();
+    },
+    clickSelectImg(item) {
+      this.$parent.defaultImage = item.ImgUrl;
+      this.$parent.shareImg = item.ShareImg;
+      this.$emit("update:modifyImgVisible", false);
+    },
+  },
+};
+</script>
+<style scoped lang="scss">
+.seleect-img-box {
+  display: flex;
+  flex-wrap: wrap;
+  .content-img {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 236px;
+    height: 133px;
+    flex-shrink: 0;
+    margin: 0 50px 50px 0;
+    border: 1px solid #dcdfe6;
+    cursor: pointer;
+    .item-img {
+      width: 222px;
+      height: 119px;
+    }
+  }
+}
+</style>

+ 124 - 0
src/views/rai_manage/activityManage/components/imgMeeting.vue

@@ -0,0 +1,124 @@
+<template>
+  <div class="container-img-meeting">
+    <el-dialog width="800px" v-dialogDrag :close-on-click-modal="false" :modal-append-to-body="false" center title="新建标的" :visible.sync="isShowImgMeetingDlg" :before-close="handleClose">
+      <div style="margin-bottom: 10px">
+        <p>请确认建会信息:</p>
+        <div class="box-content" style="padding-left:20px">
+          <div class="box-date">日期</div>
+          <div class="box-time">时间</div>
+          <div class="box-name">公司名称</div>
+        </div>
+      </div>
+      <div class="box-content hover-box-content" v-for="(item, index) in imgMeetingData" :key="item.id">
+        <div class="box-date">
+          <el-date-picker v-model="item.TitmeYMD" type="date" value-format="yyyy年MM月dd日" format="yyyy年MM月dd日  (周ddd)" placeholder="选择日期" style="width: 230px"> </el-date-picker>
+        </div>
+        <div class="box-time">
+          <el-time-picker v-model="item.TitmeHM" value-format="hh:mm A" format="hh:mm A" placeholder="任意时间点" style="width: 160px"> </el-time-picker>
+        </div>
+        <div class="box-name">
+          <el-input v-model="item.Company" placeholder="请输入内容" style="width: 100%" clearable></el-input>
+        </div>
+        <div class="delete-item-icon" @click="deleteLabelItem(item, index)">
+          <img src="~@/assets/img/icons/delete-Item.png" alt="" />
+        </div>
+      </div>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="confirmPerson">确定</el-button>
+        <el-button @click="handleClose">取消</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { raiInterface } from "@/api/api.js";
+export default {
+  name: "",
+  components: {},
+  props: {
+    isShowImgMeetingDlg: {
+      type: Boolean,
+      required: true,
+      default: false,
+    },
+    imgMeetingData: {
+      default: [],
+      required: true,
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      value1: "",
+    };
+  },
+  computed: {},
+  watch: {},
+  created() {},
+  mounted() {},
+  methods: {
+    // 确定事件
+    async confirmPerson() {
+      let isConfirm = this.imgMeetingData.every((item) => item.TitmeYMD && item.TitmeHM && item.Company);
+      if (!isConfirm) return this.$message.error("每格的内容都必填。");
+      const res = await raiInterface.preserveAndPublishAdd({
+        ListImgToText: this.imgMeetingData,
+      });
+      console.log(res);
+      if (res.Ret === 200) {
+        this.$message.success("新增成功!");
+        this.$parent.page_no = 1;
+        this.$parent.getsummaryManageList();
+        this.handleClose();
+      }
+    },
+    handleClose() {
+      this.$emit("update:isShowImgMeetingDlg", false);
+
+      this.$emit("childrenImgMeetingHandler");
+    },
+    deleteLabelItem(item, index) {
+      this.$parent.imgMeetingData.splice(index, 1);
+    },
+  },
+};
+</script>
+<style scoped lang="scss">
+.container-img-meeting {
+  .box-content {
+    margin-top: 20px;
+    display: flex;
+    font-weight: 500;
+
+    .box-date {
+      width: 230px;
+      margin-right: 20px;
+    }
+    .box-time {
+      width: 160px;
+      margin-right: 20px;
+    }
+    .box-name {
+      width: 260px;
+    }
+    .delete-item-icon {
+      display: flex;
+      align-items: center;
+      margin-left: 20px;
+      img {
+        width: 15px;
+        height: 15px;
+      }
+    }
+  }
+  .hover-box-content {
+    margin-top: 0;
+    padding: 10px 20px;
+    &:hover {
+      background-color: #eaf3fe;
+    }
+  }
+}
+</style>

+ 519 - 0
src/views/rai_manage/activityManage/meetingManagement.vue

@@ -0,0 +1,519 @@
+<template>
+  <!-- 实际到会管理页面 -->
+  <div class="container-practical">
+    <!-- 头部el-card -->
+    <el-card style="margin-bottom: 20px">
+      <div class="top-card-box">
+        <el-radio-group v-model="meetingTab" class="tabs-box">
+          <el-radio-button :label="1">线上到会管理</el-radio-button>
+          <el-radio-button :label="2">线下到会管理</el-radio-button>
+        </el-radio-group>
+        <div>
+          <el-input v-model="keyWord" placeholder="请输入活动名称" style="width: 521px" clearable>
+            <i slot="prefix" class="el-input__icon el-icon-search"></i>
+          </el-input>
+        </div>
+      </div>
+    </el-card>
+    <!-- 内容el-card -->
+    <el-card>
+      <!-- 选择部分 -->
+      <div class="screen-box">
+        <div>
+          <el-select placeholder="行业" clearable v-model="industry" @change="conditionChange" style="margin-bottom: 20px"
+          v-if="!isResearch">
+            <el-option
+              v-for="item in chartPermissionList"
+              :label="item.PermissionName"
+              :key="item.ChartPermissionId"
+              :value="item.ChartPermissionId"
+            ></el-option>
+          </el-select>
+          <el-select
+            placeholder="活动类型"
+            clearable
+            @focus="activityType"
+            v-model="cactivityTypeVal"
+            @change="conditionChange"
+            style="margin-bottom: 20px"
+          >
+            <el-option
+              v-for="item in cactivityTypeList"
+              :label="item.ActivityTypeName"
+              :key="item.ActivityTypeId"
+              :value="item.ActivityTypeId"
+            ></el-option>
+          </el-select>
+          <date-picker v-model="issueTime" type="date" range placeholder="活动时间" value-type="format" @change="conditionChange"> </date-picker>
+        </div>
+        <div class="top-buttons">
+          <el-button type="primary" @click="searchCustomer = true" v-if="meetingTab==1">搜索流失客户</el-button>
+          <el-button style="margin-left: 20px" type="primary" 
+          @click="$router.push(isResearch?'/purchaserAppointment':'/appointment')">查看客户爽约记录</el-button>
+        </div>
+      </div>
+      <!-- 表格部分 -->
+      <el-table :data="dataList" style="width: 100%; margin-top: 20px" border="">
+        <el-table-column min-width="400" align="center" label="活动名称">
+          <template slot-scope="scope">
+            <span class="editsty" @click="titleBtnClick(scope.row.ActivityId)"> {{ scope.row.ActivityName }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="ChartPermissionName" align="center" label="行业"></el-table-column>
+        <el-table-column min-width="120" prop="ActivityTypeName" align="center" label="活动类型"></el-table-column>
+        <el-table-column min-width="219" prop="ActivityTimeText" align="center" label="活动时间"></el-table-column>
+        <el-table-column prop="" align="center" label="报名人数">
+          <template slot-scope="scope">
+            <span class="editsty" @click="particulars(scope.row.ActivityId)">{{ scope.row.SignupPeopleNum }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column min-width="105" prop="MeetPeopleNum" align="center" label="实际参会人数"></el-table-column>
+        <el-table-column min-width="105" prop="UpdateTime" align="center" label="数据更新时间" v-if="meetingTab==1"></el-table-column>
+        <el-table-column min-width="115" align="center" label="操作" v-if="meetingTab==1">
+          <template slot-scope="scope">
+            <!-- <input type="file" size="small" name="file" @change="fileSelected()" id="fileImport" class="true-file" style="display: none" /> -->
+            <p class="editsty" v-if="scope.row.IsShowHandMovement" @click="matching(scope.row.ActivityId)">&nbsp;&nbsp;手动匹配</p>
+            <!-- <span class="editsty" v-if="scope.row.IsYidongConduct === 1" @click="particularsSubmit(scope.row.ActivityId)"
+              >{{ scope.row.IsSubmitMeeting === 0 ? "上传" : "修改" }}参会表格</span
+            > -->
+            <span class="editsty" v-if="scope.row.IsShowSubmitMeeting" @click="arriveHandel(scope.row.ActivityId)">&nbsp;&nbsp;提交到会情况</span>
+            <span class="editsty" v-if="scope.row.IsShowUpdateMeeting" @click="arriveHandel(scope.row.ActivityId)">&nbsp;&nbsp;修改到会情况</span>
+            <span class="editsty" v-if="scope.row.IsShowAttendanceDetails" @click="attendMeeting(scope.row, '到会详情')">&nbsp;&nbsp;到会详情</span>
+            <el-popover v-else-if="scope.row.IsSubmitMeeting == 1 && scope.row.OperationStyle == 2" width="500" trigger="hover" placement="right">
+              <p>到会详情浏览记录</p>
+              <el-table :data="gridData" style="width: 100%" border height="350">
+                <el-table-column align="center" property="RealName" label="浏览人"></el-table-column>
+                <el-table-column align="center" property="CreateTime" label="浏览时间"></el-table-column>
+                <el-table-column align="center" property="StopTime" label="停留时长">
+                  <template slot-scope="{ row }">
+                    {{ row.StopTime }}
+                    <span v-if="row.StopTime">s</span>
+                  </template>
+                </el-table-column>
+              </el-table>
+              <p slot="reference" class="editsty" @mouseenter="popoverMouseenter(scope.row.ActivityId)" @click="goDetail(scope.row.ActivityId)">
+                &nbsp;&nbsp;到会详情
+              </p>
+            </el-popover>
+          </template>
+        </el-table-column>
+        <el-table-column min-width="200" align="center" label="操作" v-else-if="meetingTab==2">
+          <template slot-scope="scope">
+            <span v-if="scope.row.OperationStyle == 1" class="editsty" @click="arriveHandel(scope.row.ActivityId)"
+              >&nbsp;&nbsp;提交到会情况</span
+            >
+
+            <span class="editsty" v-if="scope.row.OperationStyle == 2" @click="arriveHandel(scope.row.ActivityId)"
+              >&nbsp;&nbsp;修改到会情况</span
+            >
+
+            <span class="editsty" v-if="scope.row.OperationStyle == 2" @click="particularsOffline(scope.row.ActivityId, '到会详情')"
+              >&nbsp;&nbsp;到会详情</span
+            >
+           
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-col :span="24" class="toolbar">
+        <m-page :total="total" :page_no="page_no" :pageSize="PageSize" @handleCurrentChange="handleCurrentChange" />
+      </el-col>
+    </el-card>
+    <!-- 详情弹框 -->
+    <atc-particulars :dialogVisible.sync="dialogVisible" :detailData.sync="detailData" />
+    <el-dialog
+      v-dialogDrag
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      center
+      :visible.sync="dialogLeparticaShow"
+      customClass="custom-applydialog"
+      :before-close="confirmPerson"
+    >
+      <div slot="title" style="display: flex; align-items: center">
+        <img :src="$icons.warntop" style="color: #fff; width: 16px; height: 16px; margin-right: 5px" />
+        <span style="font-size: 16px">
+          {{ excelType == "Teleconference" && isLimitPeople == 1 ? "预约外呼详情" : "报名详情" }}
+        </span>
+      </div>
+      <div>
+        <p style="margin-bottom: 10px" v-if="isYiDongShow">
+          <template v-if="memberType == 'Admin'"> 共有{{ totalDlg }}人{{ excelType == "AppointmentCall" ? "预约外呼" : "报名" }} </template>
+          <template v-else-if="memberType == 'Sale'">
+            共有{{ totalDlg }}人{{ excelType == "AppointmentCall" ? "预约外呼" : "报名" }},其中本人名下客户{{ myTotalDlg }}人
+          </template>
+          <template v-else>
+            共有{{ totalDlg }}人{{ excelType == "AppointmentCall" ? "预约外呼" : "报名" }},其中本组名下客户{{ myTotalDlg }}人
+          </template>
+        </p>
+        <p style="margin-bottom: 10px" v-else>
+          <template v-if="memberType == 'Admin'"> 共有{{ totalDlg }}人报名</template>
+        </p>
+        <el-table max-height="260px" :data="tableDataSub" border style="width: 100%">
+          <el-table-column width="130" align="center" prop="RealName" key="name" label="姓名"></el-table-column>
+          <el-table-column width="150" align="center" prop="Mobile" key="mobile" label="手机号" v-if="isYiDongShow"></el-table-column>
+          <el-table-column
+            width="150"
+            align="center"
+            prop="OutboundMobile"
+            key="outboundMobile"
+            label="外呼号码"
+            v-if="isYiDongShow"
+          ></el-table-column>
+          <el-table-column align="center" prop="CompanyName" key="company" label="公司名称" v-if="isCClassNot"></el-table-column>
+          <el-table-column width="150" align="center" prop="SellerName" key="seller" label="所属销售"></el-table-column>
+          <el-table-column min-width="110" key="meeting" align="center" label="参会方式" v-if="isYiDongShow">
+            <template slot-scope="{ row }">
+              <span>
+                {{ row.SignupType == 1 ? "预约外呼" : row.SignupType == 2 ? "自主拨入" : row.SignupType == 4 ? "自主入会" : "" }}
+              </span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="confirmPerson">知道了</el-button>
+      </span>
+    </el-dialog>
+    <matching-dlg :matchingDlgShow.sync="matchingDlgShow" :matchingId="matchingId" />
+    <partical-dialog
+      :type="attendType"
+      :offlineId="offlineId"
+      :submitDialog.sync="submitDialog"
+      :dialogVisiblepartica.sync="dialogVisiblepartica"
+      :particlaDlg="particlaDlg"
+    />
+    <search-customer-dlg :searchCustomer.sync="searchCustomer" />
+  </div>
+</template>
+
+<script>
+import mPage from "@/components/mPage.vue";
+import { raiInterface } from "@/api/api.js";
+import AtcParticulars from "../components/atcParticulars.vue";
+import MatchingDlg from "../components/matchingDlg.vue";
+import ParticalDialog from "../components/particalDialog.vue";
+import SearchCustomerDlg from "../components/apply/searchCustomerDlg.vue";
+
+export default {
+  name: "meetingManagement",
+  components: { mPage, AtcParticulars, MatchingDlg, ParticalDialog, SearchCustomerDlg },
+  props: {},
+  data() {
+    return {
+      meetingTab:1,
+      dataList: [], //表格的列表
+      tableDataSub: [],
+      page_no: sessionStorage.getItem("interviewListBack") ? JSON.parse(sessionStorage.getItem("interviewListBack")).page_no : 1,
+      total: 0, //条数
+      PageSize: 10, //每页显示几条
+      keyWord: "",
+      industry: "", //行业
+      cactivityTypeVal: "", //活动
+      chartPermissionList: [], //行业的数组
+      cactivityTypeList: [], //活动类型
+      issueTime: "", //时间
+      tabsPitchonType: 1,
+      detailData: {}, //
+      dialogVisible: false,
+      dialogLeparticaShow: false,
+      companyId: "", //
+      excelType: "",
+      isLimitPeople: "",
+      totalDlg: 0,
+      myTotalDlg: 0,
+      memberType: "",
+      matchingDlgShow: false, //匹配弹框
+      matchingId: "",
+      gridData: [],
+      submitDialog: false, //
+      offlineId: "",
+      dialogVisiblepartica: false, //
+      searchCustomer: false, //搜索流失客户
+      isYidongConduct: 0,
+      particlaDlg: {
+        isSpecial: false,
+        id: "",
+        title: "",
+        type: "",
+      },
+    };
+  },
+  computed: {
+    // 弘则 研选 是否是研选
+    isResearch(){
+      return this.$route.path.indexOf("purchaser")!=-1?true:false
+    },
+    exportUser() {
+      return process.env.API_ROOT + "/cygx/activityMeet/meetingExport?" + localStorage.getItem("auth") || "";
+    },
+    isYiDongShow() {
+      return this.isYidongConduct === 1 || this.excelType !== "CClass";
+    },
+    isCClassNot() {
+      return this.isYidongConduct != 1 && this.excelType == "CClass";
+    },
+    attendType(){
+      return this.meetingTab == 1 ? "" : "线下到会";
+    }
+  },
+  watch: {
+    keyWord() {
+      this.page_no = 1;
+      this.init();
+      this.getsDataList();
+    },
+    meetingTab(value) {
+      if(!this.keyWord){
+        this.page_no = 1;
+        this.init();
+        this.getsDataList();
+      } else this.keyWord=""
+    },
+  },
+  created() {},
+  mounted() {
+    !this.isResearch && this.chartPermission();
+    this.getsDataList();
+  },
+  methods: {
+    init() {
+      this.industry = ""; //行业
+      this.issueTime = ""; //时间
+      this.cactivityTypeVal = ""; //活动
+    },
+    //获取行业
+    chartPermission() {
+      raiInterface.chartPermission({IsHideResearch:!this.isResearch}).then((res) => {
+        if (res.Ret === 200) {
+          this.chartPermissionList = res.Data.List;
+        }
+      });
+    },
+    //活动类型
+    activityType() {
+      raiInterface
+        .activityTypeMeetType({
+          MeetType: this.meetingTab,
+          IsResearch:this.isResearch
+        })
+        .then((res) => {
+          if (res.Ret === 200) {
+            this.cactivityTypeList = res.Data.List;
+          }
+        });
+    },
+    //change事件
+    conditionChange() {
+      this.page_no = 1;
+      this.getsDataList();
+    },
+    //列表表格
+    getsDataList() {
+      raiInterface
+        .activityMeetList({
+          CurrentIndex: this.page_no,
+          PageSize: this.PageSize,
+          StartDate: this.issueTime[0],
+          EndDate: this.issueTime[1],
+          KeyWord: this.keyWord,
+          SearchType: this.tabsPitchonType,
+          ChartPermissionId: this.industry,
+          ActivityTypeId: this.cactivityTypeVal,
+          MeetType: this.meetingTab,
+          IsResearch:this.isResearch
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return;
+          this.dataList = res.Data.List;
+          this.total = res.Data.Paging.Totals;
+        });
+    },
+    //分页
+    handleCurrentChange(page) {
+      this.page_no = page;
+      this.getsDataList();
+    },
+    //手动匹配
+    matching(id) {
+      this.matchingId = id;
+      this.matchingDlgShow = true;
+    },
+    //到会详情
+    attendMeeting(item, text) {
+      if (item.SubmitMeetingType == 1 || item.YidongActivityId) {
+        this.offlineId = item.ActivityId;
+        this.particlaDlg = {
+          id: item.ActivityId,
+          title: text,
+          type: item.SubmitMeetingType,
+        };
+        this.dialogVisiblepartica = true;
+      } else {
+        this.goDetail(item.ActivityId);
+      }
+    },
+    //详情弹框
+    particulars(id) {
+      if(this.meetingTab == 1){
+        raiInterface
+        .appointmentList({
+          ActivityId: id,
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return;
+          this.excelType = res.Data.ExcelType;
+          this.isLimitPeople = res.Data.IsLimitPeople;
+          this.totalDlg = res.Data.Total;
+          this.myTotalDlg = res.Data.MyTotal;
+          this.memberType = res.Data.MemberType;
+          this.isYidongConduct = res.Data.IsYidongConduct;
+          this.$nextTick(() => {
+            this.tableDataSub = res.Data.List;
+          });
+        });
+        this.dialogLeparticaShow = true;
+      }else if(this.meetingTab == 2){
+        this.particularsOffline(id,'报名详情')
+      }
+
+    },
+    particularsOffline(id,text){
+      this.offlineId = id;
+      this.particlaDlg = {
+        id,
+        title: text,
+      };
+      this.dialogVisiblepartica = true;
+    },
+    // meetingExport() {
+    //   const loading = this.$loading({
+    //     lock: true,
+    //     text: "客户参会详情文件下载中...",
+    //     spinner: "el-icon-loading",
+    //     background: "rgba(0, 0, 0, 0.7)",
+    //   });
+    //   const xhr = new XMLHttpRequest();
+    //   xhr.open("GET", this.exportUser, true);
+    //   xhr.responseType = "blob";
+    //   xhr.onload = function () {
+    //     if (this.status == 200) {
+    //       loading.close();
+    //       var blob = this.response;
+    //       var a = document.createElement("a");
+    //       var url = window.URL.createObjectURL(blob); //创建url对象
+    //       a.href = url;
+    //       a.download = "客户参会详情.xlsx";
+    //       a.click();
+    //       window.URL.revokeObjectURL(url); //释放url对象
+    //     } else {
+    //       this.$message.error("下载失败!");
+    //     }
+    //   };
+    //   xhr.send();
+    // },
+    //到会情况
+    // particularsSubmit(id) {
+    //   this.companyId = id;
+    //   $("#fileImport").click();
+    // },
+    //点击标题的弹框
+    titleBtnClick(id) {
+      raiInterface.activityDetail({ ActivityId: Number(id) }).then((res) => {
+        if (res.Ret == 200) {
+          this.detailData = res.Data;
+        }
+      });
+      this.dialogVisible = true;
+    },
+    //关闭弹框
+    confirmPerson() {
+      this.tableDataSub = [];
+      this.dialogLeparticaShow = false;
+    },
+    //到会情况
+    arriveHandel(id) {
+      this.offlineId = id;
+      this.submitDialog = true;
+    },
+    // 上传
+    // fileSelected(type) {
+    //   const that = this;
+    //   if (document.getElementById("fileImport").files[0]) {
+    //     let hostfile = document.getElementById("fileImport").files[0];
+    //     let size = Math.floor(hostfile.size / 1024 / 1024);
+    //     if (size > 200) {
+    //       that.$message.error("上传文件大小不能大于200M!");
+    //       hostfile = {};
+    //       return false;
+    //     }
+    //     if (hostfile.name.toLowerCase().includes(".xlsx")) {
+    //       let form = new FormData();
+    //       form.append("File", hostfile); //hostfile.name
+    //       form.append("ActivityId", that.companyId);
+
+    //       raiInterface.activityMeetImport(form).then((res) => {
+    //         if (res.Ret === 200) {
+    //           that.isShowImportDia = true;
+    //           that.importParams = form;
+    //           that.importData = res.Data || [];
+    //           this.$confirm("参会情况已提交成功,可点击【到会详情】查看", "提示", {
+    //             confirmButtonText: "知道了",
+    //             type: "warning",
+    //             showCancelButton: false,
+    //           });
+    //           this.getsDataList();
+    //         }
+    //         $("#fileImport").val("");
+    //         hostfile = {};
+    //       });
+    //     } else {
+    //       that.$message.error("请上传.xlsx的文件格式!");
+    //     }
+    //   }
+    // },
+    goDetail(id) {
+      let routerUrl = this.$router.resolve({
+        path: "attendMeeting",
+        query: {
+          id: id,
+        },
+      });
+      window.open(routerUrl.href, "_blank");
+    },
+    async popoverMouseenter(id) {
+      const res = await raiInterface.activityMeetHistoryList({
+        ActivityId: id,
+      });
+      if (res.Ret === 200) {
+        this.gridData = res.Data.List || [];
+      }
+    },
+  },
+};
+</script>
+<style scoped lang="scss">
+.container-practical {
+  .top-card-box {
+    display: flex;
+    justify-content: space-between;
+  }
+  .screen-box {
+    display: flex;
+    justify-content: space-between;
+    .top-buttons{
+      display: flex;
+      align-items: flex-start;
+    }
+    .el-select {
+      margin-right: 25px;
+    }
+  }
+  .mx-datepicker {
+    width: 220px !important;
+    margin-right: 25px;
+  }
+  .custom-applydialog {
+    height: 820px;
+  }
+}
+</style>

+ 1 - 1
src/views/rai_manage/activityManage/roadShow/tableTabs.js

@@ -161,7 +161,7 @@ export const PalyTable = [
   },
 ];
 export const TopTabs = [
-  { name: "产业视频", value: 1 },
   { name: "活动视频", value: 2 },
   { name: "活动音频", value: 3 },
+  { name: "产业视频", value: 1 },
 ];

+ 1 - 1
src/views/rai_manage/activityManage/roadShowList.vue

@@ -88,7 +88,7 @@ export default {
     return {
       tableColums: [],
       dataList: [],
-      tabActive: 1, //tabs 选中
+      tabActive: 2, //tabs 选中
       chartPermissionList: [], //行业的数组
       chartPermissionId: "", //行业的id
       issueTime: "", //活动时间

+ 51 - 47
src/views/rai_manage/components/addChoiceness.vue

@@ -50,12 +50,9 @@
             </div>
           </el-form-item>
         </el-form>
-          <!-- 产业/标的 模块 -->
-          <div class="content-module">
-          <draggable
-          v-model="industryList"
-          animation="300"
-          @update="sortChange">
+        <!-- 产业/标的 模块 -->
+        <div class="content-module">
+          <draggable v-model="industryList" animation="300" @update="sortChange">
             <div class="content-industry" v-for="(item, index) in industryList" :key="item.ChartPermissionId">
               <div class="content-name" :class="industryIndex == index ? 'active' : ''" @click="industryBtn(item, index)">{{ item.ChartPermissionName }}</div>
             </div>
@@ -63,15 +60,8 @@
           <div v-for="(item, index) in industryList" :key="item.ChartPermissionId">
             <RichText v-show="industryIndex == index" :ref="'logic' + index" :spareId="'logictest' + index" :isText="contentTextLogic" />
           </div>
-          <draggable
-          :list="industryListItem"
-          animation="300"
-          class="classification"
-          filter=".addIndustrial"
-          :move="onMove"
-          @update="ificationSortChange">
-            <div v-for="(val, num) in industryListItem" :key="val.IndustrialSubjectId" class="industrial" 
-            @click="ificationIndustrialBtn(val, num)" :class="num == ificationIndustrial ? 'pitch' : ''">
+          <draggable :list="industryListItem" animation="300" class="classification" filter=".addIndustrial" :move="onMove" @update="ificationSortChange">
+            <div v-for="(val, num) in industryListItem" :key="val.IndustrialSubjectId" class="industrial" @click="ificationIndustrialBtn(val, num)" :class="num == ificationIndustrial ? 'pitch' : ''">
               <span style="margin-right: 19px">{{ val.IndustrialSubjectName }}</span>
               <span v-if="num == ificationIndustrial">
                 <img src="~@/assets/img/icons/edit1.png" style="width: 12px; height: 12px; marginright: 10px" @click="editText(val, num)" />
@@ -107,6 +97,9 @@
         <div class="content-resource">
           <span class="resource">综述报告:</span>
           <span class="show">{{ overviewList.Title }}</span>
+          <div style="margin-left: 20px">
+            <el-switch @change="switchChangeHandler" v-model="overviewList.IsShowOverviewArticle" :active-value="1" :inactive-value="0" active-text="显示链接" inactive-text="不显示链接"> </el-switch>
+          </div>
         </div>
         <div class="content-bottom">
           <el-button type="primary" @click="confirm('预览')">预览</el-button>
@@ -137,11 +130,11 @@
 <script>
 import RichText from "./richText.vue";
 import { raiInterface } from "@/api/api.js";
-import draggable from 'vuedraggable';
+import draggable from "vuedraggable";
 
 export default {
   name: "",
-  components: { RichText , draggable},
+  components: { RichText, draggable },
   props: {},
   data() {
     return {
@@ -161,10 +154,10 @@ export default {
       },
       rules: {
         title: [{ required: true, message: "请输入标题", trigger: "blur" }],
-        author: [{ required: true, message: "请输入作者", trigger: "blur" }],
-        time: [{ required: true, message: "请输入时间", trigger: "change" }],
-        explain: [{ required: true, message: "请输入产品说明", trigger: "blur" }],
-        reportLink: [{ required: true, message: "请输入报告链接", trigger: "blur" }],
+        // author: [{ required: true, message: "请输入作者", trigger: "blur" }],
+        // time: [{ required: true, message: "请输入时间", trigger: "change" }],
+        // explain: [{ required: true, message: "请输入产品说明", trigger: "blur" }],
+        // reportLink: [{ required: true, message: "请输入报告链接", trigger: "blur" }],
       },
       industryList: [], //行业
       industryIndex: 0, //
@@ -193,10 +186,11 @@ export default {
           this.overviewList = {
             ArticleId: this.industryListItem[this.ificationIndustrial].OverviewArticleId,
             Title: this.industryListItem[this.ificationIndustrial].OverviewArticleTitle,
+            IsShowOverviewArticle: this.industryListItem[this.ificationIndustrial].IsShowOverviewArticle,
           };
         } else {
           this.industrialSubjectName = "";
-          this.overviewList = { ArticleId: 0, Title: "" };
+          this.overviewList = { ArticleId: 0, Title: "", IsShowOverviewArticle: 0 };
         }
       },
       deep: true,
@@ -277,6 +271,7 @@ export default {
         this.overviewList = {
           ArticleId: res.Data.List[0].List && res.Data.List[0].List[0].OverviewArticleId,
           Title: res.Data.List[0].List && res.Data.List[0].List[0].OverviewArticleTitle,
+          IsShowOverviewArticle: res.Data.List[0].List && res.Data.List[0].List[0].IsShowOverviewArticle,
         };
       }
     },
@@ -334,6 +329,7 @@ export default {
         this.overviewList = {
           ArticleId: item.OverviewArticleId,
           Title: item.OverviewArticleTitle,
+          IsShowOverviewArticle: item.IsShowOverviewArticle,
         };
       }
     },
@@ -409,6 +405,7 @@ export default {
               CompanyLabel: [{ name: "", value: item.List.length + 1 }],
               OverviewArticleId: overviewList.ArticleId,
               OverviewArticleTitle: overviewList.Title,
+              IsShowOverviewArticle: overviewList.IsShowOverviewArticle,
             });
           }
         });
@@ -445,6 +442,7 @@ export default {
               IndustrialSubjectName: arr.SubjectName,
               OverviewArticleId: overviewList.ArticleId,
               OverviewArticleTitle: overviewList.Title,
+              IsShowOverviewArticle: overviewList.IsShowOverviewArticle,
             };
             item.List.splice(this.editNum, 1, obj);
           }
@@ -491,7 +489,6 @@ export default {
           let params = this.dataHandle(type);
           // console.log(params);
           if (type == "预览") {
-            console.log(params);
             sessionStorage.setItem("choicenessPre", JSON.stringify(params));
             let { href } = this.$router.resolve({ name: "预览报告精选" });
             window.open(href, "_blank");
@@ -572,42 +569,49 @@ export default {
     deleteLabelItem(item, index) {
       this.industryListItem[this.ificationIndustrial].CompanyLabel.splice(index, 1);
     },
-      // 拖拽排序更新
-  sortChange({oldIndex,newIndex}){
-    this.industryIndex=this.sortChangeFun(this.industryIndex,oldIndex,newIndex)
+    switchChangeHandler(e) {
+      this.industryListItem.forEach((item) => {
+        if (item.OverviewArticleId === this.overviewList.ArticleId) {
+          item.IsShowOverviewArticle = e;
+        }
+      });
+    },
+  },
+  // 拖拽排序更新
+  sortChange({ oldIndex, newIndex }) {
+    this.industryIndex = this.sortChangeFun(this.industryIndex, oldIndex, newIndex);
   },
   //标的拖拽排序更新
-  ificationSortChange({oldIndex,newIndex}){
-    this.ificationIndustrial=this.sortChangeFun(this.ificationIndustrial,oldIndex,newIndex)
+  ificationSortChange({ oldIndex, newIndex }) {
+    this.ificationIndustrial = this.sortChangeFun(this.ificationIndustrial, oldIndex, newIndex);
   },
   // 排序更新后的逻辑
-  sortChangeFun(currentIndex,oldIndex,newIndex){
-    console.log({currentIndex,oldIndex,newIndex});
-    let bigger,smaller
-    if(oldIndex>newIndex){
-      bigger=oldIndex
-      smaller=newIndex
-    }else{
-      bigger=newIndex
-      smaller=oldIndex
+  sortChangeFun(currentIndex, oldIndex, newIndex) {
+    console.log({ currentIndex, oldIndex, newIndex });
+    let bigger, smaller;
+    if (oldIndex > newIndex) {
+      bigger = oldIndex;
+      smaller = newIndex;
+    } else {
+      bigger = newIndex;
+      smaller = oldIndex;
     }
     // 当前算中tab的排序 小于较小的 大于较大的 则不用做变动
-    if(currentIndex < smaller || currentIndex > bigger) return currentIndex
+    if (currentIndex < smaller || currentIndex > bigger) return currentIndex;
     // 移动的是当前选中的
-    if(currentIndex == oldIndex) return newIndex
-    if(oldIndex>newIndex){
+    if (currentIndex == oldIndex) return newIndex;
+    if (oldIndex > newIndex) {
       // 向左移 加加
-      currentIndex++
-    }else if(oldIndex<newIndex){
+      currentIndex++;
+    } else if (oldIndex < newIndex) {
       // 向右移 减减
-      currentIndex--
+      currentIndex--;
     }
-    return currentIndex
+    return currentIndex;
   },
-  onMove(e){
+  onMove(e) {
     // 返回false表示不允许停靠
-    return !!e.relatedContext.element
-  },
+    return !!e.relatedContext.element;
   },
 };
 </script>

+ 20 - 0
src/views/rai_manage/components/apply/applyTableColums.js

@@ -117,6 +117,26 @@ export const ListTitle = [
     ChartPermissionId: 3,
   },
 ];
+
+export const purchaserListTitle = [
+  {
+    PermissionName: "专家电话会",
+    ChartPermissionId: 1,
+  },
+  {
+    PermissionName: "专家线下沙龙",
+    ChartPermissionId: 2,
+  },
+  {
+    PermissionName: "买方线下交流",
+    ChartPermissionId: 5,
+  },
+  {
+    PermissionName: "公司调研",
+    ChartPermissionId: 3,
+  },
+];
+
 //表格列
 export const TableApplyColums = (type) => {
   return type === 1

+ 17 - 2
src/views/rai_manage/components/reportComponents/CompanyDetail.vue

@@ -10,8 +10,11 @@
             </tr>
           </thead>
           <tr v-for="(item, index) in childrenList" :key="index">
-            <td v-for="(i, unm) in item" :key="unm">
+            <td v-for="(i, unm) in item" :key="unm" class="new-box">
               <span class="thbody-rs">{{ i.name }}</span>
+              <template v-if="i.IsNew == 1">
+                <img v-if="unm % 2 == 0" src="https://hzchart.oss-cn-shanghai.aliyuncs.com/cygx/new_subject.png" alt="" class="new-img" />
+              </template>
             </td>
           </tr>
         </table>
@@ -65,15 +68,16 @@ export default {
             }
           });
         this.dataList = res.Data.List;
-        console.log(childrenIndex);
         for (let i = 0; i < childrenIndex; i++) {
           let childrenArr = [];
           this.dataList.forEach((item) => {
             childrenArr.push({
               name: item.List[i] ? item.List[i].SubjectName : "",
+              ...item.List[i],
             });
             childrenArr.push({
               name: item.List[i] ? item.List[i].Count : "",
+              ...item.List[i],
             });
           });
           this.childrenList.push(childrenArr);
@@ -106,6 +110,7 @@ export default {
       color: #666;
       thead {
         position: sticky;
+        z-index: 999;
         top: 0;
         left: 0;
         border-left: 1px solid #dcdfe6;
@@ -137,5 +142,15 @@ export default {
   div::-webkit-scrollbar {
     width: 3px !important;
   }
+  .new-box {
+    position: relative;
+    .new-img {
+      position: absolute;
+      width: 20px;
+      height: 20px;
+      top: 0;
+      left: 0;
+    }
+  }
 }
 </style>

+ 13 - 3
src/views/rai_manage/cygxManage/applyUserList.vue

@@ -43,12 +43,12 @@
             <span v-else>{{ scope.row.CompanyName }}</span>
           </template>
         </el-table-column>
-        <el-table-column prop="SellerName" label="所属销售" align="center">
+        <el-table-column prop="SellerName" label="所属销售" align="center" width="125">
           <template slot-scope="scope">
             <span>{{ scope.row.SellerName }}</span>
           </template>
         </el-table-column>
-        <el-table-column prop="CreateTime" label="申请时间" min-width="130" align="center">
+        <el-table-column prop="CreateTime" label="申请时间" width="160" align="center">
           <template slot-scope="scope">
             <span>{{ scope.row.CreateTime }}</span>
           </template>
@@ -58,11 +58,16 @@
             <span>{{ scope.row.CompanyIdTypeName }}</span>
           </template>
         </el-table-column>
-        <el-table-column prop="ApplicationSource" label="申请来源" min-width="130" align="center">
+        <el-table-column prop="ApplicationSource" label="申请来源" width="115" align="center">
           <template slot-scope="scope">
             <span>{{ scope.row.ApplicationSource }}</span>
           </template>
         </el-table-column>
+        <el-table-column prop="Title" label="申请内容" min-width="130" align="center">
+          <template slot-scope="scope">
+            <span class="editsty" @click="applicationContent(scope.row)">{{ scope.row.Title }}</span>
+          </template>
+        </el-table-column>
         <el-table-column label="操作" align="center" min-width="110">
           <template slot-scope="scope">
             <span class="editsty" v-if="scope.row.BusinessCardUrl" @click="previewImg(scope.row)">查看名片</span>
@@ -188,6 +193,11 @@ export default {
           }
         });
     },
+    // 申请内容
+    applicationContent(item) {
+      window.open(item.HttpUrl, "_blank");
+      console.log(item);
+    },
   },
   created() {},
   mounted() {

+ 67 - 0
src/views/rai_manage/reportManage/components/roadshowApplyDlg.vue

@@ -0,0 +1,67 @@
+<template>
+  <div class="container">
+    <!-- 选择图片的弹框 -->
+    <el-dialog title="路演申请" :visible.sync="isRadshowApplyShow" width="50%" :before-close="handleClose" v-dialogDrag :close-on-click-modal="false" :modal-append-to-body="false" center>
+      <div>
+        <el-table :data="tableData" style="width: 100%; margin-bottom: 20px" border>
+          <el-table-column prop="SubjectName" align="center" label="申请标的"></el-table-column>
+          <el-table-column prop="RealName" align="center" label="申请人"></el-table-column>
+          <el-table-column prop="CompanyName" align="center" label="公司名称"></el-table-column>
+          <el-table-column prop="SellerName" align="center" label="所属销售"></el-table-column>
+          <el-table-column width="160" prop="CreateTime" align="center" label="申请时间"></el-table-column>
+        </el-table>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { raiInterface } from "@/api/api.js";
+
+export default {
+  name: "",
+  components: {},
+  props: {
+    isRadshowApplyShow: {
+      type: Boolean,
+      default: false,
+    },
+    radshowApplyId: {
+      type: Number,
+      default: 0,
+    },
+  },
+  data() {
+    return {
+      tableData: [],
+    };
+  },
+  computed: {},
+  watch: {
+    isRadshowApplyShow: {
+      handler(newVal) {
+        newVal && this.getTableList();
+      },
+    },
+  },
+  created() {},
+  mounted() {},
+  methods: {
+    // 关闭弹框
+    handleClose() {
+      this.$emit("update:isRadshowApplyShow", false);
+      this.$emit("update:radshowApplyId", 0);
+    },
+    // 获取表格数据
+    async getTableList() {
+      const res = await raiInterface.reportSelectionTarryList({
+        ArticleId: this.radshowApplyId,
+      });
+      if (res.Ret === 200) {
+        this.tableData = res.Data.List || [];
+      }
+    },
+  },
+};
+</script>
+<style scoped lang="scss"></style>

+ 15 - 1
src/views/rai_manage/reportManage/reportChoiceness.vue

@@ -37,6 +37,11 @@
             </div>
           </template>
         </el-table-column>
+        <el-table-column prop="Periods" align="center" label="路演申请" width="100">
+          <template slot-scope="{ row }">
+            <span class="editsty" @click="roadshowApplyHandler(row)">{{ row.ApplyTotal }}</span>
+          </template>
+        </el-table-column>
         <el-table-column key="VisibleRange" width="156" label="可见范围" align="center">
           <template slot-scope="{ row }" v-if="row.PublishStatus === 1">
             <el-radio-group v-model="row.VisibleRange" @input="reportVisibleRange(row)">
@@ -61,6 +66,7 @@
       </el-col>
     </el-card>
     <CompanyDetail :isCompanyDetailShow.sync="isCompanyDetailShow" :companyDetailId.sync="companyDetailId" />
+    <roadshow-apply-dlg :isRadshowApplyShow.sync="isRadshowApplyShow" :radshowApplyId.sync="radshowApplyId" />
   </div>
 </template>
 
@@ -68,9 +74,10 @@
 import mPage from "@/components/mPage.vue";
 import { raiInterface } from "@/api/api.js";
 import CompanyDetail from "../components/reportComponents/CompanyDetail.vue";
+import RoadshowApplyDlg from "./components/roadshowApplyDlg.vue";
 export default {
   name: "",
-  components: { mPage, CompanyDetail },
+  components: { mPage, CompanyDetail, RoadshowApplyDlg },
   props: {},
   data() {
     return {
@@ -88,6 +95,8 @@ export default {
       tableData: [], //表格
       isCompanyDetailShow: false, //公司点击详情弹框
       companyDetailId: 0,
+      isRadshowApplyShow: false, // 路演申请
+      radshowApplyId: 0, // 路演申请查看的ID
     };
   },
   computed: {
@@ -217,6 +226,11 @@ export default {
         this.getList();
       }
     },
+    // 路演申请的弹框
+    roadshowApplyHandler(item) {
+      this.radshowApplyId = item.ArticleId;
+      this.isRadshowApplyShow = true;
+    },
   },
   /* 页面跳转前记录参数 */
   beforeRouteLeave(to, form, next) {

+ 1 - 0
src/views/roadshow_manage/statistics/index.scss

@@ -35,6 +35,7 @@
 
 		.table-body-wrapper {
 			max-height: calc(100vh - 340px);
+			margin-right: -6px;
 			overflow-y: scroll;
 			overflow-x: auto;
 			border-bottom: 1px solid #dcdfe6;

+ 1 - 1
src/views/roadshow_manage/statistics/researcher.vue

@@ -155,7 +155,7 @@ export default {
 				}
 				this.$nextTick(() => {
 					this.dataLoading = true;
-					$('table').find('td').css({ width: dynamic_width[this.default_tab]&&dynamic_width[this.default_tab]})
+					$('table').find('td').css({ width: dynamic_width[this.default_tab]?dynamic_width[this.default_tab]:'25%'})
 					$('table').find('.thead-rs').css({ width: dynamic_width[this.default_tab] ? dynamic_width[this.default_tab] : '120px' })
 					$('table').find('.head-column').css({ width: dynamic_width[this.default_tab] ? dynamic_width[this.default_tab] : '25%' })
 				})

+ 209 - 0
src/views/system_manage/assistance_center/assistanceCenter.vue

@@ -0,0 +1,209 @@
+<template>
+  <div class="assistance-center-container">
+    <div class="assistance-center-top-zone">
+      <div class="assistance-center-top-operation">
+        <el-button type="primary" @click="addDocument">添加文章</el-button>
+        <el-button type="primary" @click="classifyManage" style="margin-left: 20px;">分类管理</el-button>
+      </div>
+      <div class="assistance-center-top-search">
+        <el-cascader
+          :options="classifyList"
+          collapse-tags
+          clearable
+          :props="{
+            multiple:true,
+            value:'ClassifyId',
+            label:'ClassifyName',
+            children:'Children',
+            emitPath:false
+          }"
+          placeholder="所属分类"
+          @change="handlSearchClassify"
+        />
+        <el-input placeholder="文章标题" v-model="queryParams.KeyWord" clearable @input="getDocumentList"
+        style="width:500px;margin-left: 20px;">
+				  <i slot="prefix" class="el-input__icon el-icon-search"></i>
+			  </el-input>
+      </div>
+    </div>
+    <el-table ref="documentTable" :data="documentList" border class="document-table">
+      <el-table-column prop="Title" label="文章标题" align="center">
+        <template slot-scope="scope">
+          <span @click="goDetail(scope.row)" class="document-title">{{scope.row.Title}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="ClassifyName" label="所属分类" align="center">
+        <template slot-scope="scope"> <span>{{scope.row.ClassifyName}}</span> </template>
+      </el-table-column>
+      <el-table-column prop="Author" label="文章作者" align="center">
+        <template slot-scope="scope"> <span>{{scope.row.Author}}</span> </template>
+      </el-table-column>
+      <el-table-column prop="Status" label="发布状态" align="center">
+        <template slot-scope="scope"> 
+          <span :style="{color:scope.row.Status==2?'#4FB112':'#F56C6C'}">{{scope.row.Status==2?"已发布":"未发布"}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="CreateTime" label="创建时间" align="center">
+        <template slot-scope="scope"> <span>{{scope.row.CreateTime}}</span> </template>
+      </el-table-column>
+      <el-table-column prop="ModifyTime" label="更新时间" align="center">
+        <template slot-scope="scope"> <span>{{scope.row.ModifyTime}}</span> </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" min-width="110" v-if="Role!='admin'">
+        <template slot-scope="scope">
+          <div style="color:#4099ef;">
+            <span style="margin-right:10px;cursor: pointer;" @click="publish(scope.row)" v-if="scope.row.Status==2">取消发布</span>
+            <template v-if="scope.row.Status==1">
+              <span style="margin-right:10px;cursor: pointer;" @click="editDocument(scope.row)">编辑</span>
+              <span style="margin-right:10px;cursor: pointer;" @click="publish(scope.row)">发布</span>
+            </template>
+            <span style="color: #F56C6C;cursor: pointer;" @click="deleteDocument(scope.row)">删除</span>
+          </div>
+        </template>
+      </el-table-column>
+      <div slot="empty" style="lineHeight:44px;margin:60px 0;color:#999;">
+        <img src="~@/assets/img/cus_m/nodata.png" style="display:block;width:160px;height:128px;margin: auto;">
+        <span>暂无数据</span>
+      </div>
+    </el-table>
+    <!-- 页数选择器 -->
+    <m-page :page_no="queryParams.CurrentIndex" :pageSize="queryParams.PageSize"
+    :total="total" style="position: absolute;right: 40px;bottom: 40px;" @handleCurrentChange="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import mPage from '@/components/mPage.vue';
+import { assistanceDocInterence } from '../../../api/modules/assistanceDoc';
+
+  export default {
+    name:"assistanceCenter",
+    components:{mPage},
+    data() {
+      return {
+        classifyList:[],
+        documentList:[],
+        ClassifyIdList:[],
+        queryParams:{
+          CurrentIndex:1,
+          PageSize:10,
+          ClassifyIds:"",
+          KeyWord:""
+        },
+        total:100
+      }
+    },
+    created(){
+      this.getClassifyList()
+      this.getDocumentList()
+    },
+    methods: {
+      getClassifyList(){
+        assistanceDocInterence.getAssistanceClassifyList().then(res=>{
+          if(res.Ret == 200){
+            this.classifyList = res.Data?res.Data.AllNodes||[]:[]
+          }
+        })
+      },
+      getDocumentList(){
+        assistanceDocInterence.getAssistanceDocList(this.queryParams).then(res=>{
+          if(res.Ret == 200){
+            this.documentList=res.Data.List || []
+            this.total = res.Data.Paging.Totals || 0
+          }
+        })
+      },
+      handlSearchClassify(value){
+        // console.log(value);
+        this.queryParams.ClassifyIds = value.join(',')
+        this.getDocumentList()
+      },
+      pageChange(page_no){
+        this.queryParams.CurrentIndex=page_no
+        this.getDocumentList()
+      },
+      goDetail(item){
+        this.$router.push({path:"/assistanceDocDetail",query:{DocId:item.Id}})
+      },
+      //发布/取消发布
+      publish(item){
+        let text = item.Status==2?'取消发布':'发布'
+
+        this.$confirm(`是否确认${text}?`,"提示",
+        {
+          type:"warning",
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+        }).then(res=>{
+          assistanceDocInterence.assistanceDocPublish({
+            DocId:item.Id,
+            Status:3-item.Status
+          }).then(res=>{
+            if(res.Ret == 200){
+              this.$message.success(text+"成功")
+              this.getDocumentList()
+            }
+          })
+        }).catch(() => {});
+      },
+      addDocument(){
+        this.$router.push("/assistanceDocAdd")
+      },
+      editDocument(item){
+        this.$router.push({path:"/assistanceDocEdit",query:{DocId:item.Id}})
+      },
+      //删除文章
+      deleteDocument(item){
+        this.$confirm('删除后不可恢复,是否确认删除?',"提示",
+        {
+          type:"warning",
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+        }).then(res=>{
+          assistanceDocInterence.assistanceDocDelete({DocId:item.Id}).then(res=>{
+            if(res.Ret == 200){
+              this.$message.success("删除成功")
+              this.getDocumentList()
+            }
+          })
+        }).catch(() => {});
+      },
+      classifyManage(){
+        this.$router.push("/docClassifyManage")
+      }
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+.assistance-center-container{
+  background-color: white;
+  min-height: calc(100vh - 110px);
+  padding: 30px 30px 80px;
+  box-sizing: border-box;
+  border: solid 1px #ECECEC;
+  .assistance-center-top-zone{
+    display: flex;
+    align-items: flex-start;
+    justify-content: space-between;
+    flex-wrap: wrap;
+    margin-bottom: 20px;
+    .assistance-center-top-operation{
+      display: flex;
+      align-items: center;
+      justify-content: flex-start;
+      margin: 0 30px 8px 0;
+    }
+    .assistance-center-top-search{
+      margin-bottom: 8px;
+    }
+  }
+  .document-table{
+    .document-title{
+      color:#409EFF;
+      cursor:pointer;
+    }
+  }
+}
+</style>

+ 369 - 0
src/views/system_manage/assistance_center/assistanceDocAdd.vue

@@ -0,0 +1,369 @@
+<template>
+  <div class="assistance-edit-container">
+    <div class="edit-container-rich-text">
+      <froala
+        id="froala-editor"
+        ref="froalaEditor"
+        :tag="'textarea'"
+        :config="froalaConfig"
+        v-model="addDocForm.Content"
+      ></froala>
+    </div>
+    <div class="edit-container-document-options">
+      <div class="document-options-button-box">
+        <el-button type="primary" class="document-options-button" @click="previewDocument" v-loading="isSubmiting">预览</el-button>
+        <el-button type="primary" class="document-options-button" @click="saveDocument('保存')" v-loading="isSubmiting">保存</el-button>
+        <el-button type="primary" class="document-options-button" @click="saveDocument('发布')" v-loading="isSubmiting">发布</el-button>
+      </div>
+      <div class="document-options-form">
+        <el-form :model="addDocForm" ref="addDocForm" :rules="addDocRules">
+          <el-form-item label="文章标题" prop="Title">
+            <el-input v-model="addDocForm.Title" placeholder="请输入文章标题"></el-input>
+          </el-form-item>
+          <el-form-item label="所属分类" prop="ClassifyId">
+            <el-cascader style="width: 100%;"
+              v-model="addDocForm.ClassifyId" :options="classifyList"
+              :props="{value:'ClassifyId',label:'ClassifyName',children:'Children',emitPath:false,disabled:'Disabled'}" placeholder="所属分类"/>
+          </el-form-item>
+          <el-form-item label="文章作者" prop="Author">
+            <el-input v-model="addDocForm.Author" placeholder="请输入文章作者"></el-input>
+          </el-form-item>
+          <el-form-item label="相关推荐">
+            <div v-for="(item,index) in addDocForm.RecommendData" :key="index" class="form-item-recommendedLink">
+              <el-input v-model="item.Name" placeholder="请输入链接名称" style="width: 190px;"></el-input>
+              <div class="recommendedLink-line"></div>
+              <el-input v-model="item.Url" placeholder="请输入链接" style="width: 190px;"></el-input>
+            </div>
+          </el-form-item>
+        </el-form>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {assistanceDocInterence} from "@/api/api.js"
+import {createBottomHref} from "./utils/common"
+  export default {
+    name:"assistanceDocAdd",
+    data() {
+      const that = this;
+      return {
+        editor: null,
+        froalaConfig: {
+          toolbarButtons: [
+            "insertImage",
+            "insertVideo",
+            "embedly",
+            "insertFile",
+            "textColor",
+            "bold",
+            "italic",
+            "underline",
+            "strikeThrough",
+            "subscript",
+            "superscript",
+            "fontFamily",
+            "fontSize",
+            "color",
+            "inlineClass",
+            "inlineStyle",
+            "paragraphStyle",
+            "lineHeight",
+            "paragraphFormat",
+            "align",
+            "formatOL",
+            "formatUL",
+            "outdent",
+            "indent",
+            "quote",
+            "insertTable",
+            "emoticons",
+            "fontAwesome",
+            "specialCharacters",
+            "insertHR",
+            "selectAll",
+            "clearFormatting",
+            "html",
+            "undo",
+            "redo"
+          ],
+          height:"calc(100vh - 230px)",
+          fontSize: ["12", "14", "16", "18", "20", "24", "28", "32", "36", "40"],
+          fontSizeDefaultSelection: "16",
+          theme: "dark", //主题
+          placeholderText: "请输入内容",
+          language: "zh_cn", //国际化
+          imageUploadURL: process.env.API_ROOT + "/report/uploadImg", //上传url
+          videoUploadURL: process.env.API_ROOT + "/report/uploadImg", //上传url
+          fileUploadURL: process.env.API_ROOT + "/report/uploadImg", //上传url 更多上传介绍 请访问https://www.froala.com/wysiwyg-editor/docs/options
+          imageEditButtons:['imageAlign', 'imageCaption', 'imageRemove',  '-', 'imageDisplay',  'imageSize'],
+          quickInsertButtons: ["image","video","hr"], //快速插入项
+          toolbarVisibleWithoutSelection: false, //是否开启 不选中模式
+          // disableRightClick:true,//是否屏蔽右击
+          toolbarSticky: false, //操作栏是否自动吸顶
+          // zIndex:99999,
+          saveInterval: 0,
+          /* 				saveParam: 'content',
+            saveURL: process.env.API_ROOT+'/report/saveReportContent',
+            saveMethod: 'POST',
+            saveParams: {}, */
+          events: {
+            //this.editor 定义在vue data 中
+            initialized: function () {
+              that.editor = this;
+            },
+            keyup: function (e, editor) {
+              //添加事件,在每次按键按下时,都记录一下最后停留位置
+              that.$nextTick(function () {
+                that.lastEditRange = getSelection().getRangeAt(0);
+              });
+            },
+            click: function (e, editor) {
+              //添加事件,在每次鼠标点击时,都记录一下最后停留位置
+              that.$nextTick(function () {
+                that.lastEditRange = getSelection().getRangeAt(0);
+              });
+            },
+          },
+        },
+        classifyList:[],
+        addDocForm:{
+          Title:"",
+          ClassifyId:"",
+          Author:"",
+          Status:1,
+          Content:'',
+          AnchorData:[],
+          RecommendData:[{Name:"",Url:""},{Name:"",Url:""}],
+        },
+        addDocRules:{
+          Title:{required:true,message:'文章标题不能为空',trigger:'blur'},
+          ClassifyId:{required:true,message:'文章所属分类不能为空',trigger:'change'},
+          Author:{required:true,message:'文章作者不能为空',trigger:'blur'}
+        },
+        anchorData:[],
+        isSubmiting:false,
+      }
+    },
+    created() {
+      this.getClassifyData()
+      if(this.$route.query.DocId){
+        assistanceDocInterence.getAssistanceDoc({DocId:this.$route.query.DocId}).then(res=>{
+          if(res.Ret == 200){
+            this.addDocForm={
+              Id:res.Data.Id,
+              Title:res.Data.Title,
+              ClassifyId:res.Data.ClassifyId,
+              Author:res.Data.Author,
+              Status:res.Data.Status,
+              Content:res.Data.Content,
+              RecommendData:res.Data.Recommend || [{Name:"",Url:""},{Name:"",Url:""}]
+            }
+            
+          }
+        })
+      }      
+    },
+    mounted(){
+      this.addDocForm.Content=""
+    },
+    methods: {
+      getClassifyData(){
+        assistanceDocInterence.getAssistanceClassifyList().then(res=>{
+          if(res.Ret == 200){
+            this.classifyList = res.Data?res.Data.AllNodes||[]:[]
+          }
+        })
+      },
+      // 生成锚点
+      generateAnchor(){
+        this.anchorData=[]
+        // 搜索富文本中的h1和h2标签 当做一级和二级的锚点
+        this.searchTitleTag(0,1)
+        // console.log(this.addDocForm.Content,this.anchorData);
+      },
+      // 搜索标题标签h1,h2
+      searchTitleTag(searchPosition,firstLevel){
+        let frontH1Posiiton,nextH1Posiiton,H2Posiiton=0
+        let frontH1RightPosiiton,H2RightPosiiton=0
+        let backH1Posiiton,backH2Posiiton=0
+        // 本次搜索第一个h1的位置
+        frontH1Posiiton = this.addDocForm.Content.indexOf('<h1',searchPosition)
+        // 右闭合标签
+        frontH1RightPosiiton = this.addDocForm.Content.indexOf('>',frontH1Posiiton)
+
+        if(frontH1Posiiton == -1) return 
+
+        let anchorText=`id="doc_anchor_${firstLevel}"`
+        // console.log(frontH1Posiiton,firstLevel,'firstLevel');
+        this.addDocForm.Content = this.addDocForm.Content.substring(0, frontH1Posiiton+3) 
+                                  +" "+anchorText + this.addDocForm.Content.substring(frontH1RightPosiiton);
+        // 再次获取右闭合标签
+        frontH1RightPosiiton = this.addDocForm.Content.indexOf('>',frontH1Posiiton)
+        // 对应的</h1>的位置 原本用的</h1>,后来发现> 和 </h1>之间会掺其他标签
+        backH1Posiiton = this.addDocForm.Content.indexOf('<',frontH1RightPosiiton)
+        // 获取标题
+        let AnchorTitle = this.addDocForm.Content.substring(frontH1RightPosiiton+1,backH1Posiiton)
+
+        this.anchorData.push({
+          AnchorId:`${firstLevel}`,
+          Anchor:`doc_anchor_${firstLevel}`,
+          AnchorName:AnchorTitle,
+          Child:[]})
+        // 本次搜索下一个h1的位置
+        nextH1Posiiton = this.addDocForm.Content.indexOf('<h1',backH1Posiiton)==-1?
+                          this.addDocForm.Content.length:this.addDocForm.Content.indexOf('<h1',backH1Posiiton)
+        // 从第一个h1的位置开始查找h2标签
+        H2Posiiton = this.addDocForm.Content.indexOf('<h2',backH1Posiiton)
+
+        let secondLevel=1
+        while (!(H2Posiiton==-1 || H2Posiiton>nextH1Posiiton)) {
+          // 右闭合标签
+          H2RightPosiiton = this.addDocForm.Content.indexOf('>',H2Posiiton)
+
+          // 找到了,并且位置小于下一个h1的位置 
+          let anchorTextH2=`id="doc_anchor_${firstLevel}_${secondLevel}"`
+          // console.log(H2Posiiton,secondLevel,'secondLevel');
+          this.addDocForm.Content = this.addDocForm.Content.substring(0, H2Posiiton+3) 
+                                    +" "+anchorTextH2 + this.addDocForm.Content.substring(H2RightPosiiton);
+          // 再次获取右闭合标签
+          H2RightPosiiton = this.addDocForm.Content.indexOf('>',H2Posiiton)
+          // 对应的</h2>的位置  原本用的</h2>,后来发现> 和 </h2>之间会掺其他标签
+          backH2Posiiton = this.addDocForm.Content.indexOf('<',H2RightPosiiton)
+          // 获取标题
+          let AnchorTitleLevelTwo = this.addDocForm.Content.substring(H2RightPosiiton+1,backH2Posiiton)
+          this.anchorData[firstLevel-1].Child.push(
+            {AnchorId:`${firstLevel}_${secondLevel}`,
+            Anchor:`doc_anchor_${firstLevel}_${secondLevel}`,
+            AnchorName:AnchorTitleLevelTwo,
+            Child:[]
+          })
+          // nextH1Posiiton 和 secondLevel 随之增加
+          // nextH1Posiiton +=anchorTextH2.length+1
+          // 更新nextH1Posiiton位置
+          nextH1Posiiton = this.addDocForm.Content.indexOf('<h1',backH1Posiiton)==-1?
+                          this.addDocForm.Content.length:this.addDocForm.Content.indexOf('<h1',backH1Posiiton)
+          secondLevel++
+          H2Posiiton = this.addDocForm.Content.indexOf('<h2',backH2Posiiton)
+        }
+        // 结束一轮 <h1></h1>标签的寻找
+        if(this.addDocForm.Content.indexOf('<h1',backH1Posiiton+4)!=-1){
+          // 如果有下一个h1的标签,说明寻找还没结束,继续寻找
+          firstLevel++
+          this.searchTitleTag(nextH1Posiiton,firstLevel)
+        }
+      },
+      previewDocument(){
+        // this.addDocForm.Content=`<p>范德萨发的刚发的</p><p>刚发的g梵蒂冈</p><p>割发代首刚发的</p><hr><h1>1. 个刚发的施工方</h1><p>刚发的刚发的g规范的施工方都是割发代首规范</p><h2>1.1. 规范的三个富士达割发代首</h2><p>个梵蒂冈是梵蒂冈讽德诵功范德萨割发代首个割发代首</p><p>刚分手的割发代首割发代首高富帅d</p><p>刚分手的刚分手的</p><p>割发代首刚分手的</p><p>刚分手的公司发的</p><p>刚发的事故发生的</p><p><br></p><p>割发代首刚分手的刚分手的</p><h2>1.2. 噶规范十多个范德萨刚发的施工方多少公分</h2><p>个讽德诵功范德萨</p><p>割发代首割发代首刚发的s规范的三个</p><h1>2.讽德诵功是反的</h1><p>割发代首割发代首个人的施工方都是</p><p>范德萨个人东方闪电方式</p><p>割发代首割发代首</p><h2>2.1.个梵蒂冈</h2><p>讽德诵功范德萨规范的三个范德萨讽德诵功放大s</p><h2>2.2.刚发的广泛地个</h2><p>刚分手的割发代首</p><p>割发代首割发代首割发代首</p><p><br></p><p>范德萨割发代首</p><h2>2.3.辅导费是的</h2><p>范甘迪个放大割发代首个</p><p>刚发的刚发的</p><h1>3. 个梵蒂冈放大</h1>`
+        if(this.isSubmiting) return 
+        if(!this.addDocForm.Content){
+          this.$message.error("文章内容不能为空")
+          return
+        }
+        let bottomLink = createBottomHref(this.addDocForm.RecommendData)
+        
+        sessionStorage.setItem("documentDoc",this.addDocForm.Content+bottomLink)
+        let { href } = this.$router.resolve({ path: "/assistanceDocDetail" });
+        window.open(href, "_blank");
+      },
+      saveDocument(type){
+        if(this.isSubmiting) return 
+        this.$refs.addDocForm.validate(valid=>{
+          if(valid){
+            if(!this.addDocForm.Content){
+              this.$message.error("文章内容不能为空")
+              return
+            }
+            // console.log(this.addDocForm);
+            this.isSubmiting=true
+            if(type=="发布") this.addDocForm.Status=2
+
+            this.generateAnchor()
+            this.addDocForm.AnchorData = this.anchorData
+            //保存
+            assistanceDocInterence.addAssistanceDoc(this.addDocForm).then(res=>{
+              if(res.Ret == 200){
+                this.$message({
+                  type:'success',
+                  message:'操作成功',
+                  duration:2000
+                })
+                setTimeout(()=>{
+                  this.$router.back()
+                  this.isSubmiting=false
+                },2000)
+              }
+            }).catch(()=>{
+              this.isSubmiting=false
+            })
+          }
+        })
+      }
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+  .assistance-edit-container{
+    display: flex;
+    justify-content: flex-start;
+    .edit-container-rich-text{
+      flex-grow: 1;
+      min-height: calc(100vh - 110px);
+      background-color: white;
+      border:solid 1px #ECECEC;
+      box-sizing: border-box;
+    }
+    .edit-container-document-options{
+      background-color: white;
+      margin-left: 20px;
+      min-height: calc(100vh - 110px);
+      border:solid 1px #ECECEC;
+      box-sizing: border-box;
+      width: 440px;
+      min-width: 440px;
+      .document-options-button-box{
+        width: 100%;
+        height: 80px;
+        box-sizing: border-box;
+        padding: 20px;
+        box-shadow: 0px 5px 10px #ECECEC;
+        border-bottom: solid 1px #ECECEC;
+        .document-options-button{
+          height: 40px;
+          width: 120px;
+        }
+      }
+      .document-options-form{
+        padding: 30px 20px;
+        .form-item-recommendedLink{
+          display: flex;
+          align-items: center;
+          justify-content: flex-start;
+          width: 100%;
+          margin-bottom: 20px;
+          &:last-child{
+            margin-bottom: 0;
+          }
+          .recommendedLink-line{
+            flex: 1;
+            height: 1px;
+            background-color:#DCDFE6 ;
+          }
+        }
+      }
+    }
+  }
+</style>
+<style lang="scss">
+.assistance-edit-container{
+  .fr-toolbar,.fr-box.fr-basic .fr-wrapper{
+    border: none;
+  }
+}
+.fr-popup.fr-active{
+  z-index: 100000!important;
+  opacity: 1!important;
+}
+</style>

+ 45 - 0
src/views/system_manage/assistance_center/assistanceDocDetail.vue

@@ -0,0 +1,45 @@
+<template>
+  <div class="assistance-detail-container">
+    <div class="assistance-detail-box fr-view" v-html="content"></div>
+  </div>
+</template>
+
+<script>
+import {assistanceDocInterence} from '@/api/api.js'
+import {createBottomHref} from './utils/common'
+  export default {
+    name:"assistanceDocDetail",
+    data() {
+      return {
+        content:''
+      }
+    },
+    created(){
+      if(this.$route.query.DocId){
+        assistanceDocInterence.getAssistanceDoc({DocId:this.$route.query.DocId}).then(res=>{
+          if(res.Ret == 200){
+            this.content = res.Data.Content + createBottomHref(res.Data.Recommend || [{Name:"",Url:""},{Name:"",Url:""}])
+          }
+        })
+      }else{
+        this.content = sessionStorage.getItem("documentDoc") || ''
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+.assistance-detail-container{
+  background-color: white;
+  min-height: calc(100vh - 110px);
+  // height: calc(100vh - 110px);
+  padding: 20px;
+  box-sizing: border-box;
+  border: solid 1px #ECECEC;
+  // .assistance-detail-box{
+  //   border: solid 1px #333333;
+  //   height: 100%;
+  //   width: 100%;
+  // }
+}
+</style>

+ 472 - 0
src/views/system_manage/assistance_center/docClassifyManage.vue

@@ -0,0 +1,472 @@
+<!-- 
+    表格树形数据拖拽 本来使用el-table和sortablejs 但是奇怪的判断导致前端无法做跨级拖拽的限制。
+  得由后端来限制,固使用drag-tree-table 但是这个插件构造比较简单,不是用table标签实现的
+  如果产品要实现el-table上面的功能,需要自定义,有更好的方法,还请通知一声。
+ -->
+<template>
+  <div class="doc-classifyMana-container">
+    <div class="doc-classifyMana-top-zone">
+      <el-button type="primary" @click="addClassify">添加分类</el-button>
+      <el-input placeholder="分类名称" v-model="queryParams.KeyWord" @input="getclassifyData" clearable 
+      style="width:500px;margin-left: 20px;">
+        <i slot="prefix" class="el-input__icon el-icon-search"></i>
+      </el-input>
+    </div>
+    <!-- <el-table style="border:1px solid #eaeaea;" ref="classifyTableRef"
+    :data="classifyList" :row-class-name="tableRowClassName" row-key="id" :tree-props="{children:'child'}">
+      <el-table-column prop="text" label="一级分类">
+        <template slot-scope="scope">
+          <span>{{scope.row.level==1?scope.row.text:''}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="text" label="二级分类">
+        <template slot-scope="scope">
+          <span>{{scope.row.level==2?scope.row.text:''}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="text" label="三级分类">
+        <template slot-scope="scope">
+          <span>{{scope.row.level==3?scope.row.text:''}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center">
+        <template slot-scope="scope">
+          <div class="table-button">
+            <span @click="configItem(scope.row)">权限配置</span>
+            <span @click="edititem(scope.row)">编辑</span>
+            <span @click="checkdeleteitem(scope.row)" style="margin-right: 0;color: #F56C6C;">删除</span>
+          </div>
+            </template>
+      </el-table-column>
+    </el-table> -->
+    <dragTreeTable ref="dragTreeTableRef" :beforeDragOver="beforeDrag"
+    :data="treeData" :onDrag="onTreeDataChange"
+    hightRowChange resize border >
+    <!-- onlySameLevelCanDrag -->
+    </dragTreeTable>
+    <!-- 添加分类弹窗 -->
+    <el-dialog :title="dialogTitle" :visible.sync="showAddClassifyDia" width="625px"
+    append-to-body :close-on-click-modal="false" @close="resetForm">
+      <div style="display: flex;flex-direction: column; align-items: center;margin-bottom: 35px;">
+        <el-form :model="classifyForm" ref="classifyFormRef" label-width="80px">
+          <el-form-item label="上级目录" prop="ParentId">
+            <el-cascader v-model="classifyForm.ParentId" :options="noLevelThreeList" @change="selectParentId"
+              placeholder="请选择上级目录(不选默认添加的是一级分类)" ref="parentIdCascaderRef"
+              :props="{ value:'ClassifyId',label:'ClassifyName',children:'Children',checkStrictly:true,emitPath:false,disabled:'Disabled'}" 
+              class="lastCatalogCascader" :disabled="this.dialogTitle.indexOf('编辑分类')!=-1" />
+          </el-form-item>
+          <el-form-item label="分类名称" prop="HelpDocClassifyName" :rules="{required:true,message:'分类名称不能为空',trigger:'blur'}">
+            <el-input v-model="classifyForm.HelpDocClassifyName" placeholder="请输入分类名称" style="width: 337px;"
+             maxlength="10"></el-input>
+          </el-form-item>
+        </el-form>
+        <div style="margin-top: 40px;">
+          <el-button type="primary" style="width:120px;margin-right:10px" @click="classifySave" size="medium">保存</el-button>
+          <el-button  style="width:120px;" @click="showAddClassifyDia=false" size="medium">取消</el-button>
+        </div>
+      </div>
+    </el-dialog>
+    <!-- 设置权限弹窗 -->
+    <el-dialog :title="dialogTitle" :visible.sync="showPermissionDia" width="625px"
+    append-to-body :close-on-click-modal="false" @close="resetPermissonForm">
+      <div style="display: flex;flex-direction: column; align-items: center;margin-bottom: 35px;">
+        <el-form :model="permissionForm" ref="permissionFormRef" label-width="80px">
+          <el-form-item label="可见权限" prop="merchantIds">
+            <el-select v-model="permissionForm.merchantIds" placeholder="请选择商家" 
+            multiple style="width: 337px;" collapse-tags clearable filterable >
+              <el-option :label="item.BusinessName" :value="item.EtaBusinessId" 
+              v-for="item in merchantList" :key="item.merchantId"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-form>
+        <div style="margin-top: 40px;">
+          <el-button type="primary" style="width:120px;margin-right:10px" @click="configSave" size="medium">保存</el-button>
+          <el-button  style="width:120px;" @click="showPermissionDia=false" size="medium">取消</el-button>
+        </div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+// import Sortable from "sortablejs";
+import {assistanceDocInterence,businessCustomInterence} from "@/api/api.js"
+import dragTreeTable from "drag-tree-table";
+  export default {
+    name:"docClassifyManage",
+    components:{dragTreeTable},
+    data() {
+      // 表格头设置
+      this.tableHeadList=[
+        {
+          type:"selection",
+          title: '一级分类',
+          field: 'ClassifyName',
+          flex:1,
+          align: 'center',
+          formatter: (item) => {    
+            return item.Level==1?item.ClassifyName:""
+          }
+        },
+        {
+          title: '二级分类',
+          field: 'ClassifyName',
+          // width: 200,
+          flex:1,
+          align: 'center',
+          formatter: (item) => {
+            return item.Level==2?item.ClassifyName:""
+          }
+        },
+        {
+          title: '三级分类',
+          field: 'ClassifyName',
+          // width: 200,
+          flex:1,
+          align: 'center',
+          formatter: (item) => {
+            return item.Level==3?item.ClassifyName:""
+          }
+        },
+        {
+          type: 'action',
+          title: '操作',
+          width: 260,
+          // flex:1,
+          align: 'center',
+          actions:[
+            {
+              text: '权限配置',
+              onclick: (item) => {
+                // item是当前行的数据
+                this.configClassify(item)
+              },
+              formatter: (item) => {
+                return '<span class="table-button">权限配置</span>'
+              }
+            },
+            {
+              text: '编辑',
+              onclick: (item) => {
+                this.editClassify(item)
+              },
+              formatter: (item) => {
+                return '<span class="table-button">编辑</span>'
+              }
+            },
+            {
+              text: '删除',
+              onclick: (item) => {
+                this.deleteClassify(item)
+              },
+              formatter: (item) => {
+                return '<span class="table-button" style="margin-right: 0;color: #F56C6C;">删除</span>'
+              }
+            }
+          ]
+        }
+      ]
+      // 自定义字段替换
+      this.custom_field={
+        id: 'ClassifyId',
+        order: 'Sort',
+        lists: 'Children',
+        parent_id: 'ParentId'
+      }
+
+      return {
+        queryParams:{
+          KeyWord:''
+        },
+        treeData:{
+          columns:this.tableHeadList,
+          lists:[],
+          custom_field:this.custom_field
+        },
+        // 没有三级分类的分类数组,用于添加
+        noLevelThreeList:[],
+        // // 扁平化之后的数据
+        // classifyListFlat:[],
+        dialogTitle:"",
+        showAddClassifyDia:false,
+        classifyForm:{
+          ParentId:0,
+          HelpDocClassifyName:'',
+          Level:0,
+        },
+        merchantList:[],
+        showPermissionDia:false,
+        permissionForm:{
+          HelpDocClassifyId:0,
+          merchantIds:[]
+        },
+      }
+    },
+    created(){
+      this.getmerchantList()
+      this.getclassifyData()
+    },
+    mounted(){
+      this.$nextTick(()=>{
+        // this.tableDropSet()
+      })
+    },
+    methods: {
+      getmerchantList(){
+        businessCustomInterence.getBusinessList({PageSize:9999999,CurrentIndex:1}).then(res=>{
+          if(res.Ret == 200){
+            this.merchantList = res.Data.List||[]
+          }
+        })
+      },
+      getclassifyData(){
+        assistanceDocInterence.getAssistanceClassifyList(this.queryParams).then(res=>{
+          if(res.Ret == 200){
+            this.treeData.lists = res.Data?res.Data.AllNodes||[]:[]
+            this.noLevelThreeList = res.Data?res.Data.TwoLevelNodes||[]:[]
+            this.treeData.lists.map(list=> {
+              // 一级展开
+              list.open=true
+            })
+            // console.log(this.treeData.lists);
+          }
+        })
+      },
+      // tableRowClassName({row,rowIndex}) {
+      //   if( row.child && row.child.length>0 ){
+      //     return 'has-child-row';
+      //   }else{
+      //     return '';
+      //   }
+      // },
+      beforeDrag(dragItem,effectItem,type){
+        if(type=='center'){
+          // 放里面
+          if((dragItem.Level-1)!=effectItem.Level) return false
+        }else{
+          //不放里面
+          if(dragItem.Level!=effectItem.Level) return false
+        }
+        // return false
+      },
+      onTreeDataChange(list,dragItem){
+        // console.log(list,dragItem,'arguments');
+        // list - 拖拽后的数据 dragItem-拖拽的项
+        let ClassifyId,PrevClassifyId,NextClassifyId,ParentClassifyId=0
+        // 在拖拽后的数据中找到拖拽项对应的位置
+        const findDraggedItem=(list)=>{
+          let itemIndex = list.findIndex(it => it.ClassifyId == dragItem.ClassifyId)
+          if(itemIndex!=-1){
+            if(itemIndex==0){
+              PrevClassifyId=0
+            }else{
+              PrevClassifyId = list[itemIndex-1].ClassifyId
+            }
+            if(itemIndex==(list.length-1)){
+              NextClassifyId=0
+            }else{
+              NextClassifyId = list[itemIndex+1].ClassifyId
+            }
+            ClassifyId = dragItem.ClassifyId
+            ParentClassifyId = dragItem.ParentId
+            console.log({
+              ClassifyId,ParentClassifyId,PrevClassifyId,NextClassifyId
+            });
+            assistanceDocInterence.moveAssistanceClassify({
+              ClassifyId,ParentClassifyId,PrevClassifyId,NextClassifyId
+            }).then(res=>{
+              if(res.Ret == 200){
+                this.$message.success("移动分类成功")
+                this.getclassifyData()
+              }
+            })
+          }else{
+            list.map(li => {
+              li.Children && li.Children.length>0 && findDraggedItem(li.Children)
+            })
+          }
+        }
+        findDraggedItem(list)
+      },
+      // tableDropSet(){
+      //   const tbody = this.$refs.classifyTableRef.$el.querySelector(
+      //     ".el-table__body-wrapper > table > tbody"
+      //   );
+      //   const _this = this;
+      //   Sortable.create(tbody, {
+      //     animation: 150, 
+      //     onStart(evt){
+      //       if(_this.classifyListFlat && _this.classifyListFlat.length>0){
+      //         return 
+      //       }else{
+      //         _this.flatClassifyList(_this.classifyList,0)
+      //       }
+      //       console.log(_this.classifyListFlat);
+      //     },
+      //     onEnd({ newIndex, oldIndex }) {
+      //       console.log({ newIndex, oldIndex });
+      //       if(newIndex == oldIndex) return 
+      //       const oldRow = _this.classifyListFlat[oldIndex]
+      //       const newRow = _this.classifyListFlat[newIndex]
+      //       console.log(oldRow,newRow);
+      //       _this.$message.success("拖拽成功")
+      //       _this.getclassifyData()
+      //     },
+      //     onMove({ dragged, related }){
+      //       console.log(dragged.rowIndex, related.rowIndex);
+      //       const oldRow = _this.classifyListFlat[dragged.rowIndex]
+      //       const newRow = _this.classifyListFlat[related.rowIndex]
+      //       console.log(oldRow.level,newRow.level);
+      //       if (oldRow.level !== newRow.level) {
+      //         return false // 不允许不同级的拖动
+      //       }
+      //     }
+      //   });
+      // },
+      // flatClassifyList(list,parentId){
+      //   for (let i = 0; i < list.length; i++) {
+      //     const element = list[i];
+      //     const lastElementId = i==0?0:list[i-1].id
+      //     const nextElementId = i==(list.length-1)?0:list[i+1].id
+      //     this.classifyListFlat.push({id:element.id,lastElementId,nextElementId,parentId,level:element.level})
+      //     if(element.child && element.child.length>0){
+      //       this.flatClassifyList(element.child,element.id)
+      //     }
+      //   }
+      // },
+      // 添加分类
+      addClassify(){
+        this.dialogTitle="添加分类"
+        this.showAddClassifyDia=true
+      },
+      // 编辑分类
+      editClassify(item){
+        this.classifyForm={
+          ParentId:item.ParentId,
+          HelpDocClassifyId:item.ClassifyId,
+          HelpDocClassifyName:item.ClassifyName
+        }
+        this.dialogTitle="编辑分类"
+        this.showAddClassifyDia=true
+      },
+      selectParentId(value){
+        this.classifyForm.Level = this.$refs.parentIdCascaderRef.getCheckedNodes()[0].data.Level
+      },
+      deleteClassify(item){
+        this.$confirm('是否确认删除?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        }).then(() => {
+          assistanceDocInterence.deleteAssistanceClassify({ClassifyId:item.ClassifyId}).then(res=>{
+            if(res.Ret == 200){
+              this.$message.success("删除分类成功")
+              this.getclassifyData()
+            }
+          })
+        }).catch(()=>{})
+      },
+      // 保存
+      classifySave(){
+        this.$refs.classifyFormRef.validate(valid=>{
+          if(valid){
+            console.log(this.classifyForm);
+            if(this.classifyForm.HelpDocClassifyId){
+              //编辑
+              assistanceDocInterence.editAssistanceClassify(this.classifyForm).then(res=>{
+                if(res.Ret == 200){
+                  this.$message.success(this.dialogTitle+"成功")
+                  this.showAddClassifyDia=false
+                  this.resetForm()
+                  this.getclassifyData()
+                }
+              })
+            }else{
+              //新增
+              assistanceDocInterence.addAssistanceClassify({...this.classifyForm}).then(res=>{
+                if(res.Ret == 200){
+                  this.$message.success(this.dialogTitle+"成功")
+                  this.showAddClassifyDia=false
+                  this.resetForm()
+                  this.getclassifyData()
+                }
+              })
+            }
+          }
+        })
+      },
+      resetForm(){
+        this.classifyForm={
+          ParentId:0,
+          HelpDocClassifyName:'',
+          Level:0
+        }
+        this.$refs.classifyFormRef.clearValidate()
+      },
+      //权限配置
+      configClassify(row){
+        this.permissionForm={
+          HelpDocClassifyId:row.ClassifyId,
+          merchantIds:row.VisibleBusinessIds?row.VisibleBusinessIds.split(',').map(element => {
+            return parseInt(element)
+          }):[]
+        }
+        // console.log(this.permissionForm.merchantIds);
+        this.dialogTitle="设置权限"
+        this.showPermissionDia=true
+      },
+      resetPermissonForm(){
+        this.permissionForm={
+          HelpDocClassifyId:0,
+          merchantIds:[]
+        }
+        this.$refs.permissionFormRef.clearValidate()
+      },
+      configSave(){
+        assistanceDocInterence.editAssistanceClassifyVisible({
+          HelpDocClassifyId:this.permissionForm.HelpDocClassifyId,
+          VisibleBusinessIds:this.permissionForm.merchantIds.join(',')
+        }).then(res=>{
+          if(res.Ret == 200){
+            this.$message.success("设置成功")
+            this.showPermissionDia=false
+            this.resetPermissonForm()
+            this.getclassifyData()
+          }
+        })
+      }
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+.doc-classifyMana-container{
+  background-color: white;
+  min-height: calc(100vh - 110px);
+  padding: 30px;
+  box-sizing: border-box;
+  border: solid 1px #ECECEC;
+  .doc-classifyMana-top-zone{
+    display: flex;
+    align-items: flex-start;
+    justify-content: space-between;
+    margin-bottom: 20px;
+  }
+}
+</style>
+<style lang="scss">
+.lastCatalogCascader{
+  width: 337px;
+  .el-input{
+    width: 337px;
+  }
+}
+.has-child-row {
+    background-color: #f2f6fa!important;
+}
+.table-button{
+    color:#4099ef; 
+    cursor: pointer;
+    margin-right: 10px;
+  }
+</style>

+ 10 - 0
src/views/system_manage/assistance_center/utils/common.js

@@ -0,0 +1,10 @@
+// 生成底部的两个链接
+export function createBottomHref(RecommendData){
+  let hrefStringBuiler='<ul style="margin-top:40px">'
+  RecommendData.map(item =>{
+    if(item.Name){
+      hrefStringBuiler+=`<li><a href="${item.Url}" target="_blank" style="text-decoration: underline;">${item.Name}</a></li>`
+    }
+  })
+  return hrefStringBuiler+"</ul>"
+}

+ 136 - 0
src/views/system_manage/components/logSetDialog.vue

@@ -0,0 +1,136 @@
+<template>
+    <el-dialog
+        :visible.sync="isLogSetShow"
+        :close-on-click-modal="false"
+        :modal-append-to-body='false'
+        title="添加日志"
+        @close="closeDia"
+        width="820px"
+        v-dialogDrag
+        center
+    >
+        <div class="log-set-wrap">
+            <el-form :model="formData" :rules="rules" inline label-width="80px" ref="logForm">
+                <el-form-item label="版本号" prop="Version">
+                    <el-input v-model="formData.Version" placeholder="请输入版本号" style="width:100%"></el-input>
+                </el-form-item>
+                <el-form-item label="更新内容" prop="Content" class="update-text">
+                    <div class="rich-editor-wrap">
+                        <froala :id="`log-editor`"
+                            :ref="`logEditor`" 
+                            :tag="'textarea'" 
+                            :config="richEditorConfig" v-model="formData.Content">
+                        </froala>
+                    </div>
+                </el-form-item>
+                <el-form-item label="更新日期" prop="UpdateDate">
+                    <el-date-picker
+                        v-model="formData.UpdateDate"
+                        type="date"
+                        value-format="yyyy-MM-dd"
+                        placeholder="选择日期">
+                    </el-date-picker>
+                </el-form-item>
+            </el-form>
+            <div class="btn-wrap" style="text-align: center;margin-bottom: 25px;">
+                <el-button type="primary" plain style="width:200px;" @click="closeDia">取消</el-button>
+                <el-button type="primary"  style="margin-left:50px;width:200px;" @click="saveLog">保存</el-button>
+            </div>
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+export default {
+    props:{
+        isLogSetShow:{
+            type:Boolean,
+            default:false
+        },
+        logInfo:{
+            type:Object,
+            default:()=>{ return {}}
+        }
+        
+    },
+    watch:{
+        isLogSetShow(newVal){
+            if(newVal){
+                this.logInfo.Version
+                ?(this.formData = _.cloneDeep(this.logInfo))
+                :(this.formData = {Content:'',UpdateDate:this.$moment(new Date()).format('yyyy-MM-DD')})
+            }
+        }
+    },
+    data() {
+        return {
+            value1:'',
+            formData:{},
+            rules:{
+                Version:[{ required: true, message: '请输入版本号', trigger: 'blur' }],
+                Content:[{ required: true, message: '请输入更新内容', trigger: 'blur' }],
+                UpdateDate:[{ required: true, message: '请选择更新日期', trigger: 'blur' }]
+            },
+            richEditorConfig:{
+                toolbarButtons:[
+                    'textColor',
+                    'bold',
+                    'italic',
+                    'underline',
+                    'fontFamily',
+                    'fontSize',
+                    'align',
+                    'outdent',
+                    'indent',
+                    'specialCharacters',
+                    'insertHR',
+                    'selectAll',
+                    'clearFormatting',
+                    'undo',
+                    'redo',
+                ],
+                height:220,
+                fontSizeDefaultSelection: "16",
+                quickInsertEnabled: false,
+                pasteAllowedStyleProps: ['font-family', 'font-size', 'color'],
+                language: "zh_cn",
+                placeholderText:'请输入更新内容',
+                wordPasteKeepFormatting:false,
+                pastePlain:true,
+                wordPasteModal:false,
+                pluginsEnabled:['colors'],//定义可用插件
+            },//富文本编辑器配置项
+        };
+    },
+    methods: {
+        closeDia(){
+            this.$emit('close')
+        },
+        saveLog(){
+            this.formData.Content = this.formData.Content.replace(/<p data-f-id=\"pbf\".*?<\/p>/g, "");
+            this.$refs.logForm.validate((valid)=>{
+                if(valid){
+                    this.$emit('saveLog',this.formData)
+                }
+            })
+            
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+.log-set-wrap{
+    .el-form{
+        .el-form-item.update-text{
+            display: flex;
+            .el-form-item__content{
+                flex:1;
+            }
+        }
+    }
+}
+</style>
+<style scoped lang="scss">
+
+</style>

+ 175 - 0
src/views/system_manage/updateLogManage.vue

@@ -0,0 +1,175 @@
+<template>
+    <div class="update-log-manage-wrap">
+        <div class="top-wrap">
+            <el-button type="primary" @click="isLogSetShow=true">添加日志</el-button>
+            <!-- <el-date-picker
+                v-model="timeRange"
+                type="daterange"
+                clearable
+                value-format="yyyy-MM-dd"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期">
+            </el-date-picker> -->
+            <el-input v-model="searchText" @input="getTableData"
+                prefix-icon="el-icon-search" placeholder="输入更新内容检索" clearable></el-input>
+        </div>
+        <div class="table-wrap">
+            <el-table :data="tableData" 
+            @sort-change="sortChangeHandle" border>
+                <el-table-column 
+                    v-for="item in tableColumns" :key="item.key"
+                    :label="item.label" :sortable="item.sort" 
+                    align="center"
+                    >
+
+                    <template slot-scope="{row}">
+                        <div v-if="item.key==='Content'" v-html="row[item.key]"></div>
+                        <span v-else>{{ row[item.key] }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="操作" align="center">
+                    <template slot-scope="{row}">
+                        <el-button type="text" @click="handleEditLog(row)">编辑</el-button>
+                        <el-button type="text" style="color: red;" @click="handleDeleteLog(row)">删除</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+            <el-pagination 
+                layout="prev,pager,next,total" 
+                background
+                :current-page="pageNo"
+                @current-change="currentChange"
+                :page-size="pageSize" 
+                :total="total"
+                >
+            </el-pagination>
+        </div>
+        <LogSetDialog 
+            :isLogSetShow="isLogSetShow"
+            :logInfo="logInfo"
+            @saveLog="saveLog"
+            @close="()=>{logInfo = {};isLogSetShow = false}"
+        />
+    </div>
+</template>
+
+<script>
+import LogSetDialog from './components/logSetDialog.vue';
+import {updateLogInterface} from '@/api/modules/updateLogApi';
+export default {
+    components: { LogSetDialog },
+    data() {
+        return {
+            /* select */
+            timeRange: null,
+            searchText: '',
+            /* dialog */
+            logInfo:{},
+            isLogSetShow:false,
+            /* table */
+            tableData: [],
+            tableColumns: [
+                {
+                    label: '更新内容',
+                    key: 'Content'
+                },
+                {
+                    label: '版本号',
+                    key: 'Version'
+                },
+                {
+                    label: '更新日期',
+                    key: 'UpdateDate',
+                    sort:true
+                },
+            ],
+            pageNo: 1,
+            pageSize: 10,
+            total: 0,
+            sortType:0,
+        };
+    },
+    methods: {
+        getTableData(){
+            updateLogInterface.getLogList({
+                Keyword:this.searchText,
+                SortType:this.sortType,
+                CurrentIndex:this.pageNo,
+                PageSize:this.pageSize
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.tableData = res.Data.List||[]
+                this.total = res.Data.Paging.Totals
+            })
+        },
+        currentChange(page) {
+            this.pageNo = page;
+            this.getTableData()
+        },
+        sortChangeHandle(params){
+            this.sortType = params.order === 'ascending' ? 1 :params.order === 'descending' ? 2 : 0
+            this.pageNo = 1
+            this.getTableData()
+        },
+        handleEditLog(row){
+            this.logInfo = row
+            this.isLogSetShow = true
+        },
+        handleDeleteLog(row){
+            //二次确认
+            this.$confirm('删除操作不可恢复,确认删除吗?','提示',{
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+            }).then(() => {
+                updateLogInterface.deleteLogData({Id:row.Id}).then(res=>{
+                    if(res.Ret!==200) return
+                    this.$message.success('删除成功')
+                    this.getTableData()
+                })
+            }).catch(() => {});
+        },
+        async saveLog(form){
+            const res = form.Id
+                        ?await updateLogInterface.editLogData(form)
+                        :await updateLogInterface.addLogData(form)
+            if(res.Ret!==200) return 
+            this.$message.success(`${form.Id?'编辑':'添加'}成功`)
+            this.getTableData()
+            this.isLogSetShow = false
+        }
+    },
+    mounted(){
+        this.getTableData()
+    }
+    
+};
+</script>
+
+<style scoped lang="scss">
+.update-log-manage-wrap{
+    padding:30px;
+    background-color: #fff;
+    border-radius: 4px;
+    .top-wrap{
+        display: flex;
+        justify-content: space-between;
+        .el-date-editor{
+            margin-left: auto;
+        }
+        .el-input{
+            margin-left:30px;
+            width:420px;
+        }
+    }
+    .table-wrap{
+        margin-top: 30px;
+        .el-pagination{
+            margin-top: 30px;
+            text-align: right;
+        }
+    }
+
+}
+</style>