Browse Source

merge 11.3

bding 1 year ago
parent
commit
120205619a
51 changed files with 5309 additions and 138 deletions
  1. 1 1
      index.html
  2. 2 0
      package.json
  3. 9 1
      src/api/api.js
  4. 105 0
      src/api/modules/assistanceDoc.js
  5. 125 0
      src/api/modules/businessCustom.js
  6. 30 2
      src/api/modules/crmApi.js
  7. 4 0
      src/api/modules/rai/pointsApi.js
  8. 4 0
      src/api/modules/rai/raiApi.js
  9. 42 0
      src/api/modules/updateLogApi.js
  10. 2 0
      src/main.js
  11. 56 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. 458 0
      src/views/business_ETA_manage/addBusiness.vue
  17. 201 0
      src/views/business_ETA_manage/businessAuth.vue
  18. 359 0
      src/views/business_ETA_manage/businessDetail.vue
  19. 391 0
      src/views/business_ETA_manage/businessEdit.vue
  20. 500 0
      src/views/business_ETA_manage/businessList.vue
  21. 77 0
      src/views/business_ETA_manage/components/AddRenewal.vue
  22. 95 0
      src/views/business_ETA_manage/components/ModifySaller.vue
  23. 106 0
      src/views/business_ETA_manage/components/Steps.vue
  24. 22 6
      src/views/custom_manage/customList/components/deductDetailDlg.vue
  25. 29 1
      src/views/custom_manage/customList/components/shareListDialog.vue
  26. 147 0
      src/views/custom_manage/customList/customCityList.vue
  27. 11 4
      src/views/custom_manage/customList/customDetail.vue
  28. 12 2
      src/views/custom_manage/customList/customList.vue
  29. 1 1
      src/views/custom_manage/customList/customListEn.vue
  30. 4 1
      src/views/custom_manage/customList/customShareList.vue
  31. 14 2
      src/views/custom_manage/customList/limitContactListEn.vue
  32. 135 35
      src/views/ficc_manage/userApplication.vue
  33. 70 52
      src/views/rai_manage/activityManage/activityManage.vue
  34. 20 9
      src/views/rai_manage/activityManage/applyManage.vue
  35. 24 5
      src/views/rai_manage/activityManage/components/addActivity.vue
  36. 6 0
      src/views/rai_manage/activityManage/components/addComopnents/ResearchDeduct.vue
  37. 124 0
      src/views/rai_manage/activityManage/components/imgMeeting.vue
  38. 519 0
      src/views/rai_manage/activityManage/meetingManagement.vue
  39. 1 0
      src/views/rai_manage/components/addChoiceness.vue
  40. 20 0
      src/views/rai_manage/components/apply/applyTableColums.js
  41. 13 3
      src/views/rai_manage/cygxManage/applyUserList.vue
  42. 1 0
      src/views/roadshow_manage/statistics/index.scss
  43. 1 1
      src/views/roadshow_manage/statistics/researcher.vue
  44. 209 0
      src/views/system_manage/assistance_center/assistanceCenter.vue
  45. 369 0
      src/views/system_manage/assistance_center/assistanceDocAdd.vue
  46. 45 0
      src/views/system_manage/assistance_center/assistanceDocDetail.vue
  47. 472 0
      src/views/system_manage/assistance_center/docClassifyManage.vue
  48. 10 0
      src/views/system_manage/assistance_center/utils/common.js
  49. 136 0
      src/views/system_manage/components/logSetDialog.vue
  50. 175 0
      src/views/system_manage/updateLogManage.vue
  51. BIN
      static/fa.png

+ 1 - 1
index.html

@@ -12,7 +12,7 @@
 	<!-- <link rel="stylesheet" href="https://unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css" /> -->
 	<!--<link rel="stylesheet" href="./static/css/reset.min.css">-->
 	<link rel="stylesheet" href="./static/css/iconfont.css"/>
-	<link rel="icon" type="image/x-icon" href="./static/fa.ico" id="icon"/>
+	<link rel="icon" type="image/png" href="./static/fa.png" id="icon"/>
 	<script src="./static/js/vue.js"></script>  <!-- 开发版,开发过程中使用此方案-->
 	<script src="./static/js/main.js"></script>  <!-- 生产版,打包的时候使用此方案 -->
 	<!-- 引入组件库 -->

+ 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",

+ 9 - 1
src/api/api.js

@@ -70,6 +70,12 @@ import {businessTripInterence} from './modules/businessTrip'
 
 import {reportVarietyENInterence} from './modules/reportVariety'
 
+//商家管理
+import {businessCustomInterence} from './modules/businessCustom'
+
+//帮助中心
+import {assistanceDocInterence} from './modules/assistanceDoc'
+
 export {
   dataBaseInterface,
   mychartInterface,
@@ -106,7 +112,9 @@ export {
   nationalInterface,
   cloudDiskInterface,
   businessTripInterence,
-  reportVarietyENInterence
+  reportVarietyENInterence,
+  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)
+    },
+}

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

@@ -0,0 +1,125 @@
+/**
+ * 商家管理api
+ */
+import http from "@/api/http.js"
+
+export const businessCustomInterence = {
+    /**
+     * 获取商家列表
+     * @param Keyword String关键字
+     * @param SellerIds String 销售ID(多选),英文逗号拼接
+     * @param SigningStatus Integer 签约状态: 1-首次签约; 2-续约中; 3-已终止
+     * @param Province String 省份(多选),英文逗号拼接
+     * @param City String 城市(多选),英文逗号拼接
+     * @param SortParam Integer 排序字段: 1-签约时间; 2-到期时间; 3-创建时间; 4-用户上限
+     * @param SortType Integer 排序类型: 1-正序; 2-倒序
+     * @param PageSize Integer 每页数据量
+     * @param CurrentIndex Integer 页码
+     * @returns 
+     */
+    getBusinessList:(params)=>{
+        return http.get('/eta_business/page_list',params)
+    },
+    /**
+     * 获取商家签约列表
+     * @param EtaBusinessId Integer 商家ID
+     */
+    getContractList:(params)=>{
+        return http.get('/eta_business/contract_list',params)
+    },
+    /**
+     * 获取操作日志列表
+     * @param EtaBusinessId Integer 商家ID
+     */
+    getTimeLineList:(params)=>{
+        return http.get('/eta_business/operate_record_list',params)
+    },
+    /**
+     * 获取商家详情
+     * @param EtaBusinessId Integer 商家ID
+     */
+    getBusinessDetail:(params)=>{
+        return http.get('/eta_business/detail',params)
+    },
+    /**
+     * 添加续约
+     * @param EtaBusinessId Integer 商家ID
+     * @param SigningTime String 签约时间
+     * @param ExpiredTime String 到期时间
+     * @returns 
+     */
+    addNewContract:(params)=>{
+        return http.post('/eta_business/signing',params)
+    },
+    /**
+     * 修改销售
+     * @param EtaBusinessId Integer 商家ID
+     * @param SellerId Integer 销售ID
+     * @param SellerName String 销售名称
+     */
+    changeBusinessSeller:(params)=>{
+        return http.post('/eta_business/move_seller',params)
+    },
+    /**
+     * 启用禁用商家
+     * @param EtaBusinessId Integer 商家ID
+     */
+    changeBusinessStatus:(params)=>{
+        return http.post('/eta_business/enable',params)
+    },
+    /**
+     * 编辑商家
+     * @param EtaBusinessId Integer 商家ID
+     * @param Province String 省份
+     * @param City String 城市
+     * @param Leader String 决策人姓名
+     * @param IndustryId Integer 行业ID
+     * @param IndustryName String 行业名称
+     * @param CapitalScale String 资金规模
+     * @param ResearchTeamSize String 研究团队规模
+     * @param UserMax Integer 用户上限
+     */
+    editBusiness:(params)=>{
+        return http.post('/eta_business/edit',params)
+    },
+    /**
+     * 添加商家
+     * @param BusinessName String 商家名称
+     * @param CreditCode String 社会信用码
+     * @param RegionType String 所属区域:国内;海外
+     * @param Province String 省份
+     * @param City String 城市
+     * @param SellerId Integer 销售ID
+     * @param SellerName String 销售姓名
+     * @param Leader String 决策人姓名
+     * @param IndustryId Integer 行业ID
+     * @param IndustryName String 行业名称
+     * @param CapitalScale String 资金规模
+     * @param ResearchTeamSize String 研究团队规模
+     * @param UserMax Integer 用户上限
+     * @param SigningTime String 签约时间(IsCheck为false时必填)
+     * @param ExpiredTime String 到期时间(IsCheck为false时必填)
+     * @param IsCheck Boolean 是否仅校验,为true时校验参数但不实际新增
+     * @returns 
+     */
+    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)
+    }
+}

+ 30 - 2
src/api/modules/crmApi.js

@@ -289,15 +289,29 @@ const customInterence = {
   },
   /* 获取试用用户列表 */
   trialList: (params) => {
-    console.log(params);
     return http.get("/custom/official/user/list", params);
     // return http.get('/api/adminapi/custom/official/user/list?PageSize=10&CurrentIndex=1&SourceType=中文官网', params)
   },
   /* 试用用户确认已处理接口 */
   trialStatus: (params) => {
-    console.log(params);
     return http.post("/custom/official/user/confirm", params);
   },
+  /* 标记研报申请分组
+    ApplyRecordId
+    GroupName
+    UserId
+   */
+  markApplyUser:(params)=>{
+      return http.post('/yb/apply_record/mark_group',params)
+  },
+  /**
+   * 标记官网试用申请
+   * Id
+   * GroupName
+   */
+  markOfficialUser:(params)=>{
+      return http.post('/custom/official/user/mark_group',params)
+  },
   /* 搜索公司 KeyWord  */
   companySearch: (params) => {
     return http.get("/custom/potential/company/search", params);
@@ -519,6 +533,20 @@ const customInterence = {
     deleteRemark:(params)=>{
         return http.post("/custom/remark/del",params)
     },
+    /*
+     * 标记服务记录
+     * CompanyServiceRecordId
+     * Status 0取消标记 1标记
+     */
+    markRecord:(params)=>{
+        return http.post('/custom/share/mark',params)
+    },
+    /**
+     * 同城客户列表
+     */
+    getCustomCityList:(params)=>{
+        return http.get('/custom/share/list/city',params)
+    },
   /* 审批列表
 		PageSize *
 		CurrentIndex *

+ 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);
+  },
 };
 
 /* 权益小程序管理 专项调研模块*/

+ 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';

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

@@ -33,6 +33,16 @@ export default [
         name: "正式客户共享",
         hidden: false,
       },
+      {
+        path: 'customCityList',
+        component: () => import('@/views/custom_manage/customList/customCityList.vue'),
+        name: '查看同城客户',
+        hidden: false,
+        meta: {
+            pathFrom: 'customShareList',
+            pathName: '正式客户共享'
+        }
+      },
       {
         path: "customAllList",
         component: () => import("@/views/custom_manage/customList/customAllList.vue"),
@@ -370,6 +380,52 @@ export default [
 				component: () => import('@/views/ficc_manage/apply/applyList.vue'),
 				hidden: false,
 			},
+      {
+        path:'businessETAList',
+        name:"商家管理",
+        component: () => import('@/views/business_ETA_manage/businessList.vue'),
+				hidden: false,
+      },
+      {
+        path:'addETABusiness',
+        name:"新增商家",
+        component: () => import('@/views/business_ETA_manage/addBusiness.vue'),
+				hidden: false,
+        meta:{
+          pathFrom: "businessETAList",
+          pathName: "商家管理",
+        }
+      },
+      {
+        path:'editETABusiness',
+        name:"编辑商家",
+        component: () => import('@/views/business_ETA_manage/businessEdit.vue'),
+				hidden: false,
+        meta:{
+          pathFrom: "businessETAList",
+          pathName: "商家管理",
+        }
+      },
+      {
+        path:'businessETADetail',
+        name:"商家详情",
+        component: () => import('@/views/business_ETA_manage/businessDetail.vue'),
+				hidden: false,
+        meta:{
+          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>

+ 458 - 0
src/views/business_ETA_manage/addBusiness.vue

@@ -0,0 +1,458 @@
+<template>
+    <div class="add-business">
+        <!-- 自定义步骤条 -->
+        <Steps 
+            :activeStep="step"
+            :allowStepClick="false"
+        />
+        <div class="first-step-form-wrap" v-show="step===1">
+            <el-form 
+                :model="firstFormData" 
+                :rules="rules"
+                ref="firstFormEl" 
+                label-width="120px"
+                inline
+                class="first-step-form"
+            >
+                <div class="form-line">
+                    <el-form-item label="所属区域" prop="areaType">
+                        <el-radio-group v-model="firstFormData.areaType">
+                            <el-radio label="国内" border>国内</el-radio>
+                            <el-radio label="海外" border>海外</el-radio>
+                        </el-radio-group>
+                    </el-form-item>
+                    <el-form-item label="商家名称" prop="name">
+                        <autocomplete
+                            ref="auto"
+                            v-model="firstFormData.name"
+                            :fetch-suggestions="callbackHandle"
+                            placeholder="请输入商家名称"
+                            @blur="checkCompany"
+                            @select="customNameSelect"
+                            @focus="checkCompanyfocus"
+                            :disabled='inquireSuccess'
+                            clearable
+                            value-key="value"
+                            style="width:360px"
+                            :popper-class="isCheck?'el-autocomplete-none':'el-autocomplete-suggestion-data-entry'"
+                            class="autocomplete-input"
+                        >
+                            <span 
+                                v-if="firstFormData.name.length > 3" 
+                                style="color:#409EFF;cursor: pointer;" slot="suffix"  
+                                @click="$refs.auto.search(firstFormData.name)"
+                            > 查询</span>
+                            <template slot-scope="scope">
+                                <div v-if="scope.item.KeyNo">{{scope.item.Name}}</div>
+                                <div v-else style="text-align:center">暂无数据</div>		 
+                            </template>
+                        </autocomplete>
+                        <!-- <el-input placeholder="请输入商家名称" v-model="firstFormData.name"/> -->
+                    </el-form-item>
+                </div>
+                <div class="form-line">
+                    <el-form-item label="社会信用码" prop="creditCode">
+                        <el-input disabled placeholder="请输入社会信用码" v-model="firstFormData.creditCode"/>
+                    </el-form-item>
+                    <el-form-item label="商家地址" prop="address">
+                        <el-cascader 
+                            v-model="firstFormData.address"
+                            :props="locationProps"
+                            clearable 
+                            :options="locationOptions"  
+                            @change="selectRegion" 
+                            placeholder="请选择客户地址" 
+                        />
+                    </el-form-item>
+                </div>
+                <div class="form-line">
+                    <el-form-item label="决策人" prop="decisionMaker">
+                        <el-input placeholder="请输入决策人" v-model="firstFormData.decisionMaker"/>
+                    </el-form-item>
+                    <el-form-item label="研究团队规模" prop="teamSize">
+                        <el-select 
+                            v-model="firstFormData.teamSize" 
+                            placeholder="请选择研究团队规模"
+                            clearable
+                        >
+                            <el-option
+                                v-for="item in teamSizeOpts"
+                                :key="item.val"
+                                :label="item.label"
+                                :value="item.val">
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                </div>
+                <div class="form-line">
+                    <el-form-item label="资金规模" prop="fundsize">
+                        <el-input placeholder="请输入资金规模" v-model="firstFormData.fundsize"/>
+                    </el-form-item>
+                    <el-form-item label="所属行业" prop="industry">
+                        <el-select 
+                            v-model="firstFormData.industry" 
+                            placeholder="请选择行业" 
+                            clearable
+                        >
+                            <el-option
+                                v-for="item in tradeArr"
+                                :key="item.IndustryId"
+                                :label="item.IndustryName"
+                                :value="item.IndustryId">
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                </div>
+                <div class="form-line">
+                    <el-form-item label="用户上限" prop="userMax">
+                        <el-input type="number" placeholder="请输入用户上限" v-model="firstFormData.userMax"/>
+                    </el-form-item>
+                    <el-form-item label="所属销售" prop="saller">
+                        <el-cascader
+                            ref="cascader"
+                            v-model="firstFormData.saller"
+                            :options="salesArr"
+                            :show-all-levels="false"
+                            :props="{
+                                expandTrigger: 'hover',
+                                children: 'Child',
+                                emitPath: false,
+                                label:'AdminName',
+                                value:'AdminId',
+                            }"
+                            filterable
+                            clearable
+                            placeholder="请选择销售"
+                        />
+                    </el-form-item>
+                </div>
+                
+            </el-form>
+        </div>
+        <div class="second-step-form-wrap" v-show="step===2">
+            <el-form 
+                :model="secondFormData" 
+                :rules="rules"
+                ref="secondFormEl" 
+                label-width="120px"
+                inline
+                class="second-step-form"
+            >
+                <div class="form-line">
+                    <el-form-item label="签约日期" prop="signDate">
+                        <el-date-picker
+                            v-model="secondFormData.signDate"
+                            type="date"
+                            placeholder="选择日期"
+                            value-format="yyyy-MM-dd"
+                        />
+                    </el-form-item>
+                    <el-form-item label="到期日期" prop="expirationDate">
+                        <el-date-picker
+                            v-model="secondFormData.expirationDate"
+                            type="date"
+                            placeholder="选择日期"
+                            value-format="yyyy-MM-dd"
+                        />
+                    </el-form-item>
+                </div>
+                
+            </el-form>
+        </div>
+
+        <div class="btns-box">
+            <el-button style="width:80px" type="primary" v-show="step===1" @click="handleStepSecond">下一步</el-button>
+            <el-button style="width:80px" type="primary" v-show="step===1" plain @click="$router.back()">取消</el-button>
+            <el-button style="width:80px" type="primary" v-show="step===2" plain @click="step--">上一步</el-button>
+            <el-button style="width:80px" type="primary" v-show="step===2" @click="handleAddBusiness">保存</el-button>
+        </div>
+    </div>
+</template>
+
+<script>
+import { customInterence,roadshowInterence,businessCustomInterence } from '@/api/api.js'
+import autocomplete from "@/components/autocomplete.vue";
+import Steps from "./components/Steps.vue";
+import {locationOptions} from "@/views/custom_manage/customList/location"
+export default {
+    components: {autocomplete,Steps},
+    data() {
+        return {
+            /* 城市地址数据 */
+            locationOptions,
+            locationProps:{
+                value:'name',
+                children:'city',
+                label:'name'
+            },
+
+            /* 自动输入社会信用码 */
+            isCheckCompanyInfo:false, 
+			checkCompanyfocusIs:false,
+			inquireSuccess:false,
+            nameRepeat:false,
+			codeRepeat:false,
+            isCheck:false,//检查客户弹窗
+			repeatId:'',//重复公司id
+			repeatName:'',//重复公司类型
+
+            salesArr:[],//销售员数据
+            tradeArr:[],//行业数据
+            step:1,//第几步
+
+            /* 研究团队规模数据 */
+            teamSizeOpts:[
+                {
+                    val:'50人及以下',
+                    label:'50人及以下'
+                },
+                {
+                    val:'200人及以下',
+                    label:'200人及以下'
+                },
+                {
+                    val:'超过200人',
+                    label:'超过200人'
+                }
+            ],
+            
+            rules:{
+                areaType:[{ required: true, message: '请选择所属区域', trigger: 'change' },],
+                name:[{ required: true, message: '请输入商家名称', trigger: 'blur' },],
+                creditCode:[{ required: true, message: '请输入社会信用码', trigger: 'blur' },],
+                address:[{ required: true, message: '请选择商家地址', trigger: 'change' },],
+                decisionMaker:[{required: true, message: '请输入决策人', trigger: 'blur' },],
+                teamSize:[{required: true, message: '请选择研究团队规模', trigger: 'change' },],
+                industry:[{required: true, message: '请选择所属行业', trigger: 'change' },],
+                userMax:[{required: true, message: '请输入用户上限', trigger: 'blur' },],
+                signDate:[{required: true, message: '请选择签署日期', trigger: 'change' },],
+                expirationDate:[{required: true, message: '请选择签署日期', trigger: 'change' },],
+                saller:[{required: true, message: '请选择所属销售', trigger: 'change' },],
+            },
+
+            /* 表单初始值 */
+            firstFormData:{
+                areaType:'国内',
+                name:'',
+                creditCode:'',
+                address:'',
+                decisionMaker:'',
+                teamSize:'',
+                fundsize:'',
+                industry:'',
+                userMax:'',
+                saller:''
+            },
+            secondFormData:{
+                signDate:'',
+                expirationDate:''
+            }
+        }
+    },
+    watch:{
+        'firstFormData.areaType':{
+            handler(newVal){
+                console.log('watch?',newVal)
+                if(newVal==='海外'){
+                    this.firstFormData.creditCode = 'HZ' + new Date().getTime()
+                    this.firstFormData.address = ['海外','其他市']
+                    this.selectRegion(['海外','其他市'])
+                }else{
+                    this.firstFormData.creditCode = ''
+                    this.firstFormData.address = []
+                }
+            }
+        }
+    },
+    created() {
+        this.getIndustry()
+        this.getSale()
+    },
+    methods: {
+        normalizingParams(params){
+            const cascaderNodes = this.$refs.cascader.getCheckedNodes({leafOnly:true})
+            const IndustryName = this.tradeArr.find(item=>item.IndustryId===params.industry).IndustryName
+            return {
+                BusinessName:params.name,
+                CreditCode:params.creditCode,
+                RegionType:params.areaType,
+                Province:params.province,
+                City:params.city,
+                SellerId:Number(cascaderNodes[0]?cascaderNodes[0].value:0),
+                SellerName:cascaderNodes[0]?cascaderNodes[0].label:'',
+                Leader:params.decisionMaker,
+                IndustryId:Number(params.industry),
+                IndustryName:IndustryName,
+                CapitalScale:params.fundsize,
+                ResearchTeamSize:params.teamSize,
+                UserMax:Number(params.userMax),
+                SigningTime:params.signDate||'',
+                ExpiredTime:params.expirationDate||''
+            }
+        },
+        //跳转到第二步
+        handleStepSecond(){
+            this.$refs.firstFormEl.validate((valid)=>{
+                if(valid){
+                    const params = this.normalizingParams(this.firstFormData)
+                    businessCustomInterence.addBusiness({
+                        IsCheck:true,
+                        ...params
+                    }).then(res=>{
+                        if(res.Ret!==200) return 
+                        this.step++
+                    })
+                    
+                }
+            })
+        },
+        //保存商家
+        handleAddBusiness(){
+            this.$refs.secondFormEl.validate((valid)=>{
+                if(valid){
+                    const params = this.normalizingParams({...this.firstFormData,...this.secondFormData})
+                    businessCustomInterence.addBusiness({
+                        IsCheck:false,
+                        ...params
+                    }).then(res=>{
+                        if(res.Ret!==200) return 
+                        this.$message.success('添加成功')
+                        this.$router.push('/businessETAList')
+                    })
+                }
+            })
+        },
+
+        async callbackHandle(data,cb) {
+            if (data) {
+                this.isCheckCompanyInfo =true
+                cb([]);
+                let res = await customInterence.companyQccSearch({ KeyWord: data});
+                if (res.Ret === 200) {
+                    this.isCheckCompanyInfo =false;
+                    if (res.Data && res.Data.length > 0) {
+                        let arr = res.Data.map((item) => {
+                            return { value:item.Name, ...item };
+                        });
+                        cb(arr);
+                    }else{
+                        cb([{}]);
+                        // this.checkCompany()
+                    }	
+                }	
+            }
+		},
+
+        checkCompanyfocus(){
+			this.checkCompanyfocusIs =true;
+			setTimeout(() => {
+			    this.checkCompanyfocusIs =false;
+			},500)
+		},
+
+        //选中后增加社会信用码
+		customNameSelect(value) {
+			this.firstFormData.creditCode = value.CreditCode
+			//this.inquireSuccess = true;
+			setTimeout(async()=>{
+				this.checkCompany()
+			},10)
+		},
+
+        /* 客户名称/信用码失焦时校验客户名称是否存在 存在就提示 */
+		checkCompany() {	
+			setTimeout(()=>{
+                if(this.checkCompanyfocusIs) return
+                if((!this.firstFormData.name && !this.firstFormData.creditCode) || (this.isCheckCompanyInfo && this.firstFormData.name)) return
+                    customInterence.checkCompanyInfo({
+                        CompanyName:this.firstFormData.name,
+                        CreditCode:this.firstFormData.creditCode
+                    }).then(res =>{
+                        if(res.Ret === 200){
+                            if(res.Data.RepeatStatus > 0) {
+                                this.repeatId = res.Data.CompanyId;
+                                this.repeatName = res.Data.ProductName;
+                                this.nameRepeat = res.Data.RepeatStatus
+                                this.codeRepeat = res.Data.Status
+                                this.isCheck = true;
+                            }else {
+                                this.nameRepeat = 0
+                                this.isCheck = false;
+                            }
+                        }
+                    })
+			},500)
+		},
+
+        selectRegion(e){
+            this.firstFormData.province=e[0]
+            this.firstFormData.city=e[1]
+        },
+        /* 根据类型获取行业 */
+		getIndustry() {
+			customInterence.getindustry({
+				Classify:'ficc'
+			}).then(res => {
+				if(res.Ret === 200) {
+					this.tradeArr = res.Data.List || [];
+				}
+			})
+		},
+        /* 获取销售 */
+        async getSale() {
+            const res = await roadshowInterence.getSellerList();
+            if(res.Ret!==200) return 
+            this.salesArr = res.Data.List||[]
+            this.salesArr = this.salesArr.map(i=>{
+                if(!i.AdminName){
+                    i.AdminName = i.GroupName
+                }
+                if(!i.AdminId){
+                    i.AdminId = i.GroupId
+                }
+                return i
+            })
+        },
+    },
+}
+</script>
+
+<style lang="scss" scoped>
+.add-business{
+    padding:30px;
+    box-sizing: border-box;
+    background-color: #fff;
+    min-width: 1100px;
+    height: calc(100vh - 120px);
+    .first-step-form-wrap,.second-step-form-wrap{
+        margin-top:60px;
+        border-top: 1px solid #DCDCDC;
+        width:70%;
+    }
+    .el-form{
+        .form-line{
+            margin:30px 0;
+            border-bottom: 1px solid #DCDCDC;
+            .el-input,.el-select,.el-cascader,.el-radio-group{
+                width:360px;
+            }
+            .el-radio-group{
+                display: flex;
+                justify-content: space-between;
+                .el-radio{
+                    width: 165px;
+                    text-align: center;
+                }
+            }
+        }
+    }
+}
+.btns-box{
+    position: fixed;
+    left: 50%;
+    bottom: 100px;
+    transform: translateX(-50%);
+    width: 200px;
+    z-index: 99;
+}
+</style>

+ 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>

+ 359 - 0
src/views/business_ETA_manage/businessDetail.vue

@@ -0,0 +1,359 @@
+<template>
+    <div class="business-detail-wrap">
+        <div class="business-detail">
+            <Steps 
+                :activeStep="step"
+                :stepsArr="stepsArr"
+                @changeActiveStep="changeActiveStep"
+            />
+            <div class="first-step-form-wrap" v-show="step===1">
+                <el-form 
+                    :model="firstFormData" 
+                    ref="firstFormEl" 
+                    label-width="120px"
+                    inline
+                    :rules="rules"
+                    :disabled="true"
+                    class="first-step-form"
+                >
+                    <div class="form-line">
+                        <el-form-item label="商家名称" prop="BusinessName">
+                            <el-input disabled placeholder="请输入商家名称" v-model="firstFormData.BusinessName"/>
+                        </el-form-item>
+                        <el-form-item label="商家ID" prop="BusinessCode">
+                            <el-input disabled placeholder="请输入商家ID" v-model="firstFormData.BusinessCode"/>
+                        </el-form-item>
+                    </div>
+                    <div class="form-line">
+                        <el-form-item label="所属区域" prop="RegionType">
+                            <el-radio-group v-model="firstFormData.RegionType" disabled>
+                                <el-radio label="国内" border>国内</el-radio>
+                                <el-radio label="海外" border>海外</el-radio>
+                            </el-radio-group>
+                        </el-form-item>
+                        <el-form-item label="商家地址" prop="address">
+                            <el-cascader 
+                                v-model="firstFormData.address"
+                                :props="locationProps"
+                                clearable 
+                                :options="locationOptions"  
+                                @change="selectRegion" 
+                                placeholder="请选择客户地址" 
+                            />
+                        </el-form-item>
+                    </div>
+                    <div class="form-line">
+                        <el-form-item label="社会信用码" prop="CreditCode">
+                            <el-input disabled placeholder="请输入社会信用码" v-model="firstFormData.CreditCode"/>
+                        </el-form-item>
+                        <el-form-item label="研究团队规模" prop="ResearchTeamSize">
+                            <el-select 
+                                v-model="firstFormData.ResearchTeamSize" 
+                                placeholder="请选择研究团队规模"
+                                clearable
+                            >
+                                <el-option
+                                    v-for="item in teamSizeOpts"
+                                    :key="item.val"
+                                    :label="item.label"
+                                    :value="item.val">
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                    </div>
+                    <div class="form-line">
+                        <el-form-item label="决策人" prop="Leader">
+                            <el-input placeholder="请输入决策人" v-model="firstFormData.Leader"/>
+                        </el-form-item>
+                        <el-form-item label="所属行业" prop="IndustryId">
+                            <el-select 
+                                v-model="firstFormData.IndustryId" 
+                                placeholder="请选择行业" 
+                                clearable
+                            >
+                                <el-option
+                                    v-for="item in tradeArr"
+                                    :key="item.IndustryId"
+                                    :label="item.IndustryName"
+                                    :value="item.IndustryId">
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                    </div>
+                    <div class="form-line">
+                        <el-form-item label="资金规模" prop="CapitalScale">
+                            <el-input placeholder="请输入资金规模" v-model="firstFormData.CapitalScale"/>
+                        </el-form-item>
+                        <el-form-item label="用户上限" prop="UserMax">
+                            <el-input type="number" placeholder="请输入用户上限" v-model="firstFormData.UserMax"/>
+                        </el-form-item>
+                    </div>
+                    <div class="form-line">
+                        <el-form-item label="所属销售" prop="SellerName">
+                            <el-input disabled placeholder="请输入销售" v-model="firstFormData.SellerName"/>
+                        </el-form-item>
+                    </div>
+                    
+                </el-form>
+            </div>
+            <div class="second-step-form-wrap" v-show="step===2">
+                <el-table :data="recordData" border>
+                    <el-table-column
+                        v-for="item in tableColOpts"
+                        :key="item.key"
+                        :prop="item.key"
+                        :label="item.label"
+                        align="center"
+                    >
+                    </el-table-column>
+                </el-table>
+            </div>
+        </div>
+        <div class="business-other">
+            <div class="btn-wrap">
+                    <el-button type="primary" @click="$router.push({
+                        path:'/editETABusiness',
+                        query:{
+                            id:firstFormData.EtaBusinessId
+                        }
+                    })">编辑</el-button>
+            </div>
+            <div class="time-line-wrap">
+                <el-timeline>
+                    <el-timeline-item
+                        v-for="(activity, index) in activities"
+                        :key="index"
+                        color="#409EFF" 
+                        :timestamp="activity.CreateTime">
+                        <template slot="dot">
+                            <div class="dot-wrap">
+                                <div class="dot-inner"></div>
+                            </div>
+                        </template>
+                        {{activity.OperationRemark}}
+                    </el-timeline-item>
+                </el-timeline>
+            </div>
+        </div>
+
+        <!-- 添加续约 -->
+        <el-dialog
+            title="添加续约"
+            :visible.sync="showRenewal"
+            :modal-append-to-body="false"
+            :close-on-click-modal="false"
+            @closed="showRenewal=false"
+            width="580px"
+        >
+            <AddRenewal 
+                @addRenewal="handleAddRenewal"
+                @close="showRenewal=false"/>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { customInterence , businessCustomInterence} from '@/api/api.js'
+import Steps from "./components/Steps.vue";
+import AddRenewal from "./components/AddRenewal";
+import {locationOptions} from "@/views/custom_manage/customList/location"
+export default {
+    components: {Steps,AddRenewal},
+    data() {
+        return {
+            locationOptions,
+            locationProps:{
+                value:'name',
+                children:'city',
+                label:'name'
+            },
+
+            step:1,//第几步
+            teamSizeOpts:[
+                {
+                    val:'50人及以下',
+                    label:'50人及以下'
+                },
+                {
+                    val:'200人及以下',
+                    label:'200人及以下'
+                },
+                {
+                    val:'超过200人',
+                    label:'超过200人'
+                }
+            ],
+            tradeArr:[],
+            firstFormData:{
+                RegionType:'',//1国内 2国外
+                BusinessName:'',
+                CreditCode:'',
+                Address:'',
+                Leader:'',
+                ResearchTeamSize:'',
+                CapitalScale:'',
+                IndustryId:'',
+                UserMax:'',
+                SellerId:'',
+            },
+            rules:{
+                address:[{ required: true, message: '请选择商家地址', trigger: 'change' },],
+                decisionMaker:[{required: true, message: '请输入决策人', trigger: 'blur' },],
+                teamSize:[{required: true, message: '请选择研究团队规模', trigger: 'change' },],
+                industry:[{required: true, message: '请选择所属行业', trigger: 'change' },],
+                userMax:[{required: true, message: '请输入用户上限', trigger: 'blur' },],
+                saller:[{required: true, message: '请选择所属销售', trigger: 'change' },],
+            },
+            recordData:[],
+            tableColOpts:[
+                {
+                    label:'签约时间',
+                    key:'SigningTime'
+                },{
+                    label:'到期时间',
+                    key:'ExpiredTime'
+                },{
+                    label:'到期天数',
+                    key:'ExpireDay'
+                }
+            ],
+            activities:[],
+        }
+    },
+    created() {
+        this.getIndustry()
+        this.getBusinessDetail()
+    },
+    methods: {
+        selectRegion(e){
+            this.firstFormData.province=e[0]
+            this.firstFormData.city=e[1]
+        },
+        /* 根据类型获取行业 */
+		getIndustry() {
+			customInterence.getindustry({
+				Classify:'ficc'
+			}).then(res => {
+				if(res.Ret === 200) {
+					this.tradeArr = res.Data.List || [];
+				}
+			})
+		},
+        changeActiveStep(index){
+            this.step = index + 1
+        },
+        // 获取商家详情
+        getBusinessDetail(){
+            //query id
+            businessCustomInterence.getBusinessDetail({
+                EtaBusinessId:Number(this.$route.query.id)
+            }).then(res=>{
+                if(res.Ret !== 200)return 
+                this.firstFormData = res.Data||{}
+                this.firstFormData.address = [res.Data.Province||'',res.Data.City||'']
+            })
+            //获取签约详情
+            this.getTableData(Number(this.$route.query.id))
+            //获取操作日志列表
+            this.getTimeLineData(Number(this.$route.query.id))
+        },
+        // 获取签约详情
+        getTableData(id){
+            businessCustomInterence.getContractList({
+                EtaBusinessId:id
+            }).then(res=>{
+                if(res.Ret !== 200) return 
+                this.recordData = res.Data||[]
+            })
+        },
+
+        // 获取操作日志详情
+        getTimeLineData(id){
+            businessCustomInterence.getTimeLineList({
+                EtaBusinessId:id
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.activities = res.Data||[]
+            })
+        },
+    },
+}
+</script>
+
+<style lang="scss" scoped>
+.business-detail-wrap{
+    display: flex;
+    background-color: #fff;
+    min-width: 1100px;
+    min-height: calc(100vh - 120px);
+    padding:30px;
+    box-sizing: border-box;
+    gap:10%;
+    .business-detail{
+        width:70%;
+        .first-step-form-wrap,.second-step-form-wrap{
+            margin-top:60px;
+            border-top: 1px solid #DCDCDC;
+        }
+        .el-form{
+            .form-line{
+                margin:30px 0;
+                border-bottom: 1px solid #DCDCDC;
+                .el-input,.el-select,.el-cascader,.el-radio-group{
+                    width:360px;
+                }
+                .el-radio-group{
+                    display: flex;
+                    justify-content: space-between;
+                    .el-radio{
+                        width: 165px;
+                        text-align: center;
+                    }
+                }
+            }
+        }
+        .el-table{
+            margin-top: 30px;
+        }
+    }
+    .business-other{
+        flex: 1;
+        .btn-wrap{
+            display: flex;
+            gap:30px;
+            .el-button{
+                flex:1;
+            }
+        }
+        .time-line-wrap{
+            margin-top:30px;
+            border:1px solid #DCDFE6;
+            border-radius: 4px;
+            box-sizing: border-box;
+            padding: 30px;
+            max-height: calc(100vh - 250px);
+            overflow-y: auto;
+            .dot-wrap{
+                width:12px;
+                height:12px;
+                border:6px solid #fff;
+                background-color: #3385FF;
+                position: absolute;
+                left:-6px;
+                top:0;
+                border-radius: 50%;
+                .dot-inner{
+                    position: absolute;
+                    left:3px;
+                    top:3px;
+                    width:6px;
+                    height: 6px;
+                    border-radius: 50%;
+                    background-color: #fff;
+                }
+            }
+        }
+    }
+}
+
+</style>

+ 391 - 0
src/views/business_ETA_manage/businessEdit.vue

@@ -0,0 +1,391 @@
+<template>
+    <div class="business-detail-wrap">
+        <div class="business-detail">
+            <Steps 
+                :activeStep="step"
+                :stepsArr="stepsArr"
+                @changeActiveStep="changeActiveStep"
+            />
+            <div class="first-step-form-wrap" v-show="step===1">
+                <el-form 
+                    :model="firstFormData" 
+                    ref="firstFormEl" 
+                    label-width="120px"
+                    inline
+                    :rules="rules"
+                    class="first-step-form"
+                >
+                    <div class="form-line">
+                        <el-form-item label="商家名称" prop="BusinessName">
+                            <el-input disabled placeholder="请输入商家名称" v-model="firstFormData.BusinessName"/>
+                        </el-form-item>
+                        <el-form-item label="商家ID" prop="BusinessCode">
+                            <el-input disabled placeholder="请输入商家ID" v-model="firstFormData.BusinessCode"/>
+                        </el-form-item>
+                    </div>
+                    <div class="form-line">
+                        <el-form-item label="所属区域" prop="RegionType">
+                            <el-radio-group v-model="firstFormData.RegionType" disabled>
+                                <el-radio label="国内" border>国内</el-radio>
+                                <el-radio label="海外" border>海外</el-radio>
+                            </el-radio-group>
+                        </el-form-item>
+                        <el-form-item label="商家地址" prop="address">
+                            <el-cascader 
+                                v-model="firstFormData.address"
+                                :props="locationProps"
+                                clearable 
+                                :options="locationOptions"  
+                                @change="selectRegion" 
+                                placeholder="请选择客户地址" 
+                            />
+                        </el-form-item>
+                    </div>
+                    <div class="form-line">
+                        <el-form-item label="社会信用码" prop="CreditCode">
+                            <el-input disabled placeholder="请输入社会信用码" v-model="firstFormData.CreditCode"/>
+                        </el-form-item>
+                        <el-form-item label="研究团队规模" prop="ResearchTeamSize">
+                            <el-select 
+                                v-model="firstFormData.ResearchTeamSize" 
+                                placeholder="请选择研究团队规模"
+                                clearable
+                            >
+                                <el-option
+                                    v-for="item in teamSizeOpts"
+                                    :key="item.val"
+                                    :label="item.label"
+                                    :value="item.val">
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                    </div>
+                    <div class="form-line">
+                        <el-form-item label="决策人" prop="Leader">
+                            <el-input placeholder="请输入决策人" v-model="firstFormData.Leader"/>
+                        </el-form-item>
+                        <el-form-item label="所属行业" prop="IndustryId">
+                            <el-select 
+                                v-model="firstFormData.IndustryId" 
+                                placeholder="请选择行业" 
+                                clearable
+                            >
+                                <el-option
+                                    v-for="item in tradeArr"
+                                    :key="item.IndustryId"
+                                    :label="item.IndustryName"
+                                    :value="item.IndustryId">
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                    </div>
+                    <div class="form-line">
+                        <el-form-item label="资金规模" prop="CapitalScale">
+                            <el-input placeholder="请输入资金规模" v-model="firstFormData.CapitalScale"/>
+                        </el-form-item>
+                        <el-form-item label="用户上限" prop="UserMax">
+                            <el-input type="number" placeholder="请输入用户上限" v-model="firstFormData.UserMax"/>
+                        </el-form-item>
+                    </div>
+                    <div class="form-line">
+                        <el-form-item label="所属销售" prop="SellerName">
+                            <el-input disabled placeholder="请输入销售" v-model="firstFormData.SellerName"/>
+                        </el-form-item>
+                    </div>
+                </el-form>
+            </div>
+            <div class="second-step-form-wrap" v-show="step===2">
+                <el-table :data="recordData" border>
+                    <el-table-column
+                        v-for="item in tableColOpts"
+                        :key="item.key"
+                        :prop="item.key"
+                        :label="item.label"
+                        align="center"
+                    >
+                    </el-table-column>
+                </el-table>
+                <el-button type="text" @click="showRenewal=true">添加续约</el-button>
+            </div>
+        </div>
+        <div class="business-other">
+            <div class="btn-wrap">
+                <el-button type="primary" @click="handleSaveDetail">保存</el-button>
+                <el-button type="primary" plain @click="$router.push('/businessETAList')">取消</el-button>
+            </div>
+            <div class="time-line-wrap">
+                <el-timeline>
+                    <el-timeline-item
+                        v-for="(activity, index) in activities"
+                        :key="index"
+                        color="#409EFF" 
+                        :timestamp="activity.CreateTime">
+                        <template slot="dot">
+                            <div class="dot-wrap">
+                                <div class="dot-inner"></div>
+                            </div>
+                        </template>
+                        {{activity.OperationRemark}}
+                    </el-timeline-item>
+                </el-timeline>
+            </div>
+        </div>
+
+        <!-- 添加续约 -->
+        <el-dialog
+            title="添加续约"
+            :visible.sync="showRenewal"
+            :modal-append-to-body="false"
+            :close-on-click-modal="false"
+            @closed="showRenewal=false"
+            width="580px"
+        >
+            <AddRenewal 
+                @addRenewal="handleAddRenewal"
+                @close="showRenewal=false"/>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { customInterence , businessCustomInterence} from '@/api/api.js'
+import Steps from "./components/Steps.vue";
+import AddRenewal from "./components/AddRenewal";
+import {locationOptions} from "@/views/custom_manage/customList/location"
+export default {
+    components: {Steps,AddRenewal},
+    data() {
+        return {
+            locationOptions,
+            locationProps:{
+                value:'name',
+                children:'city',
+                label:'name'
+            },
+
+            step:1,//第几步
+            teamSizeOpts:[
+                {
+                    val:'50人及以下',
+                    label:'50人及以下'
+                },
+                {
+                    val:'200人及以下',
+                    label:'200人及以下'
+                },
+                {
+                    val:'超过200人',
+                    label:'超过200人'
+                }
+            ],
+            tradeArr:[],
+            firstFormData:{
+                RegionType:'',//1国内 2国外
+                BusinessName:'',
+                CreditCode:'',
+                Address:'',
+                Leader:'',
+                ResearchTeamSize:'',
+                CapitalScale:'',
+                IndustryId:'',
+                UserMax:'',
+                SellerId:'',
+                Province:'',
+                City:''
+            },
+            rules:{
+                address:[{ required: true, message: '请选择商家地址', trigger: 'change' },],
+                decisionMaker:[{required: true, message: '请输入决策人', trigger: 'blur' },],
+                teamSize:[{required: true, message: '请选择研究团队规模', trigger: 'change' },],
+                industry:[{required: true, message: '请选择所属行业', trigger: 'change' },],
+                userMax:[{required: true, message: '请输入用户上限', trigger: 'blur' },],
+                saller:[{required: true, message: '请选择所属销售', trigger: 'change' },],
+            },
+            recordData:[],
+            tableColOpts:[
+                {
+                    label:'签约时间',
+                    key:'SigningTime'
+                },{
+                    label:'到期时间',
+                    key:'ExpiredTime'
+                },{
+                    label:'到期天数',
+                    key:'ExpireDay'
+                }
+            ],
+            activities:[],
+            showRenewal:false,
+        }
+    },
+    created() {
+        this.getIndustry()
+        this.getBusinessDetail()
+    },
+    methods: {
+        selectRegion(e){
+            this.firstFormData.Province=e[0]
+            this.firstFormData.City=e[1]
+        },
+        /* 根据类型获取行业 */
+		getIndustry() {
+			customInterence.getindustry({
+				Classify:'ficc'
+			}).then(res => {
+				if(res.Ret === 200) {
+					this.tradeArr = res.Data.List || [];
+				}
+			})
+		},
+        changeActiveStep(index){
+            this.step = index + 1
+        },
+        // 获取商家详情
+        getBusinessDetail(){
+            //query id
+            businessCustomInterence.getBusinessDetail({
+                EtaBusinessId:Number(this.$route.query.id)
+            }).then(res=>{
+                if(res.Ret !== 200)return 
+                this.firstFormData = res.Data||{}
+                this.firstFormData.address = [res.Data.Province||'',res.Data.City||'']
+            })
+            //获取签约详情
+            this.getTableData(Number(this.$route.query.id))
+            //获取操作日志列表
+            this.getTimeLineData(Number(this.$route.query.id))
+        },
+        // 获取签约详情
+        getTableData(id){
+            businessCustomInterence.getContractList({
+                EtaBusinessId:id
+            }).then(res=>{
+                if(res.Ret !== 200) return 
+                this.recordData = res.Data||[]
+            })
+        },
+
+        // 获取操作日志详情
+        getTimeLineData(id){
+            businessCustomInterence.getTimeLineList({
+                EtaBusinessId:id
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.activities = res.Data||[]
+            })
+        },
+        // 保存商家
+        handleSaveDetail(){
+            const {EtaBusinessId,CapitalScale,
+                   address,Leader,IndustryId,
+                   ResearchTeamSize,UserMax} = this.firstFormData
+            const IndustryName = this.tradeArr.find(item=>item.IndustryId===IndustryId).IndustryName
+            businessCustomInterence.editBusiness({
+                EtaBusinessId,Leader,
+                IndustryName,CapitalScale,
+                ResearchTeamSize,
+                IndustryId:Number(IndustryId),
+                UserMax:Number(UserMax),
+                Province:address[0],
+                City:address[1]
+            }).then(res=>{
+                if(res.Ret!==200) return
+                this.$message.success('保存成功')
+                this.getBusinessDetail()
+            })
+        },
+        //添加续约
+        handleAddRenewal({signDate,expirationDate}){
+            businessCustomInterence.addNewContract({
+                EtaBusinessId:Number(this.$route.query.id),
+                SigningTime:signDate,
+                ExpiredTime:expirationDate
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success('添加续约成功')
+                this.showRenewal=false
+                this.getTableData(Number(this.$route.query.id))
+                this.getTimeLineData(Number(this.$route.query.id))
+            })
+        }
+    },
+}
+</script>
+
+<style lang="scss" scoped>
+.business-detail-wrap{
+    display: flex;
+    background-color: #fff;
+    min-width: 1100px;
+    min-height: calc(100vh - 120px);
+    padding:30px;
+    box-sizing: border-box;
+    gap:10%;
+    .business-detail{
+        width:70%;
+        .first-step-form-wrap,.second-step-form-wrap{
+            margin-top:60px;
+            border-top: 1px solid #DCDCDC;
+        }
+        .el-form{
+            .form-line{
+                margin:30px 0;
+                border-bottom: 1px solid #DCDCDC;
+                .el-input,.el-select,.el-cascader,.el-radio-group{
+                    width:360px;
+                }
+                .el-radio-group{
+                    display: flex;
+                    justify-content: space-between;
+                    .el-radio{
+                        width: 165px;
+                        text-align: center;
+                    }
+                }
+            }
+        }
+        .el-table{
+            margin-top: 30px;
+        }
+    }
+    .business-other{
+        flex: 1;
+        .btn-wrap{
+            display: flex;
+            gap:30px;
+            .el-button{
+                flex:1;
+            }
+        }
+        .time-line-wrap{
+            margin-top:30px;
+            border:1px solid #DCDFE6;
+            border-radius: 4px;
+            box-sizing: border-box;
+            padding: 30px;
+            max-height: calc(100vh - 250px);
+            overflow-y: auto;
+            .dot-wrap{
+                width:12px;
+                height:12px;
+                border:6px solid #fff;
+                background-color: #3385FF;
+                position: absolute;
+                left:-6px;
+                top:0;
+                border-radius: 50%;
+                .dot-inner{
+                    position: absolute;
+                    left:3px;
+                    top:3px;
+                    width:6px;
+                    height: 6px;
+                    border-radius: 50%;
+                    background-color: #fff;
+                }
+            }
+        }
+    }
+}
+
+</style>

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

@@ -0,0 +1,500 @@
+<template>
+    <div class="business-ETA-list">
+        <div class="top-filter-box">
+            <div>
+                <el-button type="primary" @click="$router.push('/addETABusiness')">新增</el-button>
+                <el-input
+                    placeholder="商家名称/社会信用码/商家ID"
+                    v-model="search_txt"
+                    @input="changeSelectOptions('search')"
+                    clearable
+                    style="maxWidth:500px;float:right">
+                    <i slot="prefix" class="el-input__icon el-icon-search"></i>
+                </el-input>
+            </div>
+            
+        </div>
+        <div class="table-wrap">
+            <div class="select-wrap">
+                <el-select 
+                    v-model="trade" 
+                    placeholder="请选择行业" 
+                    clearable 
+                    @change="changeSelectOptions('trade')"
+                >
+                    <el-option
+                        v-for="item in tradeArr"
+                        :key="item.IndustryId"
+                        :label="item.IndustryName"
+                        :value="item.IndustryId">
+                    </el-option>
+                </el-select>
+                <el-cascader
+                    ref="cascader"
+                    v-model="sales"
+                    :options="salesArr"
+                    :show-all-levels="false"
+                    :props="{
+                        expandTrigger: 'hover',
+                        children: 'Child',
+                        emitPath: false,
+                        label:'AdminName',
+                        value:'AdminId',
+                        multiple:true
+                    }"
+                    collapse-tags
+                    filterable
+                    clearable
+                    placeholder="请选择销售"
+                    @change="changeSelectOptions('sales')"
+                />
+                <el-cascader 
+                    v-model="valueLocation" 
+                    collapse-tags 
+                    :props="locationProps" 
+                    clearable 
+                    :options="locationOptions"  
+                    @change="changeSelectOptions('location')" 
+                    placeholder="请选择客户地址" 
+                />
+                <el-select 
+                    v-model="signStatus" 
+                    placeholder="请选择签约状态" 
+                    clearable
+                    @change="changeSelectOptions('signStatus')"
+                >
+                    <el-option
+                        v-for="item in signStatusOpts"
+                        :key="item.val"
+                        :label="item.label"
+                        :value="item.val">
+                    </el-option>
+                </el-select>
+            </div>
+            <el-table
+                    ref="userTable"
+                    :data="tableData"
+                    v-loading="isTableLoadding"
+                    element-loading-text="数据加载中..."
+                    @sort-change="sortChangeHandle"
+                    border
+                >
+                    <el-table-column
+                        v-for="item in tableColOpts"
+                        :key="item.key"
+                        :prop="item.key"
+                        :label="item.label"
+                        align="center"
+                        :sortable="item.sort"
+                    >
+                        <template slot-scope="scope">
+                            <span v-if="item.key==='SigningStatus'">
+                                {{signStatusOpts[scope.row.SigningStatus - 1].label}}{{!scope.row.Enable?'(禁用)':''}}
+                            </span>
+                            <span v-else-if="item.key==='BusinessName'" class="link" @click="handleShowDetail(scope.row)">
+                                {{ scope.row.BusinessName }}
+                            </span>
+                            <span v-else>{{scope.row[item.key]}}</span>
+                        </template>
+                    </el-table-column>
+                    <el-table-column
+                        label="操作"
+                        min-width="100"
+                        align="center"
+                    >
+                        <template slot-scope="scope">
+                            <div class="table-opt-btns">
+                                <span @click="handleEdit(scope.row)">编辑</span>
+                                <span @click="handleShowRenewal(scope.row)">添加续约</span>
+                                <el-dropdown 
+                                    size="medium" 
+                                    placement="bottom-start" 
+                                    @command="itemclickHandle($event,scope.row)"
+                                >
+                                    <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>
+                                    </span>
+                                </el-dropdown>
+                            </div>
+                        </template>
+                    
+                    </el-table-column>
+            </el-table>
+            <div style="text-align:right;margin-top:20px">
+                <el-pagination 
+                        layout="total,prev,pager,next,jumper" 
+                        background 
+                        :current-page="page"
+                        @current-change="handleCurrentChange"
+                        :page-size="pageSize"
+                        :total="total"
+                        style="display: inline-block"
+                    />
+            </div>
+        </div>
+
+        <!-- 添加续约 -->
+        <el-dialog
+            title="添加续约"
+            :visible.sync="showRenewal"
+            :modal-append-to-body="false"
+            :close-on-click-modal="false"
+            @closed="showRenewal=false"
+            width="580px"
+        >
+            <AddRenewal 
+                @addRenewal="handleAddRenewal"
+                @close="showRenewal=false"/>
+        </el-dialog>
+
+        <!-- 修改销售 -->
+        <el-dialog
+            title="修改销售"
+            :visible.sync="showModifySaller"
+            :modal-append-to-body="false"
+            :close-on-click-modal="false"
+            @closed="showRenewal=false"
+            width="580px"
+        >
+            <ModifySaller 
+                :salesArr="salesArr"
+                :data="modifyData"
+                @modifySaller="handleModifySaller"
+                @close="showModifySaller=false"/>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { customInterence ,businessCustomInterence , roadshowInterence} from '@/api/api.js'
+import {locationOptions} from "@/views/custom_manage/customList/location"
+import AddRenewal from './components/AddRenewal.vue'
+import ModifySaller from './components/ModifySaller.vue'
+export default {
+    components:{AddRenewal,ModifySaller},
+    data() {
+        return {
+            /* dialog */
+            showRenewal:false,//显示添加续约
+            showModifySaller:false,//显示修改销售
+            modifyData:{},//当前操作的商家数据
+
+            /* select options */
+            search_txt:'',
+            trade:'',
+            tradeArr:[],
+            sales:[],
+            salesArr:[],//销售
+            locationOptions,
+            valueLocation:[],
+            provinceValue:'',
+            cityValue:'',
+            locationProps:{
+                multiple: true,
+                value:'name',
+                children:'city',
+                label:'name'
+            },
+            signStatus:'',
+            signStatusOpts:[
+                {
+                    label:'首次签约',
+                    val:1
+                },
+                {
+                    label:'续约中',
+                    val:2
+                },
+                {
+                    label:'已终止',
+                    val:3
+                }
+            ],
+            /* sort options */
+            sortParam:0,
+            sortType:0,
+
+            /* table */
+            tableColOpts:[
+                {
+                    label:'商家名称',
+                    key:'BusinessName'
+                },
+                {
+                    label:'商家ID',
+                    key:'BusinessCode'
+                },
+                {
+                    label:'商家地址',
+                    key:'Address'
+                },
+                {
+                    label:'销售',
+                    key:'SellerName'
+                },
+                {
+                    label:'签约状态',
+                    key:'SigningStatus'
+                },
+                {
+                    label:'最新签约时间',
+                    key:'SigningTime',
+                    sort:true
+                },
+                {
+                    label:'到期时间',
+                    key:'ExpiredTime',
+                    sort:true
+                },
+                {
+                    label:'创建时间',
+                    key:'CreateTime',
+                    sort:true
+                },
+                {
+                    label:'用户上限',
+                    key:'UserMax',
+                    sort:true
+                },
+                
+            ],
+            tableData:[],
+            isTableLoadding:false,
+            page:1,
+            pageSize:20,
+            total:0,
+        }
+    },
+    created() {
+        this.getIndustry()
+        this.getSale()
+        this.getBusinessList()
+    },
+    methods: {
+        // 筛选项改变
+        changeSelectOptions(option){
+            if(option === 'location'){
+                const provinceArr = []
+                const cityArr = []
+                this.valueLocation.forEach(item=>{
+                        // 省
+                        provinceArr.push(item[0])
+                        // 市
+                        cityArr.push(item[1])
+                })
+                //provinceArr需要去重
+                this.provinceValue = [...new Set(provinceArr)].join(',')
+                this.cityValue = cityArr.join(',')
+                this.page = 1;
+            }
+            this.getBusinessList()
+        },
+        // 表格排序方式改变
+        sortChangeHandle(params){
+            const sortParamMap = {
+                'SigningTime':1,//签约时间
+                'ExpiredTime':2,//到期时间
+                'CreateTime':3,//创建时间
+                'UserMax':4,//用户上限
+            }
+            this.sortParam = sortParamMap[params.prop]
+            this.sortType = params.order === 'ascending' ? 1 :params.order === 'descending' ? 2 : 0
+            this.page = 1
+            this.getBusinessList()
+        },
+        // 获取表格数据
+        getBusinessList(){
+            this.isTableLoadding = true
+            businessCustomInterence.getBusinessList({
+                Keyword:this.search_txt,
+                SellerIds:this.sales.join(','),
+                SigningStatus:Number(this.signStatus),
+                Province:this.provinceValue,
+                City:this.cityValue,
+                IndustryId:Number(this.trade),
+                PageSize:this.pageSize,
+                CurrentIndex:this.page,
+                SortParam:this.sortParam,
+                SortType:this.sortType
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.tableData = res.Data.List
+                this.total = res.Data.Paging.Totals
+                this.isTableLoadding = false
+            })
+        },
+        // 去详情
+        handleShowDetail(data){
+            this.$router.push({
+                path:'/businessETADetail',
+                query:{
+                    id:data.EtaBusinessId
+                }
+            })
+        },
+        // 前去编辑
+        handleEdit(data){
+            this.$router.push({
+                path:'/editETABusiness',
+                query:{
+                    id:data.EtaBusinessId
+                }
+            })
+        },
+
+        // 显示添加续约
+        handleShowRenewal(e){
+            this.modifyData = e
+            this.showRenewal=true
+        },
+        // 商家添加续约
+        handleAddRenewal({signDate,expirationDate}){
+            businessCustomInterence.addNewContract({
+                EtaBusinessId:this.modifyData.EtaBusinessId,
+                SigningTime:signDate,
+                ExpiredTime:expirationDate
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success('添加续约成功')
+                this.showRenewal=false
+                this.getBusinessList()
+            })
+        },
+        // 商家修改销售
+        handleModifySaller({saller,sallerName}){
+            businessCustomInterence.changeBusinessSeller({
+                EtaBusinessId:this.modifyData.EtaBusinessId,
+                SellerId:saller,
+                SellerName:sallerName
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success('修改销售成功')
+                this.showModifySaller = false
+                this.getBusinessList()
+            })
+        },
+        // 启用禁用商家
+        changeBusinessStatus(data){
+            businessCustomInterence.changeBusinessStatus({
+                EtaBusinessId:data.EtaBusinessId
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success(`${data.Enable?'禁用':'启用'}成功`)
+                this.getBusinessList()
+            })
+        },
+
+        // 操作栏 折叠起来的按钮
+        itemclickHandle(type,data){
+            if(type==='modifySale'){
+                this.modifyData = data
+                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
+                    }
+                })
+            }
+        },
+
+        /* 根据类型获取行业 */
+		getIndustry() {
+			customInterence.getindustry({
+				Classify:'ficc'
+			}).then(res => {
+				if(res.Ret === 200) {
+					this.tradeArr = res.Data.List || [];
+				}
+			})
+		},
+        /* 获取销售 */
+        async getSale() {
+            const res = await roadshowInterence.getSellerList();
+            if(res.Ret!==200) return 
+            this.salesArr = res.Data.List||[]
+            this.salesArr = this.salesArr.map(i=>{
+                if(!i.AdminName){
+                    i.AdminName = i.GroupName
+                }
+                if(!i.AdminId){
+                    i.AdminId = i.GroupId
+                }
+                return i
+            })
+		},
+        handleCurrentChange(page){
+            this.page = page
+            this.getBusinessList()
+        }
+    },
+}
+</script>
+<style lang="scss">
+.business-ETA-list{
+    .top-filter-box{
+        .el-cascader__search-input {
+            min-width: 30px;
+        }
+    } 
+}
+
+</style>
+<style lang="scss" scoped>
+.top-filter-box{
+    border: 1px solid #ECECEC;
+    padding: 20px 30px;
+    background: #fff;
+    border-radius: 4px;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+}
+.table-wrap{
+    margin-top: 30px;
+    border: 1px solid #ECECEC;
+    padding: 20px 30px;
+    background: #fff;
+    border-radius: 4px;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+    .select-wrap{
+        display: flex;
+        gap:20px;
+        align-items: center;
+        margin-bottom: 20px;
+        .el-select,.el-cascader{
+            width:240px;
+        }
+    }
+    .link{
+        color:#4099ef;
+        cursor: pointer;
+        &:hover{
+            text-decoration: underline;
+        }
+        
+    }
+}
+.table-opt-btns{
+    color:#4099ef;
+    display:flex;
+    align-content: center;
+    justify-content: center;
+    align-items: center;
+    span{
+        margin: 0 3px;
+        cursor: pointer;
+    }
+}
+
+
+</style>

+ 77 - 0
src/views/business_ETA_manage/components/AddRenewal.vue

@@ -0,0 +1,77 @@
+<template>
+    <div class="add-renewal-wrap">
+        <el-form 
+            :model="ruleForm" 
+            :rules="rules" 
+            ref="ruleForm" 
+            label-width="100px" 
+            class="demo-ruleForm"
+        >
+            <el-form-item label="签约时间" prop="signDate">
+                <el-date-picker
+                    v-model="ruleForm.signDate"
+                    type="date"
+                    placeholder="选择日期"
+                    value-format="yyyy-MM-dd"
+                />
+            </el-form-item>
+            <el-form-item label="到期时间" prop="expirationDate">
+                <el-date-picker
+                    v-model="ruleForm.expirationDate"
+                    type="date"
+                    placeholder="选择日期"
+                    value-format="yyyy-MM-dd"
+                />
+            </el-form-item>
+            <div style="text-align:center;margin:30px 0">
+                <el-button type="primary" plain @click="handleClose">取消</el-button>
+                <el-button type="primary" @click="handleSave">保存</el-button>
+            </div>
+        </el-form>
+    </div>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            rules:{
+                signDate:[{required: true, message: '请选择签署日期', trigger: 'change' },],
+                expirationDate:[{required: true, message: '请选择签署日期', trigger: 'change' },],
+            },
+            ruleForm:{
+                signDate:'',
+                expirationDate:''
+            }
+        }
+    },
+    methods: {
+        handleSave(){
+            this.$refs.ruleForm.validate((valid)=>{
+                if(valid){
+                    const flag=this.$moment(this.ruleForm.signDate).isBefore(this.ruleForm.expirationDate);
+                    if(!flag){
+                        this.$message.warning('到期时间不得早于签约时间')
+                        return
+                    }
+                    this.$emit('addRenewal',this.ruleForm)
+                    this.initForm()
+                }
+            })
+        },
+        initForm(){
+            this.ruleForm.signDate = ''
+            this.ruleForm.expirationDate = ''
+            this.$refs.ruleForm.resetFields();
+        },
+        handleClose(){
+            this.initForm()
+            this.$emit('close')
+        }
+    },
+}
+</script>
+
+<style>
+
+</style>

+ 95 - 0
src/views/business_ETA_manage/components/ModifySaller.vue

@@ -0,0 +1,95 @@
+<template>
+    <div class="modify-saller-wrap">
+        <el-form 
+            :model="ruleForm" 
+            :rules="rules" 
+            ref="ruleForm" 
+            label-width="100px" 
+            class="demo-ruleForm"
+        >
+            <el-form-item label="商家名称">
+                <span>{{data.BusinessName||''}}</span>
+            </el-form-item>
+            <el-form-item label="当前销售">
+                <span>{{data.SellerName||''}}</span>
+            </el-form-item>
+            <el-form-item label="移至销售" prop="saller">
+                <el-cascader
+                    ref="cascader"
+                    v-model="ruleForm.saller"
+                    :options="salesArr"
+                    :show-all-levels="false"
+                    :props="{
+                        expandTrigger: 'hover',
+                        children: 'Child',
+                        emitPath: false,
+                        label:'AdminName',
+                        value:'AdminId',
+                    }"
+                    collapse-tags
+                    filterable
+                    clearable
+                    placeholder="请选择销售"
+                />
+            </el-form-item>
+            <div style="text-align:center;margin:30px 0">
+                <el-button type="primary" plain @click="handleClose">取消</el-button>
+                <el-button type="primary" @click="handleSave">保存</el-button>
+            </div>
+        </el-form>
+    </div>
+</template>
+
+<script>
+export default {
+    props:{
+        salesArr:{ //销售数据
+            type:Array,
+            default:()=>{return []}
+        },
+        data:{ //正在编辑的数据
+            type:Object,
+            default:()=>{return {}}
+        }
+    },
+    data() {
+        return {
+            salesArr:[],
+            rules:{
+                saller:[{required: true, message: '请选择所属销售', trigger: 'change' },],
+            },
+            ruleForm:{
+                saller:''
+            }
+        }
+    },
+    created() {},
+    methods: {
+        handleSave(){
+            this.$refs.ruleForm.validate((valid)=>{
+                if(valid){
+                    const cascaderNodes = this.$refs.cascader.getCheckedNodes({leafOnly:true})
+                    this.$emit('modifySaller',{
+                        saller:Number(cascaderNodes[0]?cascaderNodes[0].value:0),
+                        sallerName:cascaderNodes[0]?cascaderNodes[0].label:''
+                    })
+                    this.initForm()
+
+                }
+            })
+        },
+        initForm(){
+            this.ruleForm.saller = ''
+            this.$refs.ruleForm.resetFields();
+        },
+        handleClose(){
+            this.initForm()
+            this.$emit('close')
+        },
+    },
+}
+</script>
+
+<style>
+
+</style>

+ 106 - 0
src/views/business_ETA_manage/components/Steps.vue

@@ -0,0 +1,106 @@
+<template>
+    <div class="step-wrap">
+        <div class="step-item" :class="{'active':activeStep===index+1}"
+            v-for="(step,index) in stepsArr" :key="index"
+            @click="changeActiveStep(index)">
+            <div class="step-line"></div>
+            <div class="step-icon" v-if="(activeStep<=index+1)||allowStepClick">{{index+1}}</div>
+            <div class="step-icon finished" v-else><i class="el-icon-check"></i></div>
+            <div class="step-text">{{step.text}}</div>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props:{
+        allowStepClick:{ //是否允许点击切换步骤
+            type:Boolean,
+            default:true
+        },
+        activeStep:{ //激活的步骤
+            type:Number,
+            default:0
+        },
+        stepsArr:{ //步骤数组
+            type:Array,
+            default:()=>{
+                return [
+                    {
+                        text:'基础信息'
+                    },{
+                        text:'签约信息'
+                    }
+                ]
+            }
+        }
+    },
+    data() {
+        return {
+
+        };
+    },
+    methods: {
+        changeActiveStep(index){
+            if(!this.allowStepClick) return 
+            this.$emit('changeActiveStep',index)
+        }
+    },
+};
+</script>
+
+<style scoped lang="scss">
+.step-wrap{
+    display: flex;
+    .step-item{
+        position: relative;
+        display: flex;
+        align-items: center;
+        gap:16px;
+        color:rgba(0, 0, 0, 0.4);
+        cursor: pointer;
+        .step-line{
+            flex: 1;
+            height:2px;
+            background-color: #DCDCDC;
+            min-width: 270px;
+        }
+        .step-icon{
+            width:24px;
+            height:24px;
+            border-radius: 50%;
+            border:2px solid rgba(0, 0, 0, 0.4);
+            text-align: center;
+            line-height: 24px;
+            font-size: 16px;
+            &.finished{
+                border-color: #3385FF;
+                i{
+                    color:#3385FF;
+                    font-weight: bold;
+                }
+            }
+        }
+        .step-text{
+            margin-right: 16px;
+        }
+        &:first-child{
+            .step-line{
+                display: none;
+            }
+        }
+
+        &.active{
+            color:#3385FF;
+            .step-icon{
+                background-color: #3385FF;
+                color:#fff;
+                border-color: transparent;
+            }
+            .step-line{
+                background-color: #3385FF;
+            }
+        }
+    }
+}
+</style>

+ 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 || [];
       }

+ 29 - 1
src/views/custom_manage/customList/components/shareListDialog.vue

@@ -25,6 +25,7 @@
                 <el-table 
                     border 
                     :data="recordList"
+                    :row-class-name="tableRowClassName"
                     v-loading="tableLoading">
                     <el-table-column v-for="column in tableColumns" :key="column.key"
                         :prop="column.key"
@@ -37,8 +38,12 @@
                         v-if="allowEdit"
                         label="操作"
                         align="center"
+                        width="160"
                     >
-                    <template slot-scope="{row}">
+                    <template slot-scope="{row,$index}">
+                        <el-button type="text" size="small" style="color:#409eff;"
+                            @click="markRecord(row,$index)"
+                        >{{row.Mark?'取消标记':'标记'}}</el-button>
                         <el-button type="text" size="small" style="color:red;"
                             @click="deleteRecord(row)"
                         >删除</el-button>
@@ -114,6 +119,12 @@ export default {
                 this.tableLoading = false
             })
         },
+        tableRowClassName({row}){
+            if(row.Mark){
+                return 'mark-row'
+            }
+            return ''
+        },
         addNewRecord(){
             if(!this.recordContent.length){
                 this.$message.warning('请输入服务描述')
@@ -146,6 +157,17 @@ export default {
                 })
             })
         },
+        markRecord(data,index){
+            customInterence.markRecord({
+                CompanyServiceRecordId:data.CompanyServiceRecordId,
+                Status:data.Mark?0:1
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success(`${data.Mark?'取消标记':'标记'}成功`)
+                this.getRecordList()
+            })
+
+        },
         closeDia(){
             this.$emit('close')
         }
@@ -174,6 +196,12 @@ export default {
                 .el-table__empty-block{
                     border-bottom: 1px solid #EBEEF5;
                 }
+                .mark-row{
+                    background: #FEF0F0;
+                    &:hover>td{
+                        background-color: #FEF0F0 !important;
+                    }
+                }
             }
         }
     }

+ 147 - 0
src/views/custom_manage/customList/customCityList.vue

@@ -0,0 +1,147 @@
+<template>
+    <div class="custom-city-list-wrap">
+        <div class="select-box box-wrap">
+            <el-cascader v-model="searchCitys" 
+                :props="{multiple: true,value:'name',children:'city',label:'name'}" 
+                :options="locationOptions"
+                clearable collapse-tags 
+                placeholder="请选择客户地址"
+                @change="handleChangeLocation" >
+            </el-cascader>
+            <el-input placeholder="客户名称/原销售/分配销售" 
+                prefix-icon="el-icon-search" 
+                v-model="searchText" 
+                clearable
+                @input="getTableList"></el-input>
+        </div>
+        <div class="table-box box-wrap">
+            <el-table :data="tableData" border>
+                <el-table-column 
+                    v-for="item in tableColumns" :key="item.key"
+                    :label="item.label" align="center"
+                    >
+                    <template slot-scope="{row}">
+                        {{ row[item.key] }}
+                    </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>
+    </div>
+</template>
+
+<script>
+import {locationOptions} from "./location"
+import { customInterence } from '@/api/api.js'
+export default {
+    data() {
+        this.locationOptions = locationOptions
+        return {
+            searchCitys:[],
+            provinceValue:'',
+            cityValue:'',
+            searchText:'',
+            tableColumns:[
+                {
+                    label:'客户名称',
+                    key:'CompanyName'
+                },{
+                    label:'类型',
+                    key:'CompanyType'
+                },{
+                    label:'所属行业',
+                    key:'IndustryName'
+                },{
+                    label:'客户地址',
+                    key:'City'
+                },{
+                    label:'原销售',
+                    key:'SellerName'
+                },{
+                    label:'分配销售',
+                    key:'ShareSeller'
+                },{
+                    label:'状态',
+                    key:'Status'
+                }
+            ],
+            tableData:[],
+            tableLoading:false,
+            pageNo:1,
+            pageSize:10,
+            total:0,
+        };
+    },
+    methods: {
+        handleChangeLocation(){
+            const provinceArr = []
+            const cityArr = []
+            this.searchCitys.forEach(item=>{
+                // 省
+                provinceArr.push(item[0])
+                // 市
+                cityArr.push(item[1])
+            })
+        //provinceArr需要去重
+            this.provinceValue = [...new Set(provinceArr)].join(',')
+            this.cityValue = cityArr.join(',')
+            this.page_no = 1;
+            this.getTableList();
+        },
+        getTableList(){
+            this.tableLoading=true
+            customInterence.getCustomCityList({
+                PageSize:this.pageSize,
+                CurrentIndex:this.pageNo,
+                Keyword:this.searchText,
+                Province:this.provinceValue,
+                City:this.cityValue
+            }).then(res=>{
+                if(res.Ret!==200) return
+                this.tableData = res.Data.List
+                this.total = res.Data.Paging.Totals
+            })
+            
+        },
+        currentChange(page){
+            this.pageNo=page
+            this.getTableList()
+        }
+    },
+    mounted(){
+        this.getTableList()
+    }
+};
+</script>
+
+<style scoped lang="scss">
+.custom-city-list-wrap{
+    .box-wrap{
+        padding:30px;
+        background-color: #fff;
+        border-radius: 4px;
+    }
+    .select-box{
+        display: flex;
+        justify-content: space-between;
+        .el-input{
+            width:400px;
+        }
+    }
+    .table-box{
+        margin-top: 30px;
+        .el-pagination{
+            margin-top: 30px;
+            text-align: right;
+        }
+    }
+}
+</style>

+ 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(){

+ 4 - 1
src/views/custom_manage/customList/customShareList.vue

@@ -12,6 +12,9 @@
             <el-option :label="item.RealName" :value="item.AdminId" v-for="item in salesArr" :key="item.AdminId" ></el-option>
           </el-select>
         </div>
+        <div v-else>
+            <el-button type="primary" @click="$router.push('/customCityList')">查看同城客户</el-button>
+        </div>
         <el-input 
           placeholder="客户名称/社会信用码/手机号码/邮箱"
           v-model="search_txt"
@@ -92,7 +95,7 @@
 					</el-table-column>
 					<el-table-column
 					prop="SellerName"
-					label="销售"
+					label="销售"
 					min-width="6.14%"
 					align="center">
 						<template slot-scope="scope"> 

+ 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>

+ 135 - 35
src/views/ficc_manage/userApplication.vue

@@ -2,26 +2,40 @@
   <div class="container-userapplication">
     <div class="userapplication-top">
       <div class="top-tabs">
-        <span v-for="item in Tabs" :key="item.name" @click="handleTabsClick(item)" :class="activeName == item.type ? 'active' : ''">
+        <!-- <span v-for="item in Tabs" :key="item.name" @click="handleTabsClick(item)" :class="activeName == item.type ? 'active' : ''">
           {{ item.name }}
-        </span>
+        </span> -->
+        <el-radio-group v-model="activeItem" @input="handleTabsClick(activeItem)">
+            <el-radio-button :label="item" v-for="item in Tabs" :key="item.name">{{item.name}}</el-radio-button>
+        </el-radio-group>
       </div>
-      <div class="export-select">
-        <a style="width:80px; margin-right: 20px" :href="exportUrl" download v-if="Tabs.length>1">
+    </div>
+    <el-card style="margin-top: 20px">
+        <div class="export-select">
+        <!-- <a style="width:80px; margin-right: 20px" :href="exportUrl" download v-if="Tabs.length>1">
           <el-button type="primary" style="width: 100%"  >导出</el-button>
-        </a>
-        <el-select v-if="activeName == 1" v-model="custom_apply_type" placeholder="请选择申请类型" style="width: 300px; margin-right: 20px" clearable>
+        </a> -->
+        <date-picker 
+            v-model="date_range" 
+            type="date" 
+            range
+            value-type="format"
+            :placeholder="`请选择${activeName===1?'提交':activeName===2?'申请':'发送'}时间`"
+            @change="changeQuery">
+        </date-picker>
+        <el-select v-if="activeName == 1" v-model="custom_apply_type" placeholder="请选择申请类型" style="width: 160px;" clearable @change="changeQuery">
           <el-option v-for="item in applyArr" :key="item.name" :label="item.name" :value="item.name"> </el-option>
         </el-select>
-        <el-select v-if="activeName == 1" v-model="custom_type" placeholder="请选择状态" style="width: 300px; margin-right: 20px" clearable multiple>
+        <el-select v-if="activeName == 1" v-model="custom_type" placeholder="请选择用户状态" style="width: 200px;" clearable multiple @change="changeQuery">
           <el-option v-for="item in statusArr" :key="item.name" :label="item.name" :value="item.name"> </el-option>
         </el-select>
-        <el-input placeholder="姓名/手机号/邮箱/公司名称" v-model="search_txt" clearable style="max-width: 500px">
+        <el-select v-model="group_type" placeholder="请选择分组" style="width: 160px;" clearable @change="changeQuery">
+          <el-option v-for="item in groupArr" :key="item.name" :label="item.name" :value="item.name"> </el-option>
+        </el-select>
+        <el-input placeholder="姓名/手机号/邮箱/公司名称" v-model="search_txt" clearable style="max-width: 240px" @input="changeQuery">
           <i slot="prefix" class="el-input__icon el-icon-search"></i>
         </el-input>
       </div>
-    </div>
-    <el-card style="margin-top: 20px">
       <el-table :data="tableData" v-loading="tableLoading" element-loading-text="数据加载中..." border>
         <el-table-column v-for="item in tableColums" :key="item.label" :label="item.label" :width="item.widthsty" :min-width="item.minwidthsty" align="center">
           <template slot-scope="{ row }">
@@ -47,16 +61,23 @@
             <span v-else>{{ row[item.key] }}</span> -->
           </template>
         </el-table-column>
+        <el-table-column label="分组" align="center">
+            <template slot-scope="{ row }">
+                <span>{{row.MarkGroup}}</span>
+            </template>
+        </el-table-column>
         <el-table-column label="操作" align="center">
           <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.IsMove === 0" @click="moveHandle(row)">移动</span>
+             <!--  <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" @click="handleChooseGroup(row)">标记</span>
             </div>
             <div v-else>
-              <span class="editsty" v-if="row.Status==='待处理'" @click="dealHandle(row)">标记处理</span>
+              <!-- <span class="editsty" v-if="row.Status==='待处理'" @click="dealHandle(row)">标记处理</span> -->
+              <span class="editsty" v-if="row.Status==='待处理'" @click="handleChooseGroup(row)">标记</span>
             </div>
-            <span class="editsty" style="color:#ff0000" v-if="row.DelBtn" @click="delHandle(row)">删除</span>
+            <span class="editsty" v-if="activeName == 1&&row.IsMove === 0" @click="moveHandle(row)">移动</span>
+            <!-- <span class="editsty" style="color:#ff0000" v-if="row.DelBtn" @click="delHandle(row)">删除</span> -->
           </template>
         </el-table-column>
         <div slot="empty" style="padding: 20px 0">
@@ -74,6 +95,27 @@
     <intervewDia :isShowDia.sync="isShowDia" :item="dealObj" v-if="isShowDia" :activeName="activeName"/>
     <!-- 移动弹窗 -->
     <moveCustomDia :isShow.sync="isShowMoveDia" :item="dealObj" v-if="isShowMoveDia" />
+    <!-- 标记分组弹窗 -->
+    <el-dialog
+        v-dialogDrag 
+        :visible.sync="isChooseGroupDialogShow"
+        :close-on-click-modal="false"
+        :modal-append-to-body="false"
+        title="标记" width="480px" center
+        @close="isChooseGroupDialogShow=false">
+        <div class="dialog-container">
+            <div class="select" style="display:flex;align-items: center;">
+                <span>分组:</span>
+                <el-select v-model="choosed_group" placeholder="请选择分组" style="flex:1;margin-left: 10px;">
+                    <el-option v-for="item in groupArr" :key="item.name" :label="item.name" :value="item.name"> </el-option>
+                </el-select>
+            </div>
+        </div>
+        <div style="display:flex;justify-content:center;margin:20px 0;">
+            <el-button type="primary" style="width:80px;marginRight:24px;" @click="chooseGroup">保存</el-button>
+            <el-button type="primary" plain style="width:80px;" @click="isChooseGroupDialogShow=false">取消</el-button>
+        </div>
+	</el-dialog>
   </div>
 </template>
 
@@ -94,6 +136,7 @@ export default {
       tableData: [],
       tableColums: [],
       activeName: 1,
+      activeItem: { name: "弘则研报", type: 1 },
       total: 0,
       page_no: 1,
       pageSize: 10,
@@ -109,8 +152,18 @@ export default {
         { name: "冻结", value: 4 },
         {name:'试用暂停',value:5}
       ],
+      groupArr:[
+        {name:"楼颖丹组",value:"楼颖丹组"},
+        {name:"时代组",value:"时代组"},
+        {name:"岳梦琳组",value:"岳梦琳组"},
+        {name:"权益组",value:"权益组"}
+        ],
+      choosed_group:'',
+      choosed_row:null,
       custom_type:[],
       custom_apply_type:'',//申请类型
+      date_range:[],
+      group_type:'',
       applyArr:[
         {name:'已申请',value:'已申请'},
         {name:'未申请',value:'未申请'},
@@ -122,6 +175,7 @@ export default {
       dealObj: {},
       isShowDia: false, //处理弹窗
       isShowMoveDia: false, //移动弹窗
+      isChooseGroupDialogShow:false
     };
   },
   computed: {
@@ -147,26 +201,17 @@ export default {
       return this.custom_type.join(',')
     },//筛选客户的类型,可多选
   },
-  watch: {
-    search_txt(newval) {
-			this.page_no = 1;
-			this.getTableData();
-		},
-		custom_type(newval) {
-			this.page_no = 1;
-			this.getTableData();
-		},
-    custom_apply_type(newval){
-      this.page_no = 1;
-			this.getTableData();
-    }
-  },
+  watch: {},
   created() {},
   mounted() {
     this.tableColums = tableColums(1);
     this.getTableData();
   },
   methods: {
+    changeQuery(){
+        this.page_no = 1
+        this.getTableData()
+    },
     /* 获取表格数据 */
     async getTableData() {
       this.tableLoading = true;
@@ -177,13 +222,19 @@ export default {
               CurrentIndex: this.page_no,
               KeyWord: this.search_txt,
               States: this.search_type,
-              ApplyStatus:this.custom_apply_type
+              ApplyStatus:this.custom_apply_type,
+              MarkGroup:this.group_type,
+              StartDate:this.date_range[0],
+              EndDate:this.date_range[1],
             })
           : await customInterence.trialList({
-              PageSize: 10,
+              PageSize: this.pageSize,
               CurrentIndex: this.page_no,
               SourceType: this.activeName == 2 ? "中文官网" : this.activeName == 3 ? "英文官网" : "",
               KeyWord: this.search_txt,
+              MarkGroup:this.group_type,
+              StartDate:this.date_range[0],
+              EndDate:this.date_range[1],
             });
 
       if (res.Ret === 200) {
@@ -198,6 +249,13 @@ export default {
         this.activeName = item.type;
         this.tableColums = tableColums(this.activeName);
       }
+      //重置筛选项
+      this.search_txt=''
+      this.custom_type=[]
+      this.custom_apply_type=[]
+      this.date_range=[]
+      this.group_type=''
+
       this.page_no = 1;
       this.getTableData();
     },
@@ -236,10 +294,10 @@ export default {
       this.isRead = true;
     },
     /* 关闭阅读报告弹窗 */
-		cancelRead() {
-			this.readTit = '阅读报告列表';
-			this.isRead = false;
-		},
+    cancelRead() {
+        this.readTit = '阅读报告列表';
+        this.isRead = false;
+    },
     // 移动
     moveHandle(item) {
       this.dealObj = item;
@@ -269,12 +327,45 @@ export default {
       }).catch(() => {
                   
       });
+    },
+    //打开标记分组弹窗
+    handleChooseGroup(row){
+        this.choosed_row = row
+        this.choosed_group=''
+        this.isChooseGroupDialogShow = true
+    },
+    //标记分组
+    async chooseGroup(){
+        if(!this.choosed_group){
+            this.$message.warning('请选择分组')
+            return 
+        }
+        const {ApplyRecordId,UserId,Id} = this.choosed_row
+        //请求接口
+        const res = this.activeName===1?await customInterence.markApplyUser({
+            ApplyRecordId,UserId,GroupName:this.choosed_group
+        }):await customInterence.markOfficialUser({Id,GroupName:this.choosed_group})
+
+        if(res.Ret!==200) return 
+        this.$message.success('标记分组成功')
+        this.isChooseGroupDialogShow = false
+        this.choosed_group=''
+        this.getTableData()
+        
     }
   },
 };
 </script>
-<style scoped lang="less">
+<style lang="scss">
+.container-userapplication{
+    .mx-datepicker{
+        width:200px !important;
+    }
+}
+</style>
+<style scoped lang="scss">
 .container-userapplication {
+    min-width: 1500px;
   .userapplication-top {
     display:flex;
     align-items:center;
@@ -305,10 +396,19 @@ export default {
       color: #409eff;
       border-radius: 4px;
       margin-right: 20px;
+      cursor: pointer;
     }
   }
   .export-select {
     display: flex;
+    flex: 1;
+    justify-content: flex-start;
+    align-items: flex-start;
+    gap: 10px;
+    margin-bottom: 20px;
+    .el-input{
+        margin-left: auto;
+    }
   }
 }
 </style>

+ 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];

+ 24 - 5
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">
@@ -358,7 +359,12 @@ export default {
       videoAndVoiceList: [],
     };
   },
-  computed: {},
+  computed: {
+    // 弘则 研选 是否是研选
+    isResearch(){
+      return this.$route.path.indexOf("Purchaser")!=-1?true:false
+    }
+  },
   mixins: [richTextMixins],
   watch: {
     radio: {
@@ -387,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();
@@ -523,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) => {
@@ -652,6 +669,8 @@ export default {
         PointsSet,
         BackgroundImg:this.defaultImage,
         ShareImg:this.shareImg,
+        IsResearch:this.optionFormregion.includes('研选')?true:false,
+        IsShowHz:RefPage.isShowHz?1:0
       });
 
       if (res.Ret !== 200) return;
@@ -660,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;
         }
@@ -668,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;

+ 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: {

+ 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 - 0
src/views/rai_manage/components/addChoiceness.vue

@@ -487,6 +487,7 @@ export default {
             return this.$message.error("请输入公司标签");
           }
           let params = this.dataHandle(type);
+          // console.log(params);
           if (type == "预览") {
             sessionStorage.setItem("choicenessPre", JSON.stringify(params));
             let { href } = this.$router.resolve({ name: "预览报告精选" });

+ 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

+ 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() {

+ 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>

BIN
static/fa.png