瀏覽代碼

Merge branch 'master' into cygx_12.8.1

bding 1 年之前
父節點
當前提交
fe7c0349e6
共有 46 個文件被更改,包括 3783 次插入875 次删除
  1. 1 0
      config/index.js
  2. 11 0
      src/api/modules/crmApi.js
  3. 25 4
      src/api/modules/rai/YanXuanApi.js
  4. 63 1
      src/api/modules/statisticApi.js
  5. 二進制
      src/assets/img/icons/gpt-4-turbo.png
  6. 二進制
      src/assets/img/icons/gpt-4.png
  7. 二進制
      src/assets/img/icons/like-heart.png
  8. 16 0
      src/routes/modules/sellerRoutes.js
  9. 12 0
      src/routes/modules/statisticRoutes.js
  10. 56 5
      src/views/Login.vue
  11. 4 6
      src/views/business_ETA_manage/businessAuth.vue
  12. 15 11
      src/views/custom_manage/compontents/Contactdialog.vue
  13. 1 1
      src/views/custom_manage/contacts/contactsList.vue
  14. 5 0
      src/views/custom_manage/contacts/mixins/mutualAssistance.js
  15. 44 1
      src/views/custom_manage/customList/customDetail.vue
  16. 83 10
      src/views/custom_manage/customList/customShareList.vue
  17. 162 0
      src/views/dataReport_manage/components/abnormalRenewalChart.vue
  18. 67 0
      src/views/dataReport_manage/components/previousDetail.vue
  19. 380 291
      src/views/dataReport_manage/configdata.js
  20. 677 0
      src/views/dataReport_manage/equityCustomStatistics.vue
  21. 466 0
      src/views/dataReport_manage/equityPackageStatistics.vue
  22. 1 0
      src/views/dataReport_manage/index.scss
  23. 172 0
      src/views/dataReport_manage/statistic/abnormalRenewal.vue
  24. 100 22
      src/views/dataReport_manage/statistic/contractCustom.vue
  25. 52 13
      src/views/dataReport_manage/statistic/mixin.js
  26. 42 3
      src/views/dataReport_manage/statistic/newCustom.vue
  27. 0 3
      src/views/dataReport_manage/statistic/todoTask.vue
  28. 6 1
      src/views/login_manage/EmailModel.vue
  29. 7 1
      src/views/login_manage/MobileModel.vue
  30. 1 1
      src/views/login_manage/modelMixins.js
  31. 21 8
      src/views/operation_manage/AIQA/AIQA.vue
  32. 4 2
      src/views/operation_manage/AIQA/components/messageItem.vue
  33. 2 3
      src/views/operation_manage/AIQA/components/newWindowHint.vue
  34. 119 132
      src/views/rai_manage/components/addChoiceness.vue
  35. 58 9
      src/views/rai_manage/components/addRoadshow.vue
  36. 55 1
      src/views/rai_manage/components/addSummary.vue
  37. 1 2
      src/views/rai_manage/components/apply/applyDialog.vue
  38. 1 0
      src/views/rai_manage/components/reportComponents/RichTextMixins.js
  39. 14 1
      src/views/rai_manage/components/richText.vue
  40. 9 2
      src/views/rai_manage/cygxManage/lableManage.vue
  41. 56 43
      src/views/rai_manage/reportManage/components/addHaveReport.vue
  42. 79 0
      src/views/rai_manage/reportManage/components/collectFansDlg.vue
  43. 1 1
      src/views/rai_manage/reportManage/components/specialDlg.vue
  44. 183 0
      src/views/rai_manage/reportManage/components/yanXuanLable.js
  45. 355 297
      src/views/rai_manage/reportManage/yanXuanSpecial.vue
  46. 356 0
      src/views/rai_manage/reportManage/yanxuan.vue

+ 1 - 0
config/index.js

@@ -40,6 +40,7 @@ module.exports = {
 			// target:'http://rddpapi.brilliantstart.cn', // 接口的域名
 			// target:'https://admin.hzinsights.com', // 接口的域名
 	  	   target:'http://8.136.199.33:7777', // 接口的域名
+	  	  //  target:'http://192.168.77.7:8602', // 接口的域名
 			// secure:false,  // 如果是https接口,需要配置这个参数
 			changeOrigin:true, // 如果接口跨域,需要进行这个参数配置
 			pathRewrite:{

+ 11 - 0
src/api/modules/crmApi.js

@@ -249,6 +249,13 @@ const customInterence = {
   concactEdit: (params) => {
     return http.post("/custom/user/edit", params);
   },
+  /* 关注/取消关注 联系人
+  UserId CompanyId
+  Type 0取关 1关注
+  */
+  concactFollow: (params) => {
+    return http.post("/custom/follow", params);
+  },
   /* 获取权限基本信息 */
   authList: (params) => {
     return http.get("/custom/permission/list", params);
@@ -699,6 +706,10 @@ const customInterence = {
   getSalesData: (params) => {
     return http.get("/custom/receive/seller", params);
   },
+  //权益销售列表
+  getSalesRaiData: (params) => {
+    return http.get("/custom/seller/check/list_rai", params);
+  },
   //启用/禁用权限
   changeSaleAuth: (params) => {
     return http.post("/custom/receive/permission/change", params);

+ 25 - 4
src/api/modules/rai/YanXuanApi.js

@@ -1,10 +1,6 @@
 import http from "@/api/http.js";
 /* 权益小程序管理 报告模块*/
 const YanXuanApi = {
-  // 作者列表
-  yanxuan_specialAuthorList: (params) => {
-    return http.get("/cygx/yanxuan_special/author/list", params);
-  },
   // 新增研选专栏作者
   yanxuan_specialAuthorAdd: (params) => {
     return http.post("/cygx/yanxuan_special/author/add", params);
@@ -25,6 +21,31 @@ const YanXuanApi = {
   yanxuan_tope_change: (params) => {
     return http.post("/cygx/activity/tope_change ", params);
   },
+  // 文章列表
+  yanxuanReportSpecial: (params) => {
+    return http.get("/cygx/yanxuan_special/list", params);
+  },
+  // 审批记录接口
+  yanxuanApprovalLogList: (params) => {
+    return http.get("/cygx/yanxuan_special/approval_log_list", params);
+  },
+  // 作者列表
+  getYanxuanSpecialAuthor: (params) => {
+    return http.get("/cygx/yanxuan_special/author/list", params);
+  },
+  // 收藏详情
+  getYanxuanSpecialCollect: (params) => {
+    return http.get("/cygx/yanxuan_special/special_collect/list", params);
+  },
+  // 作者粉丝列表
+  getYanxuanSpecialFans: (params) => {
+    return http.get("/cygx/yanxuan_special/special_author_fans_list", params);
+  },
+  // 作者管理栏按钮是否展示接口
+  getYanxuanShowButton: (params) => {
+    return http.get("/cygx/yanxuan_special/show_button", params);
+  },
+  
 };
 
 export default YanXuanApi;

+ 63 - 1
src/api/modules/statisticApi.js

@@ -52,6 +52,23 @@ const dataMainInterface = {
 		return http.get('/statistic_report/incremental_company_list',params);
 	},
 	/**
+	 * 权益客户统计列表接口
+	 * @param {PageSize} params 
+	 * @param {CurrentIndex} params 
+	 * @param {EndDate} params 结束日期
+	 * @param {CompanyType} params 
+	 * @param {AdminId } params 销售id,多个用英文逗号隔开,空字符串为全部
+	 * @param {RegionType } params 
+	 * @param {StartDate} params 
+	 * @param {DataType} params 
+	 * @param {IsConfirm} params  是否确认续约: -1-默认全部; 0-待确认; 1-已确认
+	 * @param {CompanyAscribeId} params  归因Id
+	 * @returns  
+	 */
+	incrementalEquityList:params => {
+		return http.get('/statistic_report/merge_company_list',params);
+	},
+	/**
  * 获取未续约备注列表
  * @param {CompanyId} params 公司ID
  * @param {ProductId} params 产品ID 1:FICC ,2权益
@@ -86,6 +103,14 @@ const dataMainInterface = {
 	addAscrib:params => {
 		return http.post('/custom/company_ascribe/add',params);
 	},
+	/**
+	 * 合同通过归因添加确认不续约接口
+	 * @param {KeyWord} params 
+	 * @returns  
+	*/
+	addAscribContract:params => {
+		return http.post('/custom/company_contract_no_renewed_ascribe/add',params);
+	},
 	/**
 	 * 修改归因标签
 	* @param {CompanyId} params 公司ID
@@ -106,6 +131,14 @@ const dataMainInterface = {
 	infoNoRenewedAscribe:params => {
 		return http.get('/custom/company_no_renewed_ascribe/detail',params);
 	},
+	/**
+	 * 合同确认归因不续约详情接口
+	* @param {CompanyContractId} params 合同ID
+	 * @returns  
+	*/
+	contractInfoNoRenewedAscribe:params => {
+		return http.get('/custom/company_contract_no_renewed_ascribe/detail',params);
+	},
 	/**
 	 * 获取收入统计列表接口
 	 * @param {PageSize} params 
@@ -149,6 +182,10 @@ const dataMainInterface = {
 	moreRenewReason:params => {
 		return http.get('/statistic_report/more_renew_reason',params);
 	},
+	// 客户数据未续约说明更多
+	mergeCompanyPreviousDetail:params => {
+		return http.get('/statistic_report/merge_company_previous/detail',params);
+	},
 	/**
 	 * 	// 获取图表阅读统计列表
 	 * @param {PageSize} params 
@@ -212,6 +249,15 @@ const dataMainInterface = {
 		return http.get('/statistic_report/report/renew_company',params)
 	},
 
+	// 续约异常客户统计
+	unusualRenewalCustomStatistic: params => {
+		return http.get('/statistic_report/report/unusual_renew_company',params)
+	},
+	//续约异常客户统计图表数据
+	unusualRenewalCustomStatisticChartData:params=>{
+		return http.get('/statistic_report/report/unusual_renew_company/chart',params)
+	},
+
 	/**
 	 * 新增客户列表
 	 * @param {} params PageSize CurrentIndex SortParam SortType 	CompanyIds
@@ -320,7 +366,23 @@ const dataMainInterface = {
    chartDetailList:params=>{
     return http.post('/statistic_report/report/seller_chart_collect_log/detail',params)
   },
-
+ /**
+  * 权益客户统计列表接口
+  * @param {PageSize} params 
+  * @param {CurrentIndex} params 
+  * @param {EndDate} params 结束日期
+  * @param {CompanyType} params 
+  * @param {AdminId } params 销售id,多个用英文逗号隔开,空字符串为全部
+  * @param {RegionType } params 
+  * @param {StartDate} params 
+  * @param {DataType} params 
+  * @param {IsConfirm} params  是否确认续约: -1-默认全部; 0-待确认; 1-已确认
+  * @param {CompanyAscribeId} params  归因Id
+  * @returns  
+  */
+ incrementalCompanyContractPermissionList:params => {
+ 	return http.get('/statistic_report/merge_company/company_contract_permission/list',params);
+ },
 }
 
 export {

二進制
src/assets/img/icons/gpt-4-turbo.png


二進制
src/assets/img/icons/gpt-4.png


二進制
src/assets/img/icons/like-heart.png


+ 16 - 0
src/routes/modules/sellerRoutes.js

@@ -127,6 +127,22 @@ export default [
 				component: () => import('@/views/custom_manage/saleAuthManage.vue'),
 				hidden: false,
 			},
+			{
+				path:"abnormalRenewal",
+				name: '续约异常统计',
+				component: () => import('@/views/dataReport_manage/statistic/abnormalRenewal.vue'),
+				hidden: false,
+			},
+			{
+				path: 'abnormalRenewalCustomlist',
+				component: () => import('@/views/dataReport_manage/statistic/newCustomlist.vue'),
+				name: '续约异常客户列表',
+				meta: {
+					pathFrom: 'abnormalRenewal',
+					pathName: '续约异常统计' 
+				},
+				hidden: true
+			},
 		]
 	},
 ]

+ 12 - 0
src/routes/modules/statisticRoutes.js

@@ -45,6 +45,18 @@ export default [
 				name: '图库阅读统计',
 				hidden: false
 			},
+			{
+				path: 'equityCustomStatistics',
+				component: () => import('@/views/dataReport_manage/equityCustomStatistics.vue'),
+				name: '权益客户统计',
+				hidden: false
+			},
+			{
+				path: 'equityPackageStatistics',
+				component: () => import('@/views/dataReport_manage/equityPackageStatistics.vue'),
+				name: '权益套餐统计',
+				hidden: false
+			},
 			{
 				path: 'readClassify',
 				component: () => import('@/views/dataReport_manage/readClassify.vue'),

+ 56 - 5
src/views/Login.vue

@@ -90,9 +90,9 @@
 							:areaCode="areaCode"
 						/>
 					</el-tab-pane>
-					<el-tab-pane label="邮箱登录" name="emailModel">
-						<EmailModel ref="emailModel"/>
-					</el-tab-pane>
+					<!-- <el-tab-pane label="邮箱登录" name="emailModel"> -->
+						<EmailModel ref="emailModel" v-show="activeModel=='emailModel'"/>
+					<!-- </el-tab-pane> -->
 				</el-tabs>
 				<el-button
 					type="primary"
@@ -101,6 +101,20 @@
 					:loading="logining"
 					class="submit_btn"
 					>登录</el-button>
+					<div class="another-login-type">
+						<div class="another-type-hint">
+							<div class="type-hint-line"></div>
+							<div class="type-hint-text">其他登录方式</div>
+							<div class="type-hint-line"></div>
+						</div>
+						<div class="another-type">
+							<div class="login-type-item"
+							@click="activeModel='emailModel';handleClick({name:'emailModel'})">
+								<img src="~@/assets/img/icons/email-login-type.png">
+								<span>邮箱登录</span>
+							</div>
+						</div>
+					</div>
 			</div>
 			<div class="login-box" v-else>
 				<ForgetPassModel 
@@ -652,7 +666,7 @@ export default {
 			box-sizing: border-box;
 			border-radius: 10px;
 			position: absolute;
-			top: 31%;
+			top: 18%;
 			right: 14%;
 			z-index: 100;
 			font-size: 30px;
@@ -668,7 +682,7 @@ export default {
 				background: #007eff;
 				font-size: 16px;
 				border-radius: 5px;
-				margin-top: 30px;
+				// margin-top: 30px;
 			}
 			.el-input input {
 				width: 100%;
@@ -712,6 +726,43 @@ export default {
 			.el-form-item {
 				margin-bottom: 30px;
 			}
+
+			.another-login-type{
+				margin-top: 45px;
+				.another-type-hint{
+					display: flex;
+					align-items: center;
+					.type-hint-line{
+						flex: 1;
+						height: 1px;
+						background-color: #C0C4CC;
+					}
+					.type-hint-text{
+						font-size: 18px;
+						color: #999999;
+						padding: 0 20px;
+					}
+				}
+				.another-type{
+					.login-type-item{
+						display: flex;
+						flex-direction: column;
+						justify-content: center;
+						align-items: center;
+						margin-top: 20px;
+						cursor: pointer;
+						img{
+							height: 40px;
+							width: 40px;
+							margin-bottom: 4px;
+						}
+						span{
+							font-size: 16px;
+							color: #666666;
+						}
+					}
+				}
+			}
 		}
 	}
 	@media screen and (max-width:650px) {

+ 4 - 6
src/views/business_ETA_manage/businessAuth.vue

@@ -9,8 +9,6 @@
         </div>
         <div class="model-wrap">
             <el-button :type="model==='auth'?'primary':''" @click="model='auth'">菜单权限</el-button>
-            <span class="block"></span>
-            <el-button :type="model==='interence'?'primary':''" @click="model='interence'">接口权限</el-button>
         </div>
         <div class="auth-wrap" v-show="model==='auth'">
             <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" style="margin-bottom: 20px;">全选</el-checkbox>
@@ -26,7 +24,7 @@
                 @check-change="()=>{handleCheckChange()}">
             </el-tree>
         </div>
-        <div class="interence-wrap" v-show="model==='interence'">
+        <!-- <div class="interence-wrap" v-show="model==='interence'">
             <div class="interence-item">
                 <span>研报审批</span>
                 <el-radio-group v-model="isApprove">
@@ -38,7 +36,7 @@
                     <el-checkbox :label="1">研报列表</el-checkbox>
                 </el-checkbox-group>
             </div>
-        </div>
+        </div> -->
     </div>
 </template>
 
@@ -178,7 +176,7 @@ export default {
                 if(res.Ret!==200) return 
                 this.$message.success('权限设置成功')
 
-                if(typeof(this.isApprove)==='string'){
+                /* if(typeof(this.isApprove)==='string'){
                     this.$message.warning('请配置接口权限')
                     this.model='interence'
                     return
@@ -200,7 +198,7 @@ export default {
                     })
                     if(interenceRes.Ret!==200) return 
                     this.$message.success('接口权限设置成功')
-                }
+                } */
             }
             this.$router.push('/businessETAList')
         },

+ 15 - 11
src/views/custom_manage/compontents/Contactdialog.vue

@@ -201,7 +201,7 @@
 
 <script>
 import { validateTel, validatePwd } from "@/utils/validate.js";
-import { customInterence } from "@/api/api.js";
+import { customInterence, departInterence } from "@/api/api.js";
 import { lang } from 'moment';
 export default {
   name: "",
@@ -276,16 +276,7 @@ export default {
       }
     };
     return {
-      telCodeArr: [
-        { value: '86', label: '+86' },
-        { value: '852', label: "+852" },
-        { value: '886', label: '+886' },
-        { value: '1', label: '+1' },
-        { value: '65', label: '+65' },
-        { value: '62', label: '+62' },
-        { value:'081',label: '+081' },
-        { value:'44',label: '+44' }
-      ],
+      telCodeArr: [],
 
       isHaveUser: false, //已存在联系人弹窗
       uploadloading: false,
@@ -329,6 +320,18 @@ export default {
     };
   },
   methods: {
+    getPhoneCode(){
+        departInterence.getPhoneAreaCode().then(res=>{
+            if(res.Ret!==200) return 
+            this.telCodeArr = res.Data||[]
+            this.telCodeArr = this.telCodeArr.map(i=>{
+                return {
+                    value:i.Value,
+                    label:i.Name
+                }
+            })
+        })
+    },
     // 领取自己的流失客户点击下一步
     handleNext() {
       this.$refs.userForm.validate((valid) => {
@@ -728,6 +731,7 @@ export default {
   },
   watch: {
     isAddContact() {
+        this.getPhoneCode()
       if (this.userForm.Source) {
         this.userFormIndeterminacy = this.userForm.Source
       } else {

+ 1 - 1
src/views/custom_manage/contacts/contactsList.vue

@@ -262,7 +262,7 @@ export default {
     },
     /* 获取销售 */
     getSale() {
-      customInterence.getSale().then((res) => {
+      customInterence.getSalesRaiData().then((res) => {
         if (res.Ret === 200) {
           this.salesArr = res.Data.List;
         }

+ 5 - 0
src/views/custom_manage/contacts/mixins/mutualAssistance.js

@@ -109,6 +109,11 @@ export const mutualMixin = {
     /* 表格行的点击事件 */
     handleRowClick(row, key) {
       if (key === "Title") {
+        if (row.SpecialType > 0) {
+          let href = `${process.env.CYGX_WEB}/column/detail/${row.ArticleId}`;
+          window.open(href, "_blank");
+          return;
+        }
         if (row.ArticleType == 1) {
           let url =
             process.env.NODE_ENV === "production"

+ 44 - 1
src/views/custom_manage/customList/customDetail.vue

@@ -210,6 +210,7 @@
 				ref="userTable"
 				:data="userTable"
 				v-loading="isShowloadding"
+				:row-class-name="setRowClass"
 				element-loading-text="数据加载中..."
 				border>
 					<el-table-column
@@ -224,6 +225,7 @@
 							<img :src="$icons.card" alt="" style="width:17px;cursor:pointer;marginRight:5px;"
 							v-if="scope.row.BusinessCardUrl"
 							@click="reviewCard(scope.row.BusinessCardUrl)">
+							<img src="~@/assets/img/icons/like-heart.png" class="name-follow-heart" v-if="scope.row.IsFollow==1">
 							<span :class="{'isShared':scope.row.IsShared}">{{scope.row.RealName}}</span>
 						</template>
 					</el-table-column>
@@ -309,6 +311,9 @@
 							<div class="contact-opt-box" style="color:#4099ef; font-size:14px;">
 								<span  class="editsty" @click="editContact(scope.row)">编辑</span>
 								<span class="editsty move" style="margin:0 5px;" @click="handleShowMove(scope.row)">移动</span>
+								<span style="margin-right:5px;" :class="scope.row.IsFollow==1?'deletesty':'editsty'"
+								@click="followContact(scope.row)"
+								>{{ scope.row.IsFollow==1?'取消关注':'关注' }}</span>
 								<span class="deletesty" @click.stop="delConcat(scope.row)">删除</span>
 								<!-- <block v-if="RoleType!='权益'&&ficcform&&['正式','试用','永续'].includes(ficcform.Status)">
 								<span 
@@ -1259,7 +1264,29 @@ export default {
 			this.isAddContact = true;
 			this.diatit = '编辑联系人';
 		},
-		
+		// 关注与取消关注
+		followContact(row){
+			// console.log(row);
+			let isFollow = row.IsFollow==1
+			let confirmText = isFollow?'是否取消':'是否设为'
+			this.$confirm(`${confirmText}特别关注?`, "提示", {
+        type: "warning",
+      }).then(() => {
+				let params={
+					UserId:row.UserId,
+					CompanyId:row.CompanyId,
+					Type:isFollow?0:1
+				}
+				customInterence.concactFollow(params).then(res=>{
+					if(res.Ret == 200){
+						this.$message.success(isFollow?"取消成功":"关注成功")
+						this.getuserTable()
+					}
+				})
+
+			})
+			.catch(() => {});
+		},
 		// 删除联系人判断 试用、正式、永续、冻结状态下的客户 如只剩一个联系人不允许删除
 		/**
 		 * 1.如果是非管理员用户则直接根据数量判断
@@ -1538,6 +1565,12 @@ export default {
 		this.isShowDlgType = type
 		this.isShowResearchNumber =true
 	},
+	// 设置表格行的样式
+	setRowClass({row}){
+		if(row.NotRead && row.IsFollow==1){
+			return "not-read-seven-days"
+		}
+	}
 	},
 	mounted() {
 		this.getDetail();
@@ -1677,6 +1710,16 @@ export default {
 		align-items: center;
 		margin-bottom: 28px;
 	}
+	.name-follow-heart{
+		width:25px;
+		height: 15px;
+		position: absolute;
+		left: 0;
+    top: 0;
+	}
+	.not-read-seven-days{
+		background-color: #FFF8F8;
+	}
 }
 .customDetail_contract_dialog {
 	max-height: 810px;

+ 83 - 10
src/views/custom_manage/customList/customShareList.vue

@@ -3,10 +3,23 @@
 	<div class="customList_container" id="customList_container" ref="cusContainer">
 		<div class="customList_bot">
       <div class="customList_bot_search">
-        <div style="margin-bottom: 8px;" v-if="Role=='thisAdmin'">
+        <div style="margin-bottom: 8px;" v-if="!IsShareGroup">
           <el-select v-model="status" placeholder="请选择状态" @change="getTableData" style="width: 214px; margin-right: 20px;">
-            <el-option :label="item" :value="index" v-for="(item,index) in statusList" :key="index" ></el-option>
+            <el-option :label="item.label" :value="item.value" v-for="(item,index) in statusList" :key="index" ></el-option>
           </el-select>
+		  <el-cascader
+			v-model="originalSales"
+			placeholder="请选择原销售"
+			style="width:240px;marginRight:10px;marginBottom:8px;"
+			:options="originalSalesArr"
+			:props="defaultSalesProps"
+			:show-all-levels="false"
+			collapse-tags
+			clearable
+			filterable
+			@change="getTableData"
+			v-if="roleType!=='ficc_seller'"
+		  />
           <el-select v-model="sales" placeholder="请选择分配销售" style="width: 214px; margin-right: 20px;" 
           clearable filterable multiple collapse-tags @change="getTableData">
             <el-option :label="item.RealName" :value="item.AdminId" v-for="item in salesArr" :key="item.AdminId" ></el-option>
@@ -14,7 +27,19 @@
         </div>
         <div v-else>
             <el-button type="primary" @click="$router.push('/customCityList')">查看同城客户</el-button>
-        </div>
+			<el-cascader
+				v-model="originalSales"
+				placeholder="请选择原销售"
+				style="width:200px;marginRight:10px;marginBottom:8px;"
+				:options="originalSalesArr"
+				:props="defaultSalesProps"
+				:show-all-levels="false"
+				collapse-tags
+				clearable
+				filterable
+				@change="getTableData"
+			/>
+        </div> 
         <el-input 
           placeholder="客户名称/社会信用码/手机号码/邮箱"
           v-model="search_txt"
@@ -300,7 +325,7 @@
 										<el-dropdown-menu slot="dropdown">
 											<el-dropdown-item :command="{type:item.type,data:scope.row}" 
 											v-for="item in getToolBtnList(scope.row).slice(3)" :key="item.type">
-												<span>{{item.type}}</span>
+												<span>{{item.type=='设置共享'&&scope.row.IsShare==1?'取消共享':item.type}}</span>
 											</el-dropdown-item>
 										</el-dropdown-menu>
 									</span>
@@ -464,18 +489,21 @@ export default {
 			}else{
 				return 'thisSeller';
 			}
+		},
+		roleType(){
+			return localStorage.getItem('Role') || ''
 		}
 	},
 	data () {
 
-		this.statusList = ['全部','已分配','待分配']
+		this.statusList = [{label:'未共享',value:3},{label:'已分配',value:1},{label:'待分配',value:2}]
 		return {
 			adminId:localStorage.getItem('AdminId'),
 			sales:[],
 			salesArr:[],//销售
 			tableData:[],
 			isShowloadding:false,
-			status:2,
+			status:'',
 			search_txt:'',
 			total:0,
 			page_no:1,
@@ -505,7 +533,8 @@ export default {
 				BtnAddAgreement: '补充协议',
 				BtnTryOut: '增开试用',
 				BtnServiceRecord:'服务记录',
-				BtnRemarkView:'备注'
+				BtnRemarkView:'备注',
+				BtnShare:'设置共享',
 			},	// 按钮命令列表
 			accumulativeFrequencyDlg:false,//路演业阅读的弹框
 			accumulativeFrequencyItem:{},
@@ -523,26 +552,48 @@ export default {
 			completeForm:{},
 			isAddTrial:false,
 			authList:[],
+
+			originalSales:'',
+			originalSalesArr:[],
+			defaultSalesProps:{
+				multiple: true,
+				label:'RealName',
+				children:'ChildrenList',
+				value:'AdminId'
+			},//销售级联配置
+
+			IsShareGroup:false,//是否为咨询组销售
 		};
 	},
 	methods: {
 		/* 获取表格 */
 		getTableData() {
 			this.isShowloadding = true;
+			// 处理销售筛选
+			let salesArr=[]
+			if(this.originalSales.length){
+				salesArr=this.originalSales.map(item=>{
+					return item[item.length-1]
+				})
+			}
+
 			let params = {
 				SortParam:this.sort_param,//自定义排序字段
 				SortType:this.sort_type,//排序方式
 				PageSize:this.pageSize,
 				CurrentIndex:this.page_no,
 				Keyword:this.search_txt,
-				ListParam:this.Role=='thisSeller'?1:this.status, // 销售只能看分配给自己的共享客户,即状态需要是已分配
-				SellerId:this.sales.join(',')
+				ListParam:this.status, 
+				SellerId:this.sales.join(','),
+				OriginalSellerId:salesArr.join(','),
 			}
 			customInterence.getShareCustomList(params).then(res => {
 				if(res.Ret === 200) {
 					this.total = res.Data.Paging.Totals || 0;
 					this.tableData = res.Data.List || [];
 					this.isShowloadding = false;
+					this.IsShareGroup=res.Data.IsShareGroup||false
+					this.status=res.Data.Status
 				}
 			})
 		},
@@ -587,10 +638,21 @@ export default {
 				this.handleShowRemark(query.data)
 			}else if(["续约申请","补充协议"].includes(query.type)){
 				this.handleOpenContractChoose(query.type,query.data)
-			}else if("增开试用"){
+			}else if(query.type=="增开试用"){
 				this.addTrialHandle(query.data)
+			}else if(query.type=='设置共享' || query.type=='取消共享'){
+				this.shareSetting(query.data)
 			}
 		},
+		// 设置/取消 共享
+		shareSetting(row){
+			customInterence.setCustomShare({CompanyId:row.CompanyId,IsShare:row.IsShare==0?1:0}).then(res=>{
+				if(res.Ret==200){
+					this.$message.success(row.IsShare==0?'设置共享成功':'取消共享成功')
+					this.getTableData()
+				}
+			})
+		},
 		/* 查看权限 */
 		lookHandle(item) {
 			this.lookTitle = item.CompanyName;
@@ -944,9 +1006,20 @@ export default {
 			this.addTryId = item.CompanyId;
 			this.isAddTrial = true;
 		},
+
+		/* 获取销售 */
+		getoriginalSale() {
+			let status=0;
+			customInterence.getSale({"Status":status}).then(res => {
+				if(res.Ret === 200) {
+					this.originalSalesArr = res.Data.List||[];
+				}
+			})
+		},
 	},
 	created() {
 		this.getSale()
+		this.getoriginalSale()
 		this.getTableData()
 	}
 }

+ 162 - 0
src/views/dataReport_manage/components/abnormalRenewalChart.vue

@@ -0,0 +1,162 @@
+<template>
+    <div class="abnormal-renewal-chart-wrap">
+        <div class="top-wrap">
+            <el-date-picker
+                v-model="date"
+                type="monthrange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                :clearable="false"
+                value-format="yyyy-MM"
+                @change="handleDateChange"
+            />
+            <div style="color:#409EFF;cursor: pointer;" @click="handleClose">
+                <img src="~@/assets/img/icons/changeLang.png" alt="">
+                <span style="display:inline-block;position: relative;top:-3px;left:3px">数据表</span>
+            </div>
+        </div>
+        <div class="chart-main-wrap">
+            <h2 style="text-align:center;font-size:30px;margin:30px 0;">续约异常客户统计图</h2>
+            <div class="chart-box" ref="chartBox"></div>
+        </div>
+    </div>
+</template>
+
+<script>
+import { dataMainInterface } from '@/api/api.js';
+import { nextTick } from 'vue';
+export default {
+    data() {
+        return {
+            date:'',
+            myChart:null
+        }
+    },
+    created() {
+        this.date=[this.$moment().format('YYYY-01'),this.$moment().format('YYYY-MM')]
+    },
+    mounted() {
+        this.getData()
+    },
+    methods: {
+        async getData(){
+            const res=await dataMainInterface.unusualRenewalCustomStatisticChartData({
+                StartDate:this.date[0],
+                EndDate:this.date[1]
+            })
+            if(res.Ret===200){
+                this.$nextTick(()=>{
+                    this.renderChart(res.Data)
+                })
+            }
+        },
+        handleDateChange(){
+            this.getData()
+        },
+        handleClose(){
+            this.$emit('close')
+        },
+        renderChart(data){
+            const arr=data.List||[]
+
+            const options={
+				legend: {
+					name: [],
+                    icon:'circle',
+					left: 'center',
+				},
+				tooltip: {
+                    formatter:function(params){
+                        let str=`${params.name}<br>
+                        <span style='display:inline-block;width:15px;height:15px;background:#FDB863;border-radius:100%'></span>
+                        ${params.seriesName}&nbsp;&nbsp;${params.value}`
+
+                        return str
+                    }
+                },
+				title: {
+					text: '',
+				},
+				color: ['#FDB863'],
+				textStyle: {
+					fontSize: 12,
+				},
+				xAxis: {
+					type: '',
+					data: [],
+					// /* x轴文字 */
+					axisLabel: {
+						show: true,
+						rotate: '40', //字体倾斜
+						textStyle: {
+							color: '#999', //更改坐标轴文字颜色
+							fontSize: 12, //更改坐标轴文字大小
+						},
+					},
+				},
+				yAxis: {
+					type: 'value',
+					minInterval:1,
+                    position: 'left',
+                    name:'家',
+                    splitLine:{
+                        lineStyle:{
+                            type:'dotted'
+                        }
+                    }
+				},
+				series: [
+                    {
+                        data:[],
+                        name:'续约异常客户合计',
+                        type:'bar',
+                        yAxisIndex: 0,
+                    }
+                ],
+			}
+
+            arr.forEach(item => {
+                options.xAxis.data.push(item.Date)
+                options.series[0].data.push(item.CompanyNum)
+            });
+
+            console.log(options);
+
+            const chart = this.$refs.chartBox;
+            if(chart){
+                this.$nextTick(()=>{
+                    if(!this.myChart){
+                        this.myChart = echarts.init(chart);
+                        this.myChart.setOption(options);
+                    }else{
+                        this.myChart.setOption(options,true);
+                    }
+                    
+                })
+            }
+        }
+    },
+}
+</script>
+
+<style lang="scss" scoped>
+.abnormal-renewal-chart-wrap{
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: #fff;
+    padding: 30px;
+    .top-wrap{
+        display: flex;
+        justify-content: space-between;
+    }
+    .chart-box{
+        margin: 0 auto;
+        width: 80%;
+        height: 500px;
+    }
+}
+</style>

+ 67 - 0
src/views/dataReport_manage/components/previousDetail.vue

@@ -0,0 +1,67 @@
+<template>
+  <el-dialog v-dialogDrag :visible.sync="previousDetailDlg" @close="handleClose" :modal-append-to-body="false" center title="维持套餐">
+    <p>上一份合同信息</p>
+    <el-table :data="dataList" border max-height="250" style="margin: 20px 0">
+      <el-table-column label="合同期限" prop="StartDate" align="center" width="220">
+        <template slot-scope="{ row }">
+          <span> {{ row.StartDate }} ~ {{ row.EndDate }} </span>
+        </template>
+      </el-table-column>
+      <el-table-column label="合同金额" prop="Money" align="center" />
+      <el-table-column label="签约套餐" prop="PermissionName" align="center">
+        <template slot-scope="{ row }">
+          <template v-if="row.PermissionName.length">
+            <el-tag size="mini" style="margin: 0 10px 10px 0" v-for="key in row.PermissionName.split(',')" :key="key">{{ key }}</el-tag>
+          </template>
+        </template>
+      </el-table-column>
+    </el-table>
+  </el-dialog>
+</template>
+
+<script>
+import { dataMainInterface } from "@/api/api.js";
+export default {
+  props: {
+    rowInfo: {
+      type: Object,
+      default: null,
+    },
+    previousDetailDlg: {
+      type: Boolean,
+      require: true,
+    },
+  },
+  data() {
+    return {
+      dataList: [],
+    };
+  },
+  methods: {
+    handleClose() {
+      this.$emit("update:previousDetailDlg", false);
+    },
+    async getrenewalReasonList() {
+      console.log(this.rowInfo);
+      const res = await dataMainInterface.mergeCompanyPreviousDetail({
+        CompanyContractId: this.rowInfo.CompanyContractId,
+      });
+      if (res.Ret == 200) {
+        this.dataList = [res.Data.Detail];
+        console.log(this.dataList);
+      }
+    },
+  },
+  watch: {
+    previousDetailDlg(val) {
+      if (val) {
+        this.getrenewalReasonList();
+      } else {
+        this.renewalList = [];
+      }
+    },
+  },
+};
+</script>
+
+<style></style>

+ 380 - 291
src/views/dataReport_manage/configdata.js

@@ -1,302 +1,391 @@
 export const monthLabel = [
-	{
-		label: "未来一个月"
-	},
-	{
-		label: "未来2个月"
-	},
-	{
-		label: "未来3个月"
-	}
-]
+  {
+    label: "未来一个月",
+  },
+  {
+    label: "未来2个月",
+  },
+  {
+    label: "未来3个月",
+  },
+];
 /* 即将到期表格列 */
 export const expringTableColums = [
-	{
-		label:"客户名称",
-		align:"center",
-		key:"CompanyName",
-		widthsty:'300px',
-		textsty:"color:#409EFF;cursor:pointer;",
-		link:true
-	},
-	{
-		label:"客户类型",
-		align:"center",
-		key:"ProductName",
-		widthsty:'100px'
-	},
-	{
-		label:"所属销售",
-		align:"center",
-		key:"SellerName"
-	},
-	// {
-	// 	label:"合同编号",
-	// 	align:"center",
-	// 	key:"ContractCode"
-	// },
-	// {
-	// 	label:"合同金额",
-	// 	align:"center",
-	// 	key:"Money"
-	// },
-	{
-		label:"服务期限",
-		align:"center",
-		key:""
-	},
-	{
-		label:"剩余天数",
-		align:"center",
-		key:"ExpireDay",
-		widthsty:'100px',
-		sort:true
-	},
-]
+  {
+    label: "客户名称",
+    align: "center",
+    key: "CompanyName",
+    widthsty: "300px",
+    textsty: "color:#409EFF;cursor:pointer;",
+    link: true,
+  },
+  {
+    label: "客户类型",
+    align: "center",
+    key: "ProductName",
+    widthsty: "100px",
+  },
+  {
+    label: "所属销售",
+    align: "center",
+    key: "SellerName",
+  },
+  // {
+  // 	label:"合同编号",
+  // 	align:"center",
+  // 	key:"ContractCode"
+  // },
+  // {
+  // 	label:"合同金额",
+  // 	align:"center",
+  // 	key:"Money"
+  // },
+  {
+    label: "服务期限",
+    align: "center",
+    key: "",
+  },
+  {
+    label: "剩余天数",
+    align: "center",
+    key: "ExpireDay",
+    widthsty: "100px",
+    sort: true,
+  },
+];
 /* 增量客户表格列 */
 export const incrementTableColums = [
-	{
-		label:"客户名称",
-		key:"CompanyName",
-		widthsty:'300px',
-		textsty:"color:#409EFF;cursor:pointer;",
-		link:true,
-	},
-	{
-		label:"客户类型",
-		key:"ProductName",
-		widthsty:'100px'
-	},
-	{
-		label:"不续约归因",
-		key:"AscribeContent",
-		dataType:"未续约客户",
-		notRenewedConfirm:1,
-		sort:true
-	},
-	{
-		label:"客户状态",
-		key:"Status",
-		dataType:"未续约客户",
-		sort:true
-	},
-	{
-		label:"所属销售",
-		key:"SellerName",
-		widthsty:'150px'
-	},
-	{
-		label:"新增时间",
-		key:"CreateTime",
-		dataType:"新增试用客户",
-		sort:true
-	},
-	{
-		label:"合同金额",
-		key:"Money",
-		dataType:"新签客户",
-		sort:true
-	},
-	{
-		label:"签约时间",
-		key:"StartDate",
-		dataType:"新签客户",
-		sort:true
-	},
-	{
-		label:"合同金额",
-		key:"Money",
-		dataType:"续约客户",
-		sort:true
-	},
-	{
-		label:"续约时间",
-		key:"StartDate",
-		dataType:"续约客户",
-		sort:true
-	},
-	{
-		label:"最近合同到期时间",
-		key:"EndDate",
-		dataType:"未续约客户",
-		sort:true
-	},
-	{
-		label:"备注",
-		key:"Remark",
-		dataType:"未续约客户",
-		widthsty:'100px',
-		sort:true
-	},
-	{
-		label:"未续约说明",
-		key:"RenewalReason",
-		dataType:"未续约客户",
-		widthsty:'300px',
-		sort:true
-	}
-]
+  {
+    label: "客户名称",
+    key: "CompanyName",
+    widthsty: "300px",
+    textsty: "color:#409EFF;cursor:pointer;",
+    link: true,
+  },
+  {
+    label: "客户类型",
+    key: "ProductName",
+    widthsty: "100px",
+  },
+  {
+    label: "不续约归因",
+    key: "AscribeContent",
+    dataType: "未续约客户",
+    notRenewedConfirm: 1,
+    sort: true,
+  },
+  {
+    label: "客户状态",
+    key: "Status",
+    dataType: "未续约客户",
+    sort: true,
+  },
+  {
+    label: "所属销售",
+    key: "SellerName",
+    widthsty: "150px",
+  },
+  {
+    label: "新增时间",
+    key: "CreateTime",
+    dataType: "新增试用客户",
+    sort: true,
+  },
+  {
+    label: "合同金额",
+    key: "Money",
+    dataType: "新签客户",
+    sort: true,
+  },
+  {
+    label: "签约时间",
+    key: "StartDate",
+    dataType: "新签客户",
+    sort: true,
+  },
+  {
+    label: "合同金额",
+    key: "Money",
+    dataType: "续约客户",
+    sort: true,
+  },
+  {
+    label: "续约时间",
+    key: "StartDate",
+    dataType: "续约客户",
+    sort: true,
+  },
+  {
+    label: "最近合同到期时间",
+    key: "EndDate",
+    dataType: "未续约客户",
+    sort: true,
+  },
+  {
+    label: "备注",
+    key: "Remark",
+    dataType: "未续约客户",
+    widthsty: "100px",
+    sort: true,
+  },
+  {
+    label: "未续约说明",
+    key: "RenewalReason",
+    dataType: "未续约客户",
+    widthsty: "300px",
+    sort: true,
+  },
+];
 /* 存量客户表格列 */
 export const stockTableColums = [
-	{
-		label:"客户名称",
-		key:"CompanyName",
-		widthsty:'300px',
-		textsty:"color:#409EFF;cursor:pointer;",
-		link:true,
-	},
-	{
-		label:"客户类型",
-		key:"ProductName",
-		widthsty:'100px'
-	},
-	{
-		label:"不续约归因",
-		key:"AscribeContent",
-		dataType:"未续约客户",
-		notRenewedConfirm:1,
-		sort:true
-	},
-	{
-		label:"客户状态",
-		key:"Status",
-		dataType:"未续约客户",
-	},
-	{
-		label:"所属销售",
-		key:"SellerName",
-		widthsty:'150px'
-	},
-	{
-		label:"服务期限",
-		dataType:"新签客户,续约客户"
-	},
-	{
-		label:"剩余天数",
-		key:"ExpireDay",
-		widthsty:'150px',
-		dataType:"新签客户,续约客户"
-	},
-	{
-		label:"最近合同到期时间",
-		key:"EndDate",
-		dataType:"未续约客户"
-	},
-	{
-		label:"备注",
-		key:"Remark",
-		dataType:"未续约客户",
-		widthsty:'100px',
-		sort:true
-	},
-	{
-		label:"未续约说明",
-		key:"RenewalReason",
-		dataType:"未续约客户",
-		widthsty:'300px'
-	},
-	{
-		label:"超出到期时间(天)",
-		key:"ExpireDay",
-		widthsty:'150px',
-		dataType:"未续约客户"
-	},
-]
+  {
+    label: "客户名称",
+    key: "CompanyName",
+    widthsty: "300px",
+    textsty: "color:#409EFF;cursor:pointer;",
+    link: true,
+  },
+  {
+    label: "客户类型",
+    key: "ProductName",
+    widthsty: "100px",
+  },
+  {
+    label: "不续约归因",
+    key: "AscribeContent",
+    dataType: "未续约客户",
+    notRenewedConfirm: 1,
+    sort: true,
+  },
+  {
+    label: "客户状态",
+    key: "Status",
+    dataType: "未续约客户",
+  },
+  {
+    label: "所属销售",
+    key: "SellerName",
+    widthsty: "150px",
+  },
+  {
+    label: "服务期限",
+    dataType: "新签客户,续约客户",
+  },
+  {
+    label: "剩余天数",
+    key: "ExpireDay",
+    widthsty: "150px",
+    dataType: "新签客户,续约客户",
+  },
+  {
+    label: "最近合同到期时间",
+    key: "EndDate",
+    dataType: "未续约客户",
+  },
+  {
+    label: "备注",
+    key: "Remark",
+    dataType: "未续约客户",
+    widthsty: "100px",
+    sort: true,
+  },
+  {
+    label: "未续约说明",
+    key: "RenewalReason",
+    dataType: "未续约客户",
+    widthsty: "300px",
+  },
+  {
+    label: "超出到期时间(天)",
+    key: "ExpireDay",
+    widthsty: "150px",
+    dataType: "未续约客户",
+  },
+];
 /* 合同列表表格列 */
 export const contractTableColums = [
-	{
-		label:"客户名称",
-		key:"CompanyName",
-		widthsty:'300px',
-		textsty:"color:#409EFF;cursor:pointer;",
-		link:true,
-	},
-	{
-		label:"客户类型",
-		key:"ProductName",
-		widthsty:'100px'
-	},
-	{
-		label:"所属销售",
-		key:"SellerName",
-		widthsty:'150px'
-	},
-	{
-		label:"有效合同数",
-		key:"Count",
-		widthsty:'150px',
-		dataType:"有效合同总数,有效合同总金额,正式客户数"
-	},
-	{
-		label:"有效合同总金额",
-		key:"SumMoney",
-		widthsty:'150px',
-		dataType:"有效合同总数,有效合同总金额,正式客户数"
-	},
-	{
-		label:'生成方式',
-		key:'Source',
-		widthsty:'150px',
-		dataType:"系统合同/上传附件"
-	},
-	{
-		label:'提交时间',
-		key:'CreateTime',
-		widthsty:'180px',
-		dataType:"系统合同/上传附件"
-	},
-	{
-		label:"操作",
-		textsty:"color:#409EFF;cursor:pointer;",
-		action:{
-			name:'合同详情'
-		}
-		
-	}
-]
+  {
+    label: "客户名称",
+    key: "CompanyName",
+    widthsty: "300px",
+    textsty: "color:#409EFF;cursor:pointer;",
+    link: true,
+  },
+  {
+    label: "客户类型",
+    key: "ProductName",
+    widthsty: "100px",
+  },
+  {
+    label: "所属销售",
+    key: "SellerName",
+    widthsty: "150px",
+  },
+  {
+    label: "有效合同数",
+    key: "Count",
+    widthsty: "150px",
+    dataType: "有效合同总数,有效合同总金额,正式客户数",
+  },
+  {
+    label: "有效合同总金额",
+    key: "SumMoney",
+    widthsty: "150px",
+    dataType: "有效合同总数,有效合同总金额,正式客户数",
+  },
+  {
+    label: "生成方式",
+    key: "Source",
+    widthsty: "150px",
+    dataType: "系统合同/上传附件",
+  },
+  {
+    label: "提交时间",
+    key: "CreateTime",
+    widthsty: "180px",
+    dataType: "系统合同/上传附件",
+  },
+  {
+    label: "操作",
+    textsty: "color:#409EFF;cursor:pointer;",
+    action: {
+      name: "合同详情",
+    },
+  },
+];
 /* 收入列表表格列 */
 export const incomeTableColums = [
-	{
-		label:"合同编号",
-		key:"ContractCode",
-	},
-	{
-		label:"客户名称",
-		key:"CompanyName",
-		widthsty:'200px',
-		textsty:"color:#409EFF;cursor:pointer;",
-		link:true,
-	},
-	{
-		label:"客户类型",
-		key:"ProductName",
-	},
-	{
-		label:"所属销售",
-		key:"SellerName",
-	},
-	{
-		label:"合同金额",
-		key:"Money",
-	},
-	{
-		label:"付款方式",
-		key:"PayMethod",
-	},
-	{
-		label:"付款渠道",
-		key:"PayChannel",
-	},
-	{
-		label:"服务期限",
-		widthsty:"200px"
-	},
-	{
-		label:"操作",
-		textsty:"color:#409EFF;cursor:pointer;",
-		action:{
-			name:'合同详情'
-		}
-		
-	}
-]
+  {
+    label: "合同编号",
+    key: "ContractCode",
+  },
+  {
+    label: "客户名称",
+    key: "CompanyName",
+    widthsty: "200px",
+    textsty: "color:#409EFF;cursor:pointer;",
+    link: true,
+  },
+  {
+    label: "客户类型",
+    key: "ProductName",
+  },
+  {
+    label: "所属销售",
+    key: "SellerName",
+  },
+  {
+    label: "合同金额",
+    key: "Money",
+  },
+  {
+    label: "付款方式",
+    key: "PayMethod",
+  },
+  {
+    label: "付款渠道",
+    key: "PayChannel",
+  },
+  {
+    label: "服务期限",
+    widthsty: "200px",
+  },
+  {
+    label: "操作",
+    textsty: "color:#409EFF;cursor:pointer;",
+    action: {
+      name: "合同详情",
+    },
+  },
+];
+
+/* 权益客户统计表格列 */
+export const equityTableColums = (type) => {
+  return type === "新签客户" || type === "续约客户"
+    ? [
+        {
+          label: "客户名称",
+          key: "CompanyName",
+          widthsty: "300px",
+          textsty: "color:#409EFF;cursor:pointer;",
+          link: true,
+        },
+        {
+          label: "所属销售",
+          key: "SellerName",
+          widthsty: "150px",
+        },
+        {
+          label: "合同期限",
+          align: "center",
+          key: "StartDate",
+        },
+        {
+          label: "合同金额",
+          key: "Money",
+          dataType: "新签客户",
+        },
+        {
+          label: type === "新签客户" ? "签约套餐" : "续约套餐",
+          align: "center",
+          key: "PermissionName",
+        },
+      ]
+    : type === "未续约客户"
+    ? [
+        {
+          label: "客户名称",
+          key: "CompanyName",
+          widthsty: "300px",
+          textsty: "color:#409EFF;cursor:pointer;",
+          link: true,
+        },
+        {
+          label: "客户状态",
+          key: "Status",
+          sort: true,
+        },
+        {
+          label: "所属销售",
+          key: "SellerName",
+          widthsty: "150px",
+        },
+        {
+          label: "合同到期时间",
+          key: "EndDate",
+          dataType: "未续约客户",
+          sort: true,
+        },
+        {
+          label: "签约套餐",
+          align: "center",
+          key: "PermissionName",
+        },
+        {
+          label: "合同金额",
+          key: "Money",
+          dataType: "新签客户",
+        },
+        {
+          label: "未续约说明",
+          key: "RenewalReason",
+          dataType: "未续约客户",
+          widthsty: "300px",
+          sort: true,
+        },
+        {
+          label: "备注",
+          key: "Remark",
+          dataType: "未续约客户",
+          widthsty: "100px",
+          sort: true,
+        },
+        {
+          label: "不续约归因",
+          key: "AscribeContent",
+          notRenewedConfirm: 1,
+          sort: true,
+        },
+      ]
+    : [];
+};

+ 677 - 0
src/views/dataReport_manage/equityCustomStatistics.vue

@@ -0,0 +1,677 @@
+<template>
+  <div class="dataReport-container" id="dataReport-container">
+    <div class="dataReport-top">
+      <a :href="exportExcel" download>
+        <button class="button-sty act">导出EXCEL</button>
+      </a>
+      <button :class="['button-sty', { act: filterObj.month === item.label }]" v-for="item in monthLabel" @click="toggleMonth(item.label)" :key="item.label">
+        {{ item.label }}
+      </button>
+      <date-picker v-model="filterObj.date" type="date" range value-type="format" placeholder="自定义时间段" :clearable="false" :editable="false" @change="dateChange" />
+      <el-input placeholder="请输入客户名称" v-model="searchVal" style="width: 400px; margin-left: auto" @input="handleSearch" clearable>
+        <i slot="prefix" class="el-input__icon el-icon-search"></i>
+      </el-input>
+    </div>
+    <div class="dataReport-main">
+      <div class="main-top">
+        <el-cascader
+          v-if="Role == 'finance' || Role == 'admin' || Role == 'ficc_admin' || Role == 'rai_admin' || ManageType != 0"
+          v-model="filterObj.sale"
+          placeholder="请选择销售"
+          style="min-width: 250px; margin-right: 10px; margin-bottom: 8px"
+          :options="salesArr"
+          :props="defaultSalesProps"
+          :show-all-levels="false"
+          collapse-tags
+          clearable
+          filterable
+          @change="changeFilter"
+        >
+        </el-cascader>
+      </div>
+      <div class="main-section">
+        <el-row :gutter="36">
+          <el-col :span="8" v-for="item in data_typeArr" :key="item.label">
+            <el-card :class="['base-card', { 'main-card': filterObj.data_type === item.label }]" shadow="hover" @click.native="toggleType(item.label)">
+              <div slot="header" class="clearfix">
+                <span>
+                  {{ lableTextDisplay(item.label) }}数
+                  <el-tooltip
+                    class="item"
+                    effect="dark"
+                    :content="
+                      item.label === '新签客户' ? '起始时间在所选时间段内的新签合同' : item.label === '续约客户' ? '起始时间在所选时间段内的续约合同' : '合同截止时间在所选时间段内的非正式、非永续客户'
+                    "
+                    placement="top"
+                  >
+                    <i class="el-icon-info"></i>
+                  </el-tooltip>
+                </span>
+              </div>
+              <div class="card-cont">
+                {{
+                  item.label === "新签客户"
+                    ? NewCompanyTotal
+                    : item.label === "续约客户"
+                    ? RenewalCompanyTotal
+                    : item.label === "未续约客户"
+                    ? NotRenewalCompanyTotal + " / " + NotRenewalCompanyToBeConfirmTotal
+                    : ""
+                }}
+              </div>
+            </el-card>
+          </el-col>
+        </el-row>
+      </div>
+      <div class="tabs-box" v-if="filterObj.data_type == '续约客户'">
+        <div class="tabs-box-confirm">
+          <div style="margin-bottom: 0px" class="tabs-box-confirm" v-for="(item, index) in packageTypeList" :key="item">
+            <div :class="['confirm-box-li', PackageDifference == item && 'active']" @click="notPackageDifferenceChange(item)">{{ item }}</div>
+            <div v-if="index != 2" class="center-line"></div>
+          </div>
+        </div>
+      </div>
+      <div class="tabs-box" v-if="filterObj.data_type == '未续约客户'">
+        <el-radio-group v-model="isNotRenewedConfirm" class="tabs-box-confirm" @change="notRenewedConfirmChange">
+          <el-radio-button :label="1">已确认</el-radio-button>
+          <div class="center-line"></div>
+          <el-radio-button :label="0">待确认</el-radio-button>
+        </el-radio-group>
+        <div class="tabs-box-status" v-show="isNotRenewedConfirm">
+          <el-select v-model="noRenewalReasonId" placeholder="请选择不续约归因" clearable @change="getTableData" style="width: 240px; margin-right: 50px">
+            <el-option :label="item.AscribeContent" :value="item.CompanyAscribeId" v-for="item in noRenewalReasonList" :key="item.reasonId"></el-option>
+          </el-select>
+          <!-- <span @click="tabsHandler(item)" :class="tabsActiveName === item.value ? 'active' : ''" v-for="item in tabsList" :key="item">
+            {{ item.name }}({{ item.name === "试用" ? NotRenewalTryOut : NotRenewalNotTryOut }})
+          </span> -->
+          <el-select v-model="tabsActiveName" placeholder="当前状态" clearable @change="getTableData" style="width: 240px; margin-right: 50px">
+            <el-option :label="item.name" :value="item.value" v-for="item in tabsList" :key="item.value"></el-option>
+          </el-select>
+        </div>
+      </div>
+      <el-table :data="tableData" border style="margin-top: 20px; min-height: 400px" v-loading="isShowloadding" element-loading-text="数据加载中...">
+        <template v-for="item in incrementTableColums">
+          <el-table-column :key="item.label" :label="item.label" :width="item.widthsty" align="center" v-if="item.key != 'AscribeContent'">
+            <template slot-scope="scope">
+              <span :style="item.textsty" @click="jumpHandle(scope.row, item)" v-if="item.key === 'CreateTime'">
+                {{ scope.row[item.key] | formatTime }}
+              </span>
+              <span v-else-if="item.label == '未续约说明'">
+                <span style="display: block" v-if="scope.row[item.key]">最新情况:{{ scope.row[item.key] }}</span>
+                <span v-if="scope.row.RenewalTodo">To Do 事项:{{ scope.row.RenewalTodo }}</span>
+                <span v-if="scope.row[item.key] || scope.row.RenewalTodo" style="color: #409eff; cursor: pointer" @click="renewalReasonMore(scope.row)">&emsp;更多>></span>
+              </span>
+              <div v-else-if="item.key == 'CompanyName'" style="padding: 4px 0">
+                <span :style="item.textsty" @click="jumpHandle(scope.row, item)">
+                  {{ scope.row[item.key] }}
+                </span>
+                <div class="package-difference" v-if="scope.row.PackageDifference && filterObj.data_type == '续约客户'" @click="previousDetailHadler(scope.row)">
+                  {{ scope.row.PackageDifference }}
+                </div>
+              </div>
+              <div v-else-if="item.key === 'Remark'" class="remark-row">
+                <span class="remark-text" @click="viewHistoryRemarkFun(scope.row)" v-if="scope.row.IsShowNoRenewedNote">...</span>
+                <span class="operation-button" v-show="canConfirmNotRenewed && !isNotRenewedConfirm" style="margin-right: 0" @click="addRemarkFun(scope.row)">添加</span>
+              </div>
+              <div v-else-if="item.key == 'AscribeContent'">
+                <span style="color: #409eff; cursor: pointer" @click="editReasonLabel(scope.row)">
+                  {{ scope.row[item.key] }}
+                </span>
+              </div>
+              <div v-else-if="item.key == 'PermissionName'">
+                <template v-if="scope.row.PermissionName.length">
+                  <el-tag size="mini" style="margin: 0 10px 10px 0" v-for="key in scope.row.PermissionName.split(',')" :key="key">{{ key }}</el-tag>
+                </template>
+              </div>
+              <div v-else-if="item.key == 'StartDate'">
+                <span> {{ scope.row[item.key] }} ~ {{ scope.row.EndDate }} </span>
+              </div>
+              <span v-else :style="item.textsty" @click="jumpHandle(scope.row, item)">
+                {{ scope.row[item.key] }}
+              </span>
+            </template>
+          </el-table-column>
+          <el-table-column :key="item.label" :label="item.label" :width="item.widthsty" align="center" v-else-if="item.key == 'AscribeContent' && isNotRenewedConfirm == 1">
+            <template slot-scope="scope">
+              <span style="color: #409eff; cursor: pointer" @click="editReasonLabel(scope.row)">
+                {{ scope.row[item.key] }}
+              </span>
+            </template>
+          </el-table-column>
+        </template>
+        <el-table-column label="操作" width="180px" align="center" v-if="canConfirmNotRenewed && !isNotRenewedConfirm && filterObj.data_type == '未续约客户'">
+          <template slot-scope="scope">
+            <div class="operation-row">
+              <span class="operation-button" @click="confirmedNoRenewalFun(scope.row)">确认不续约</span>
+            </div>
+          </template>
+        </el-table-column>
+        <div slot="empty" style="line-height: 44px; margin: 60px 0; color: #999">
+          <img src="~@/assets/img/cus_m/nodata.png" alt="" style="display: block; width: 160px; height: 128px; margin: auto" />
+          <span>暂无数据</span>
+        </div>
+      </el-table>
+      <el-col :span="24" class="toolbar" v-if="total">
+        <m-page :total="total" :page_no="page_no" @handleCurrentChange="handleCurrentChange" />
+      </el-col>
+    </div>
+    <!-- 未续约说明列表弹窗 -->
+    <renewalListDia :isShow.sync="isRenewalShow" :rowInfo="rowInfo" />
+    <!-- 添加备注弹窗 -->
+    <addRemark :isShow.sync="isAddRemarkShow" @saveRemark="saveRemark" />
+    <!-- 历史备注弹窗 -->
+    <viewRemark :isShow.sync="isViewRemarkShow" :tableData="historyRemarkList" />
+    <!-- 确认不续约弹窗 -->
+    <confirmedNoRenewal
+      :isShow.sync="isConfirmNoRenewalShow"
+      :dataForm="confirmNoRenewalForm"
+      :noRenewalReasonList="noRenewalReasonList"
+      @refreshReasonList="getNORenewalReasonList"
+      @saveLabel="saveLabel"
+      equityType="权益客户统计"
+    />
+    <previous-detail :previousDetailDlg.sync="previousDetailDlg" :rowInfo="rowInfo" />
+  </div>
+</template>
+
+<script>
+import { equityTableColums } from "./configdata.js";
+import { dataMainInterface, customInterence } from "@/api/api.js";
+import mPage from "@/components/mPage.vue";
+import renewalListDia from "./components/renewalListDia.vue";
+import addRemark from "./components/noRenewalReasonDia/addRemark.vue";
+import viewRemark from "./components/noRenewalReasonDia/viewRemark.vue";
+import confirmedNoRenewal from "./components/noRenewalReasonDia/confirmedNoRenewal.vue";
+import PreviousDetail from "./components/previousDetail.vue";
+
+var moment = require("moment");
+moment().format();
+export default {
+  name: "",
+  components: { mPage, renewalListDia, addRemark, viewRemark, confirmedNoRenewal, PreviousDetail },
+  computed: {
+    exportExcel() {
+      let baseUrl = process.env.API_ROOT + "/statistic_report/merge_company_list";
+      let token = localStorage.getItem("auth") || "";
+      let paramStr = "";
+      // 处理销售筛选
+      let salesArr = [];
+      if (this.filterObj.sale.length) {
+        salesArr = this.filterObj.sale.map((item) => {
+          return item[item.length - 1];
+        });
+      }
+      let obj = {
+        AdminId: salesArr.join(","),
+        EndDate: this.end_date,
+        StartDate: this.start_date,
+        DataType: this.filterObj.data_type == "新增试用客户" ? "新增试用" : this.filterObj.data_type,
+        Keyword: this.searchVal,
+        IsExport: true,
+        IsConfirm: this.filterObj.data_type == "未续约客户" ? this.isNotRenewedConfirm : -1,
+        CompanyAscribeId: this.noRenewalReasonId,
+      };
+      for (let key in obj) {
+        paramStr = `${paramStr}&${key}=${obj[key]}`;
+      }
+      return `${baseUrl}?${token}${paramStr}`;
+    },
+    Role() {
+      let role = localStorage.getItem("Role") || "";
+      return role;
+    },
+    //管理权限
+    ManageType() {
+      return localStorage.getItem("ManageType") || "";
+    },
+    //确认未续约权限
+    canConfirmNotRenewed() {
+      return ["admin", "rai_admin"].includes(this.Role);
+    },
+  },
+  data() {
+    return {
+      searchVal: sessionStorage.getItem("incrementBack") ? JSON.parse(sessionStorage.getItem("incrementBack")).searchVal : "",
+      tableData: [],
+      isShowloadding: false,
+      start_date: "",
+      end_date: "",
+      /* 筛选条件 */
+      filterObj: {
+        month: "近1个月",
+        date: [],
+        sale: "",
+        data_type: "新签客户",
+      },
+      monthLabel: [
+        {
+          label: "近1个月",
+        },
+        {
+          label: "近2个月",
+        },
+        {
+          label: "近3个月",
+        },
+      ],
+      salesArr: [], //销售列表
+      defaultSalesProps: {
+        multiple: true,
+        label: "RealName",
+        children: "ChildrenList",
+        value: "AdminId",
+      }, //销售级联配置
+      pageSize: 10,
+      page_no: sessionStorage.getItem("incrementBack") ? JSON.parse(sessionStorage.getItem("incrementBack")).page_no : 1,
+      total: 0,
+      data_typeArr: [
+        {
+          label: "新签客户",
+        },
+        {
+          label: "续约客户",
+        },
+        {
+          label: "未续约客户",
+        },
+      ], //数据类型
+      NewCompanyTotal: 0, //新签客户数
+      NotRenewalCompanyTotal: 0, //未续约客户数
+      RenewalCompanyTotal: 0, //续约客户数
+      NotRenewalCompanyToBeConfirmTotal: 0,
+      isRenewalShow: false, //未续约说明列表弹框是否显示
+      rowInfo: null, // 未续约说明更多行信息
+      tabsList: [
+        { name: "试用", value: "试用" },
+        { name: "冻结/流失", value: "非试用" },
+      ],
+      tabsActiveName: "",
+      NotRenewalNotTryOut: 0, //冻结流失的人数
+      NotRenewalTryOut: 0, //试用的人数
+      isNotRenewedConfirm: 1, //未续约的是否已确认
+      noRenewalReasonList: [],
+      noRenewalReasonId: "",
+      selectItemRow: {}, // 当前选中的row
+      // 添加备注
+      isAddRemarkShow: false,
+      //历史备注
+      isViewRemarkShow: false,
+      historyRemarkList: [],
+      //确认不续约
+      isConfirmNoRenewalShow: false,
+      confirmNoRenewalForm: {
+        reason: "",
+        detailReason: "",
+      },
+      incrementTableColums: [],
+      PackageDifference: "",
+      previousDetailDlg: false,
+      packageTypeList: ["增加套餐", "减少套餐", "维持套餐"],
+    };
+  },
+  /* 页面跳转前记录参数 */
+  beforeRouteLeave(to, form, next) {
+    let backData = {
+      page_no: this.page_no,
+      end_date: this.end_date,
+      start_date: this.start_date,
+      filterObj: this.filterObj,
+    };
+    sessionStorage.setItem("incrementBack", JSON.stringify(backData));
+    next();
+  },
+  /* 页面进入前是否清除参数 */
+  beforeRouteEnter(to, from, next) {
+    if (from.path != "/customDetail") {
+      sessionStorage.removeItem("incrementBack");
+    }
+    next();
+  },
+  methods: {
+    // 搜索
+    handleSearch() {
+      if (!this.searchVal) {
+        this.page_no = 1;
+        this.filterObj = {
+          month: "近1个月",
+          date: [],
+          sale: "",
+          data_type: this.filterObj.data_type,
+        };
+        let date_before = moment().subtract(1, "M").format("YYYY-MM-DD");
+        let date_now = moment().format("YYYY-MM-DD");
+        let date = [date_before, date_now];
+        this.start_date = date_before;
+        this.end_date = date_now;
+        this.filterObj.date = date;
+        this.getTableData();
+        return;
+      }
+      this.page_no = 1;
+      this.filterObj = {
+        month: "",
+        date: [],
+        sale: "",
+        data_type: this.filterObj.data_type,
+      };
+      this.start_date = "";
+      this.end_date = "";
+      this.getTableData();
+    },
+    //tabs 的点击事件
+    // tabsHandler(item) {
+    //   this.tabsActiveName = item.value;
+    //   this.noRenewalReasonId = "";
+    //   this.page_no = 1;
+    //   this.getTableData();
+    // },
+    notRenewedConfirmChange() {
+      this.tabsActiveName = "";
+      this.noRenewalReasonId = "";
+      this.page_no = 1;
+      this.getTableData();
+    },
+    notPackageDifferenceChange(type) {
+      if (this.PackageDifference == type) {
+        this.PackageDifference = "";
+      } else {
+        this.PackageDifference = type;
+      }
+      this.page_no = 1;
+      this.getTableData();
+    },
+    /* 获取表格 */
+    getTableData() {
+      this.isShowloadding = true;
+      // 处理销售筛选
+      let salesArr = [];
+      if (this.filterObj.sale.length) {
+        salesArr = this.filterObj.sale.map((item) => {
+          return item[item.length - 1];
+        });
+      }
+      let params = {
+        Keyword: this.searchVal,
+        PageSize: this.pageSize,
+        CurrentIndex: this.page_no,
+        AdminId: salesArr.join(","),
+        EndDate: this.end_date,
+        StartDate: this.start_date,
+        DataType: this.filterObj.data_type == "新增试用客户" ? "新增试用" : this.filterObj.data_type,
+        TryOutType: this.filterObj.data_type == "未续约客户" && this.isNotRenewedConfirm == 1 ? this.tabsActiveName : "",
+        IsConfirm: this.filterObj.data_type == "未续约客户" ? this.isNotRenewedConfirm : -1,
+        CompanyAscribeId: this.noRenewalReasonId,
+        PackageDifference: this.PackageDifference,
+      };
+      dataMainInterface.incrementalEquityList(params).then((res) => {
+        if (res.Ret === 200) {
+          this.tableData = res.Data.List || [];
+          this.total = res.Data.Paging.Totals;
+          this.NewCompanyTotal = res.Data.NewCompanyTotal;
+          this.RenewalCompanyTotal = res.Data.RenewalCompanyTotal;
+          this.NotRenewalCompanyTotal = res.Data.NotRenewalCompanyTotal;
+          this.NotRenewalCompanyToBeConfirmTotal = res.Data.NotRenewalCompanyToBeConfirmTotal;
+          this.NotRenewalTryOut = res.Data.NotRenewalTryOut;
+          this.NotRenewalNotTryOut = res.Data.NotRenewalNotTryOut;
+          this.isShowloadding = false;
+        }
+      });
+    },
+    /* 获取销售 */
+    getSale() {
+      customInterence.getSalesRaiData().then((res) => {
+        if (res.Ret === 200) {
+          this.salesArr = res.Data.List;
+        }
+      });
+    },
+    /* 切换月份 */
+    toggleMonth(label) {
+      this.filterObj.month = label;
+      let days = label == "近1个月" ? 1 : label == "近2个月" ? 2 : label == "近3个月" ? 3 : 0;
+      this.filterDate(days);
+    },
+    /* 选择服务日期 */
+    dateChange(e) {
+      if (e[0]) {
+        this.start_date = e[0];
+        this.end_date = e[1];
+      } else {
+        this.start_date = "";
+        this.end_date = "";
+      }
+      this.filterObj.month = "";
+      this.page_no = 1;
+      this.searchVal = "";
+      this.getTableData();
+    },
+    /* 切换数据类型 */
+    toggleType(label) {
+      this.filterObj.data_type = label;
+      this.incrementTableColums = equityTableColums(this.filterObj.data_type);
+      this.noRenewalReasonId = "";
+      if (label == "未续约客户") {
+        this.getNORenewalReasonList();
+      }
+      this.tabsActiveName = "";
+      this.page_no = 1;
+      this.getTableData();
+    },
+    /* 筛选改变时 */
+    changeFilter() {
+      this.page_no = 1;
+      this.searchVal = "";
+      this.getTableData();
+    },
+    /* 切换页码 */
+    handleCurrentChange(page) {
+      this.page_no = page;
+      this.getTableData();
+    },
+    /* 获取近几个月的日期范围 */
+    filterDate(month) {
+      if (month) {
+        let date_before = moment().subtract(month, "M").format("YYYY-MM-DD");
+        let date_now = moment().format("YYYY-MM-DD");
+        let date = [date_before, date_now];
+        this.start_date = date_before;
+        this.end_date = date_now;
+        this.filterObj.date = date;
+        this.page_no = 1;
+        this.searchVal = "";
+        this.getTableData();
+      }
+    },
+    /* 跳转 */
+    jumpHandle(row, item) {
+      if (item.link) {
+        let { href } = this.$router.resolve({
+          path: "/customDetail",
+          query: {
+            id: row.CompanyId,
+          },
+        });
+        window.open(href, "_blank");
+      }
+    },
+    getNORenewalReasonList() {
+      dataMainInterface.getAscribList().then((res) => {
+        if (res.Ret == 200) {
+          this.noRenewalReasonList = res.Data.List || [];
+        }
+      });
+    },
+    // 未续约说明更多按钮
+    renewalReasonMore(row) {
+      this.rowInfo = {
+        CompanyId: row.CompanyId,
+        ProductId: row.ProductId,
+      };
+      this.isRenewalShow = true;
+    },
+    // 添加备注
+    addRemarkFun(row) {
+      this.selectItemRow = row;
+      this.isAddRemarkShow = true;
+    },
+    // 添加备注 保存
+    saveRemark(remark) {
+      // console.log(remark);
+      let params = {
+        CompanyId: this.selectItemRow.CompanyId,
+        ProductId: this.selectItemRow.ProductId,
+        Content: remark,
+      };
+      dataMainInterface.addNotRenewedRemark(params).then((res) => {
+        if (res.Ret == 200) {
+          this.$message.success("添加成功");
+          this.getTableData();
+          this.isAddRemarkShow = false;
+          this.selectItemRow = {};
+        }
+      });
+    },
+    // 查看历史备注
+    viewHistoryRemarkFun(row) {
+      dataMainInterface.getNotRenewedRemarkList({ CompanyId: row.CompanyId, ProductId: row.ProductId }).then((res) => {
+        if (res.Ret == 200) {
+          this.historyRemarkList = res.Data.List || [];
+          this.isViewRemarkShow = true;
+        }
+      });
+    },
+    confirmedNoRenewalFun(row) {
+      this.confirmNoRenewalForm.reason = "";
+      this.confirmNoRenewalForm.detailReason = "";
+      this.selectItemRow = row;
+      this.isConfirmNoRenewalShow = true;
+    },
+    editReasonLabel(row) {
+      dataMainInterface.contractInfoNoRenewedAscribe({ CompanyContractId: row.CompanyContractId }).then((res) => {
+        if (res.Ret == 200) {
+          this.confirmNoRenewalForm.reason = res.Data.Detail ? res.Data.Detail.CompanyAscribeId || "" : "";
+          this.confirmNoRenewalForm.detailReason = res.Data.Detail ? res.Data.Detail.Content || "" : "";
+          this.selectItemRow = row;
+          this.isConfirmNoRenewalShow = true;
+        }
+      });
+    },
+    saveLabel(item) {
+      let params = {
+        CompanyContractId: this.selectItemRow.CompanyContractId,
+        CompanyAscribeId: item.CompanyAscribeId,
+        Content: item.Content,
+      };
+      dataMainInterface.addAscribContract(params).then((res) => {
+        if (res.Ret == 200) {
+          this.$message.success("确认成功");
+          this.isConfirmNoRenewalShow = false;
+          this.selectItemRow = {};
+          this.getTableData();
+        }
+      });
+    },
+    previousDetailHadler(row) {
+      console.log(123);
+      this.rowInfo = row;
+      this.previousDetailDlg = true;
+    },
+    lableTextDisplay(text) {
+      let str = text == "新签客户" ? "新签合同" : text == "续约客户" ? "续约合同" : "未续约客户";
+      return str;
+    },
+  },
+  created() {},
+  mounted() {
+    this.incrementTableColums = equityTableColums(this.filterObj.data_type);
+    this.getSale();
+    if (sessionStorage.getItem("incrementBack")) {
+      let backData = JSON.parse(sessionStorage.getItem("incrementBack"));
+      this.page_no = backData.page_no;
+      this.end_date = backData.end_date;
+      this.start_date = backData.start_date;
+      this.filterObj = backData.filterObj;
+      this.searchVal = backData.searchVal;
+    }
+    /* 默认选中近1个月 */
+    this.filterDate(this.filterObj.month === "近1个月" ? 1 : this.filterObj.month === "近2个月" ? 2 : this.filterObj.month === "近3个月" ? 3 : 0);
+  },
+};
+</script>
+<style lang="scss" scoped>
+@import "./index.scss";
+.tabs-box {
+  flex-direction: column;
+  .tabs-box-confirm {
+    display: flex;
+    align-items: center;
+    margin-bottom: 20px;
+    .center-line {
+      width: 1px;
+      height: 21px;
+      background-color: #333333;
+      margin: 0 20px;
+    }
+    .confirm-box-li {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      cursor: pointer;
+      width: 120px;
+      height: 40px;
+      border-radius: 4px;
+    }
+    .active {
+      background-color: #409eff;
+      color: #fff;
+    }
+  }
+}
+.operation-button {
+  color: #409eff;
+  cursor: pointer;
+  font-size: 14px;
+  margin-right: 10px;
+}
+.remark-row {
+  display: flex;
+  justify-content: center;
+  .remark-text {
+    width: 18px;
+    height: 18px;
+    margin-right: 8px;
+    font-size: 18px;
+    color: #409eff;
+    cursor: pointer;
+  }
+}
+.operation-row {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-wrap: wrap;
+  .operation-button {
+    &:last-child {
+      margin-right: 0;
+    }
+  }
+}
+.package-difference {
+  cursor: pointer;
+}
+</style>
+<style lang="scss">
+#dataReport-container {
+  .tabs-box {
+    .el-radio-button {
+      margin-right: 0;
+    }
+    .el-radio-button .el-radio-button__inner {
+      border: none;
+      width: 120px;
+      height: 40px;
+      border-radius: 4px;
+    }
+  }
+}
+</style>

+ 466 - 0
src/views/dataReport_manage/equityPackageStatistics.vue

@@ -0,0 +1,466 @@
+<template>
+  <div class="dataReport-container" id="dataReport-container">
+    <div class="dataReport-top">
+      <a :href="exportExcel" download>
+        <button class="button-sty act">导出EXCEL</button>
+      </a>
+      <button :class="['button-sty', { act: filterObj.month === item.label }]" v-for="item in monthLabel" @click="toggleMonth(item.label)" :key="item.label">
+        {{ item.label }}
+      </button>
+      <date-picker v-model="filterObj.date" type="date" range value-type="format" placeholder="自定义时间段" :clearable="false" :editable="false" @change="dateChange" />
+      <el-input placeholder="请输入客户名称" v-model="searchVal" style="width: 400px; margin-left: auto" @input="handleSearch" clearable>
+        <i slot="prefix" class="el-input__icon el-icon-search"></i>
+      </el-input>
+    </div>
+    <div class="dataReport-main">
+      <div class="main-top">
+        <el-cascader
+          v-if="Role == 'finance' || Role == 'admin' || Role == 'ficc_admin' || Role == 'rai_admin' || ManageType != 0"
+          v-model="filterObj.sale"
+          placeholder="请选择销售"
+          style="min-width: 250px; margin-right: 10px; margin-bottom: 8px"
+          :options="salesArr"
+          :props="defaultSalesProps"
+          :show-all-levels="false"
+          collapse-tags
+          clearable
+          filterable
+          @change="changeFilter"
+        >
+        </el-cascader>
+      </div>
+      <div class="main-section">
+        <el-row :gutter="36">
+          <el-col :span="8" v-for="item in data_typeArr" :key="item.label">
+            <el-card :class="['base-card', { 'main-card': filterObj.data_type === item.label }]" shadow="hover" @click.native="toggleType(item.label)">
+              <div slot="header" class="clearfix">
+                <span>
+                  {{ item.label }}
+                  <el-tooltip
+                    class="item"
+                    effect="dark"
+                    :content="
+                      item.label === '行业新签'
+                        ? '行业合同开始时间在查询时间段内,且该行业在历史上没有转正记录'
+                        : item.label === '行业续约'
+                        ? '行业合同开始时间在查询时间段内,且该行业历史上有过正式到期记录'
+                        : '行业合同到期时间在查询时间段内,且该行业当前状态是非正式状态'
+                    "
+                    placement="top"
+                  >
+                    <i class="el-icon-info"></i>
+                  </el-tooltip>
+                </span>
+              </div>
+              <div class="card-cont">
+                {{ item.label === "行业新签" ? NewCompanyTotal : item.label === "行业续约" ? RenewalCompanyTotal : item.label === "行业未续约" ? NotRenewalCompanyTotal : "" }}
+              </div>
+            </el-card>
+          </el-col>
+        </el-row>
+      </div>
+      <div class="tabs-content-box">
+        <span v-for="item in listPermissionName" :key="item.ChartPermissionId" @click="tabsBoxBtn(item)" :class="item.PermissionName == tabsPitchon ? 'pitch' : ''">
+          {{ item.PermissionName }} ({{ item.Total }})
+        </span>
+      </div>
+      <el-table :data="tableData" border style="margin-top: 20px; min-height: 400px" v-loading="isShowloadding" element-loading-text="数据加载中...">
+        <el-table-column label="公司名称" prop="CompanyName" align="center">
+          <template slot-scope="{ row }">
+            <span class="editsty" @click="goCompanyHandle(row)">{{ row.CompanyName }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column width="100" label="所属销售" prop="SellerName" align="center"> </el-table-column>
+        <el-table-column label="合同金额" prop="Money" align="center"> </el-table-column>
+        <el-table-column label="合同期限" prop="StartDate" align="center">
+          <template slot-scope="{ row }">
+            <span>{{ row.StartDate }} ~ {{ row.EndDate }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="签约套餐" prop="PermissionName" align="center">
+          <template slot-scope="{ row }">
+            <template v-if="row.PermissionName.length">
+              <el-tag size="mini" style="margin: 0 10px 10px 0" v-for="key in row.PermissionName.split(',')" :key="key">{{ key }}</el-tag>
+            </template>
+          </template>
+        </el-table-column>
+        <template v-if="filterObj.data_type == '行业未续约'">
+          <el-table-column width="118" label="当前行业状态" prop="PermissionNameStatus" align="center"> </el-table-column>
+          <el-table-column width="118" label="当前客户状态" prop="CompanyProductStatus" align="center"> </el-table-column>
+        </template>
+      </el-table>
+      <el-col :span="24" class="toolbar" v-if="total">
+        <m-page :total="total" :page_no="page_no" @handleCurrentChange="handleCurrentChange" />
+      </el-col>
+    </div>
+  </div>
+</template>
+
+<script>
+import { equityTableColums } from "./configdata.js";
+import { dataMainInterface, customInterence } from "@/api/api.js";
+import mPage from "@/components/mPage.vue";
+var moment = require("moment");
+moment().format();
+export default {
+  name: "",
+  components: { mPage },
+  computed: {
+    exportExcel() {
+      let baseUrl = process.env.API_ROOT + "/statistic_report/merge_company/company_contract_permission/list";
+      let token = localStorage.getItem("auth") || "";
+      let paramStr = "";
+      // 处理销售筛选
+      let salesArr = [];
+      if (this.filterObj.sale.length) {
+        salesArr = this.filterObj.sale.map((item) => {
+          return item[item.length - 1];
+        });
+      }
+      let obj = {
+        IsExport: true,
+        Keyword: this.searchVal,
+        AdminId: salesArr.join(","),
+        EndDate: this.end_date,
+        StartDate: this.start_date,
+        DataType: this.filterObj.data_type,
+        PermissionName: this.tabsPitchon,
+      };
+      for (let key in obj) {
+        paramStr = `${paramStr}&${key}=${obj[key]}`;
+      }
+      return `${baseUrl}?${token}${paramStr}`;
+    },
+    Role() {
+      let role = localStorage.getItem("Role") || "";
+      return role;
+    },
+    //管理权限
+    ManageType() {
+      return localStorage.getItem("ManageType") || "";
+    },
+    //确认未续约权限
+    canConfirmNotRenewed() {
+      return ["admin", "rai_admin"].includes(this.Role);
+    },
+  },
+  data() {
+    return {
+      searchVal: sessionStorage.getItem("incrementBack") ? JSON.parse(sessionStorage.getItem("incrementBack")).searchVal : "",
+      tableData: [],
+      isShowloadding: false,
+      start_date: "",
+      end_date: "",
+      /* 筛选条件 */
+      filterObj: {
+        month: "近1个月",
+        date: [],
+        sale: "",
+        data_type: "行业新签",
+      },
+      monthLabel: [
+        {
+          label: "近1个月",
+        },
+        {
+          label: "近2个月",
+        },
+        {
+          label: "近3个月",
+        },
+      ],
+      salesArr: [], //销售列表
+      defaultSalesProps: {
+        multiple: true,
+        label: "RealName",
+        children: "ChildrenList",
+        value: "AdminId",
+      }, //销售级联配置
+      pageSize: 10,
+      page_no: sessionStorage.getItem("incrementBack") ? JSON.parse(sessionStorage.getItem("incrementBack")).page_no : 1,
+      total: 0,
+      data_typeArr: [
+        {
+          label: "行业新签",
+        },
+        {
+          label: "行业续约",
+        },
+        {
+          label: "行业未续约",
+        },
+      ], //数据类型
+      NewCompanyTotal: 0, //行业新签数
+      NotRenewalCompanyTotal: 0, //行业未续约数
+      RenewalCompanyTotal: 0, //行业续约数
+      listPermissionName: [],
+      tabsPitchon: "医药",
+    };
+  },
+  /* 页面跳转前记录参数 */
+  beforeRouteLeave(to, form, next) {
+    let backData = {
+      page_no: this.page_no,
+      end_date: this.end_date,
+      start_date: this.start_date,
+      filterObj: this.filterObj,
+    };
+    sessionStorage.setItem("incrementBack", JSON.stringify(backData));
+    next();
+  },
+  /* 页面进入前是否清除参数 */
+  beforeRouteEnter(to, from, next) {
+    if (from.path != "/customDetail") {
+      sessionStorage.removeItem("incrementBack");
+    }
+    next();
+  },
+  methods: {
+    // 搜索
+    handleSearch() {
+      if (!this.searchVal) {
+        this.page_no = 1;
+        this.filterObj = {
+          month: "近1个月",
+          date: [],
+          sale: "",
+          data_type: this.filterObj.data_type,
+        };
+        let date_before = moment().subtract(1, "M").format("YYYY-MM-DD");
+        let date_now = moment().format("YYYY-MM-DD");
+        let date = [date_before, date_now];
+        this.start_date = date_before;
+        this.end_date = date_now;
+        this.filterObj.date = date;
+        this.getTableData();
+        return;
+      }
+      this.page_no = 1;
+      this.filterObj = {
+        month: "",
+        date: [],
+        sale: "",
+        data_type: this.filterObj.data_type,
+      };
+      this.start_date = "";
+      this.end_date = "";
+      this.getTableData();
+    },
+    /* 获取表格 */
+    getTableData() {
+      this.isShowloadding = true;
+      // 处理销售筛选
+      let salesArr = [];
+      if (this.filterObj.sale.length) {
+        salesArr = this.filterObj.sale.map((item) => {
+          return item[item.length - 1];
+        });
+      }
+      let params = {
+        Keyword: this.searchVal,
+        PageSize: this.pageSize,
+        CurrentIndex: this.page_no,
+        AdminId: salesArr.join(","),
+        EndDate: this.end_date,
+        StartDate: this.start_date,
+        DataType: this.filterObj.data_type,
+        PermissionName: this.tabsPitchon,
+      };
+      dataMainInterface.incrementalCompanyContractPermissionList(params).then((res) => {
+        if (res.Ret === 200) {
+          this.tableData = res.Data.List || [];
+          this.total = res.Data.Paging.Totals;
+          this.NewCompanyTotal = res.Data.NewCompanyTotal;
+          this.RenewalCompanyTotal = res.Data.RenewalCompanyTotal;
+          this.NotRenewalCompanyTotal = res.Data.NotRenewalCompanyTotal;
+          this.isShowloadding = false;
+          this.listPermissionName = res.Data.ListPermissionName;
+        }
+      });
+    },
+    /* 获取销售 */
+    getSale() {
+      customInterence.getSalesRaiData().then((res) => {
+        if (res.Ret === 200) {
+          this.salesArr = res.Data.List;
+        }
+      });
+    },
+    /* 切换月份 */
+    toggleMonth(label) {
+      this.filterObj.month = label;
+      let days = label == "近1个月" ? 1 : label == "近2个月" ? 2 : label == "近3个月" ? 3 : 0;
+      this.filterDate(days);
+    },
+    /* 选择服务日期 */
+    dateChange(e) {
+      if (e[0]) {
+        this.start_date = e[0];
+        this.end_date = e[1];
+      } else {
+        this.start_date = "";
+        this.end_date = "";
+      }
+      this.filterObj.month = "";
+      this.page_no = 1;
+      this.searchVal = "";
+      this.getTableData();
+    },
+    /* 切换数据类型 */
+    toggleType(label) {
+      this.tabsPitchon = "医药";
+      this.filterObj.data_type = label;
+      this.page_no = 1;
+      this.getTableData();
+    },
+    /* 筛选改变时 */
+    changeFilter() {
+      this.page_no = 1;
+      this.searchVal = "";
+      this.getTableData();
+    },
+    /* 切换页码 */
+    handleCurrentChange(page) {
+      this.page_no = page;
+      this.getTableData();
+    },
+    /* 获取近几个月的日期范围 */
+    filterDate(month) {
+      if (month) {
+        let date_before = moment().subtract(month, "M").format("YYYY-MM-DD");
+        let date_now = moment().format("YYYY-MM-DD");
+        let date = [date_before, date_now];
+        this.start_date = date_before;
+        this.end_date = date_now;
+        this.filterObj.date = date;
+        this.page_no = 1;
+        this.searchVal = "";
+        this.getTableData();
+      }
+    },
+    tabsBoxBtn(item) {
+      this.tabsPitchon = item.PermissionName;
+      this.changeFilter();
+    },
+    // 去往公司详情
+    goCompanyHandle(row) {
+      let { href } = this.$router.resolve({
+        path: "/customDetail",
+        query: {
+          id: row.CompanyId,
+        },
+      });
+      window.open(href, "_blank");
+    },
+  },
+  created() {},
+  mounted() {
+    this.getSale();
+    if (sessionStorage.getItem("incrementBack")) {
+      let backData = JSON.parse(sessionStorage.getItem("incrementBack"));
+      this.page_no = backData.page_no;
+      this.end_date = backData.end_date;
+      this.start_date = backData.start_date;
+      this.filterObj = backData.filterObj;
+      this.searchVal = backData.searchVal;
+    }
+    /* 默认选中近1个月 */
+    this.filterDate(this.filterObj.month === "近1个月" ? 1 : this.filterObj.month === "近2个月" ? 2 : this.filterObj.month === "近3个月" ? 3 : 0);
+  },
+};
+</script>
+<style lang="scss" scoped>
+@import "./index.scss";
+.tabs-box {
+  flex-direction: column;
+  .tabs-box-confirm {
+    display: flex;
+    align-items: center;
+    margin-bottom: 20px;
+    .center-line {
+      width: 1px;
+      height: 21px;
+      background-color: #333333;
+      margin: 0 20px;
+    }
+    .confirm-box-li {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      cursor: pointer;
+      width: 120px;
+      height: 40px;
+      border-radius: 4px;
+    }
+    .active {
+      background-color: #409eff;
+      color: #fff;
+    }
+  }
+}
+.operation-button {
+  color: #409eff;
+  cursor: pointer;
+  font-size: 14px;
+  margin-right: 10px;
+}
+.remark-row {
+  display: flex;
+  justify-content: center;
+  .remark-text {
+    width: 18px;
+    height: 18px;
+    margin-right: 8px;
+    font-size: 18px;
+    color: #409eff;
+    cursor: pointer;
+  }
+}
+.operation-row {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-wrap: wrap;
+  .operation-button {
+    &:last-child {
+      margin-right: 0;
+    }
+  }
+}
+.package-difference {
+  cursor: pointer;
+}
+.tabs-content-box {
+  margin-top: 20px;
+  span {
+    display: inline-block;
+    padding: 9px 24px;
+    background-color: #e9f4ff;
+    border: 1px solid #b3d8ff;
+    border-radius: 4px;
+    margin-right: 30px;
+    color: #409eff;
+    cursor: pointer;
+  }
+  .pitch {
+    background-color: #409eff;
+    border: none;
+    color: #fff;
+  }
+}
+</style>
+<style lang="scss">
+#dataReport-container {
+  .tabs-box {
+    .el-radio-button {
+      margin-right: 0;
+    }
+    .el-radio-button .el-radio-button__inner {
+      border: none;
+      width: 120px;
+      height: 40px;
+      border-radius: 4px;
+    }
+  }
+}
+</style>

+ 1 - 0
src/views/dataReport_manage/index.scss

@@ -18,6 +18,7 @@
 			color: #2D8CF0;
 			cursor: pointer;
 			border-radius:4px;
+			flex-shrink: 0;
 			&.act {
 				background: #409EFF;
 				color: #fff;

+ 172 - 0
src/views/dataReport_manage/statistic/abnormalRenewal.vue

@@ -0,0 +1,172 @@
+<template>
+    <div class="statistic-container" ref="reference">
+        <div class="frequency-cont" style="position: relative;">
+			<ul class="frequency-ul">
+				<li v-for="tab in staticTabs" :key="tab" :class="{act: tab=== default_tab}" @click="changeTabHandle(tab)">{{ tab }}</li>
+			</ul>
+			<date-picker
+                v-model="select_date"
+                type="date" 
+                range
+                value-type="format"
+                :clearable="false"
+                @change="dateChange"
+                placeholder="请选择统计时间"
+            />
+            <span style="color:#A3A3A3;display:inline-block;margin-left:20px">续约异常:合同到期后两个月内未签约</span>
+
+            <div style="color:#409EFF;position: absolute;top:10px;right:10px;cursor: pointer;" @click="showChart=true">
+                <img src="~@/assets/img/icons/changeLang.png" alt="">
+                <span style="display:inline-block;position: relative;top:-3px;left:3px">统计图</span>
+            </div>
+        </div>
+        <div class="table-cont" v-show="dataLoading">
+            <div class="table-body-wrapper">
+                <table>
+                    <thead>
+						<tr>
+							<td class="thead-rs">销售</td>
+                            <td 
+                                v-for="item in tableThead"
+								:key="item" 
+								class="head-column"
+                            >{{item}}</td>
+						</tr>
+					</thead>
+                    <tbody>
+                        <tr v-for="rs in sellerList" :key="rs.SellerId">
+                            <td class="thead-rs">{{rs.SellerName}}</td>
+                            <td 
+								:class="['data-cell',{link: data.UnusualRenewNum}]" 
+								v-for="data,index in rs.CompanyRenewRecordNumList" 
+								:key="data.UnusualRenewIds"
+							>		
+								<span 
+									@click="goList(data,index,rs)"
+								>
+									{{ data.UnusualRenewNum !== 0 ? data.UnusualRenewNum : '' }}
+								</span>
+							</td>
+                        </tr>
+                    </tbody>
+                    <tfoot>
+                        <tr>
+                            <td>合计</td>
+                            <td 
+                                :class="['data-cell',{link: item.UnusualRenewNum}]" 
+                                v-for="item,index in summaryList" 
+                                :key="item.UnusualRenewIds"
+                            >
+                                <span
+                                    @click="goList(item,index,{SellerName:'合计'})"
+                                >
+                                    {{item.UnusualRenewNum||''}}
+                                </span>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td>
+                                <span>异常率</span>
+                                <el-tooltip 
+									effect="dark" 
+									placement="top-start" 
+									content="异常率=当期续约异常客户总数/截止当期系统中存量客户总数"
+								>
+									<i class="el-icon-info"/>
+								</el-tooltip>
+                            </td>
+                            <td v-for="item in summaryList" :key="item.UnusualRenewIds">{{item.UnusualRate||''}}</td>
+                        </tr>
+                    </tfoot>
+                </table>
+            </div>
+        </div>
+        <abnormalRenewalChart v-if="showChart" @close="showChart=false"/>
+    </div>
+</template>
+
+<script>
+import { dataMainInterface } from '@/api/api.js';
+import mixin from './mixin';
+import abnormalRenewalChart from '../components/abnormalRenewalChart.vue';
+export default {
+    name:'abnormalRenewal',
+    mixins: [ mixin ],
+    components:{abnormalRenewalChart},
+    computed:{
+        tableThead:function(){
+            if(['周度统计表','月度统计表'].includes(this.default_tab)){
+                return this.tableTheadColumns
+            }
+            return ['续约异常']
+        }
+    },
+
+    data() {
+        return {
+            sellerList:[],
+            summaryList:[],
+            showChart:false,
+        }
+    },
+    created() {
+        this.getTableData()
+    },
+    methods:{
+
+        getTableData(){
+            this.dataLoading=true
+            this.sellerList=[]
+            this.summaryList=[]
+            dataMainInterface.unusualRenewalCustomStatistic({
+                DataType: this.default_tab === '周度统计表' ? 'week' : this.default_tab === '月度统计表' ? 'month' : 'time_interval',
+				StartDate: this.select_date ? this.select_date[0] : '',
+				EndDate: this.select_date ? this.select_date[1] : '',
+            }).then(res=>{
+                const { Data,Ret } = res;
+				if(Ret !== 200) return
+                this.sellerList=Data.List||[]
+                this.summaryList=Data.SummaryList||[]
+            })
+        },
+
+        /* 进入列表 */
+        goList({UnusualRenewNum,UnusualRenewIds},index,parent) {
+            // if(!value) return
+            let column_title = this.getColumnTitle(index);
+            let title=encodeURIComponent(`${column_title}/${parent.SellerName}`);
+                    
+            sessionStorage.setItem('renewalTab',this.activeTab.tabName)
+            const{href}=this.$router.resolve({
+                path: '/abnormalRenewalCustomlist',
+                query: {
+                    ids: encodeURIComponent(UnusualRenewIds),
+                    title
+                }
+            })
+            window.open(href,'_blank')
+        },
+
+        /* 获取数据对应表头 */
+        getColumnTitle(index) {
+			let title = '';
+
+			if(['周度统计表','月度统计表'].includes(this.default_tab)) {
+				title=this.tableTheadColumns[index] 
+			} else {
+				title = this.default_tab || `${this.select_date[0]}~${this.select_date[1]}`;
+			}
+			
+			return title
+		}
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+@import './index.scss';
+.statistic-container{
+    height: calc(100vh - 180px);
+    position: relative;
+}
+</style>

+ 100 - 22
src/views/dataReport_manage/statistic/contractCustom.vue

@@ -99,34 +99,40 @@
 							<td rowspan="2" class="thead-rs">组别</td>
 							<td rowspan="2" class="thead-rs">销售</td>
 							<td rowspan="2" class="thead-rs-typeTwo">
-				未续约
-				<el-tooltip 
+								未续约
+								<el-tooltip 
 									effect="dark" 
 									placement="top-start" 
 									:content="tipMap.get('未续约')"
-					v-if="['周度统计表'].includes(default_tab)"
 								>
-					<i class="el-icon-info"/>
+									<i class="el-icon-info"/>
 								</el-tooltip>
-				</td>
+							</td>
 							<td rowspan="2" class="thead-rs-typeTwo">
-				续约跟进
-				<el-tooltip 
+								续约跟进
+								<el-tooltip 
 									effect="dark" 
 									placement="top-start" 
 									:content="tipMap.get('续约跟进')"
-					v-if="['周度统计表'].includes(default_tab)"
 								>
-					<i class="el-icon-info"/>
+									<i class="el-icon-info"/>
 								</el-tooltip>
-				</td>
+							</td>
 							<td
-								:colspan="['周度统计表','月度统计表'].includes(default_tab) ? 2 : 1"
+								:colspan="['周度统计表','月度统计表'].includes(default_tab) ? activeTab.tabName !== 'QY'? 3:2 : 1"
 								v-for="item in contractTableThead"
 								:key="item" 
 								class="head-column"
 							>
 								{{item}}
+								<el-tooltip 
+									effect="dark" 
+									placement="top-start"
+									v-if="!['周度统计表','月度统计表'].includes(default_tab)"
+									:content="tipMap.get(item)"
+								>
+									<i class="el-icon-info"/>
+								</el-tooltip>
 							</td>	
 						</tr>
 						<tr v-if="['周度统计表'].includes(default_tab)">
@@ -153,12 +159,54 @@
 										<i class="el-icon-info"/>
 									</el-tooltip>
 								</td>
+								<td :key="index+'_2'" v-if="activeTab.tabName !== 'QY'">
+									续约异常
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('续约异常')"
+									>
+										<i class="el-icon-info"/>
+									</el-tooltip>
+								</td>
 							</template>
 						</tr>
 						<tr v-else-if="['月度统计表'].includes(default_tab)">
 							<template v-for="(item,index) in new Array(6).fill('')">
-								<td :key="index+'_0'">到期</td>
-								<td :key="index+'_1'">续约</td>
+								<td :key="index+'_0'">
+									到期
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('到期')"
+									>
+										<i class="el-icon-info"/>
+									</el-tooltip>
+								</td>
+								<td :key="index+'_1'">
+									续约
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('续约')"
+									>
+										<i class="el-icon-info"/>
+									</el-tooltip>
+								</td>
+								<td :key="index+'_2'" v-if="activeTab.tabName !== 'QY'">
+									续约异常
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('续约异常')"
+									>
+										<i class="el-icon-info"/>
+									</el-tooltip>
+								</td>
 							</template>
 						</tr>
 					</thead>
@@ -222,6 +270,30 @@
 								</span>
 							</td>
 						</tr>
+						<tr v-if="activeTab.tabName !== 'QY'">
+							<td colspan="2">
+								<span>异常率</span>
+								<el-tooltip 
+									effect="dark" 
+									placement="top-start" 
+									:content="tipMap.get('异常率')"
+								>
+									<i class="el-icon-info"/>
+								</el-tooltip>
+							</td>
+							<td>
+								<span></span>
+							</td>
+							<td>
+								<span></span>
+							</td>
+							<template v-if="['周度统计表','月度统计表'].includes(default_tab)">
+								<td v-for="(item,index) in UnusualRateArr" :key="index" colspan="3">{{item.UnusualRate}}</td>
+							</template>
+							<template v-else>
+								<td colspan="3">{{UnusualRateArr[0].UnusualRate}}</td>
+							</template>
+						</tr>
 					</tfoot>
 				</table>
 			</div>	
@@ -238,14 +310,18 @@ export default {
   mixins: [ mixin ],
   data() {
     return {
-      tipMap:new Map([
-        ['未续约','之前是正式客户,现在是冻结或流失状态的客户'],
-        ['续约跟进','之前是正式客户,现在是试用状态且未经历过冻结或流失状态的客户'],
-        ['到期','合同到期时间在统计时间段内的客户'],
-        ['续约','续约申请审批通过时间在所选时间段内的客户']
-      ]),
-			notRenewNumAll:0, // 未续约总合计
-			renewFollowNumAll:0, // 续约跟进总合计
+      	tipMap:new Map([
+			['未续约','之前是正式客户,现在是冻结或流失状态的客户'],
+			['续约跟进','之前是正式客户,现在是试用状态且未经历过冻结或流失状态的客户'],
+			['到期','合同到期时间在统计时间段内的客户'],
+			['续约','续约申请审批通过时间在所选时间段内的客户'],
+			['续约异常','合同到期后两个月内未签约 '],
+			['异常率','异常率=当期续约异常客户总数/截止当期系统中存量客户总数']
+
+		]),
+		notRenewNumAll:0, // 未续约总合计
+		renewFollowNumAll:0, // 续约跟进总合计
+		UnusualRateArr:[],
     }
   },
   computed:{
@@ -253,7 +329,7 @@ export default {
       if(['周度统计表','月度统计表'].includes(this.default_tab)){
         return this.tableTheadColumns
       }
-      return  ['到期','续约']
+      return this.activeTab.tabName !== 'QY'?['到期','续约','续约异常']:['到期','续约']
     }
   },
   created(){
@@ -281,6 +357,8 @@ export default {
 				this.totalGroupArr = this.filterTableData(Data.CompanyRenewRecordNumList,{},'renew');
 				this.notRenewNumAll = Data.CompanyRenewRecordNumList[0].NotRenewNum
 				this.renewFollowNumAll = Data.CompanyRenewRecordNumList[0].RenewFollowNum
+				// 异常率处理
+				this.UnusualRateArr= Data.CompanyRenewRecordNumList||[]
 				//处理数据结构
 				let data = []
 				if(this.activeTab.productionId ==1){

+ 52 - 13
src/views/dataReport_manage/statistic/mixin.js

@@ -133,20 +133,59 @@ export default {
 					}
 				]))
 			}else if(type == 'renew'){
-				list = data.map(item => ([
-					{
-						key: '到期',
-						value: item.ExpireNum,
-						ids: item.ExpireIds,
-						...other_param
-					},
-					{
-						key: '续约',
-						value:item.RenewNum,
-						ids: item.RenewIds,
-						...other_param
+				list=data.map(item=>{
+					if(this.activeTab.tabName !== 'QY'){
+						return [
+							{
+								key: '到期',
+								value: item.ExpireNum,
+								ids: item.ExpireIds,
+								...other_param
+							},
+							{
+								key: '续约',
+								value:item.RenewNum,
+								ids: item.RenewIds,
+								...other_param
+							},
+							{
+								key: '续约异常',
+								value:item.UnusualRenewNum,
+								ids: item.UnusualRenewIds,
+								...other_param
+							}
+						]
+					}else{
+						return [
+							{
+								key: '到期',
+								value: item.ExpireNum,
+								ids: item.ExpireIds,
+								...other_param
+							},
+							{
+								key: '续约',
+								value:item.RenewNum,
+								ids: item.RenewIds,
+								...other_param
+							},
+						]
 					}
-				]))
+				})
+				// list = data.map(item => ([
+				// 	{
+				// 		key: '到期',
+				// 		value: item.ExpireNum,
+				// 		ids: item.ExpireIds,
+				// 		...other_param
+				// 	},
+				// 	{
+				// 		key: '续约',
+				// 		value:item.RenewNum,
+				// 		ids: item.RenewIds,
+				// 		...other_param
+				// 	}
+				// ]))
 			}else if(type==='ficcproduct'){
 				list = data.map(item => ([
 					{

+ 42 - 3
src/views/dataReport_manage/statistic/newCustom.vue

@@ -96,13 +96,52 @@
 								class="head-column"
 							>
 								{{item}}
+								<el-tooltip 
+									effect="dark" 
+									placement="top-start"
+									v-if="!['周度统计表','月度统计表'].includes(default_tab)"
+								>
+									<i class="el-icon-info"/>
+									<div slot="content" v-html="tipMap.get(item==='试用'?item:`${item}${activeTab.productionId}`)"></div>
+								</el-tooltip>
 							</td>	
 						</tr>
 						<tr v-if="['月度统计表'].includes(default_tab)">
 							<template v-for="(item,index) in new Array(6).fill('')">
-								<td :key="index+'_0'">试用</td>
-								<td :key="index+'_1'">活跃</td>
-								<td :key="index+'_2'">正式</td>
+								<td :key="index+'_0'">
+									试用
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('试用')"
+									>
+										<i class="el-icon-info"/>
+									</el-tooltip>
+								</td>
+								<td :key="index+'_1'">
+									活跃
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('活跃'+activeTab.productionId)"
+									>
+										<i class="el-icon-info"/>
+										<div slot="content" v-html="tipMap.get('活跃'+activeTab.productionId)"></div>
+									</el-tooltip>
+								</td>
+								<td :key="index+'_2'">
+									正式
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('正式'+activeTab.productionId)"
+									>
+										<i class="el-icon-info"/>
+									</el-tooltip>
+								</td>
 							</template>
 						</tr>
 						<tr v-else-if="['周度统计表'].includes(default_tab)">

+ 0 - 3
src/views/dataReport_manage/statistic/todoTask.vue

@@ -106,7 +106,6 @@
 										effect="dark" 
 										placement="top-start"
 										content="截止日期小于等于今天的未完成To Do任务统计"
-										v-if="['周度统计表'].includes(default_tab)"
 									>
 										<i class="el-icon-info"/>
 									</el-tooltip>
@@ -119,7 +118,6 @@
 										effect="dark" 
 										placement="top-start"
 										content="进行中且未到截止日期的To Do任务统计"
-										v-if="['周度统计表'].includes(default_tab)"
 									>
 										<i class="el-icon-info"/>
 									</el-tooltip>
@@ -132,7 +130,6 @@
 										effect="dark" 
 										placement="top-start"
 										content="该销售累计完成To Do任务数量"
-										v-if="['周度统计表'].includes(default_tab)"
 									>
 										<i class="el-icon-info"/>
 									</el-tooltip>

+ 6 - 1
src/views/login_manage/EmailModel.vue

@@ -77,6 +77,7 @@ export default {
             timer:0,
             codeStr:'获取验证码',
             codeCountDown:60,
+            isGetNewCode:false,
             form:{
                 email:'',
                 picCode:'',
@@ -102,10 +103,12 @@ export default {
     methods: {
         checkForm(){
             //首先检查是否是重新获取验证码
-            if(this.codeStr==='重新获取'){
+            if(this.codeStr==='重新获取'&&!this.isGetNewCode){
                 //引导用户重新输入图形验证码
                 this.getCodePic()
                 this.form.picCode = ''
+                this.isGetNewCode = true
+                return
             }
             //检查邮箱和图形验证码是否正确
             const {email,picCode} = this.form
@@ -127,7 +130,9 @@ export default {
             }).then(res=>{
                 if(res.Ret!==200) return 
                 this.$message.success('验证码已发送')
+                this.isGetNewCode = false
                 //60秒倒计时
+                this.codeCountDown = 60
                 this.countDown()
                 this.timer = setInterval(()=>{
                     this.countDown()

+ 7 - 1
src/views/login_manage/MobileModel.vue

@@ -87,6 +87,7 @@ export default {
             timer:0,
             codeStr:'获取验证码',
             codeCountDown:60,
+            isGetNewCode:false,
             form:{
                 mobile:'',
                 picCode:'',
@@ -113,10 +114,13 @@ export default {
     methods: {
         checkForm(){
             //首先检查是否是重新获取验证码
-            if(this.codeStr==='重新获取'){
+            if(this.codeStr==='重新获取'&&!this.isGetNewCode){
                 //引导用户重新输入图形验证码
+                this.$message.warning('重新获取需再次输入图形验证码')
                 this.getCodePic()
                 this.form.picCode = ''
+                this.isGetNewCode = true
+                return
             }
             //检查手机号和图形验证码是否正确
             const {picCode,mobile} = this.form
@@ -143,7 +147,9 @@ export default {
             }).then(res=>{
                 if(res.Ret!==200) return 
                 this.$message.success('验证码已发送')
+                this.isGetNewCode = false
                 //60秒倒计时
+                this.codeCountDown = 60
                 this.countDown()
                 this.timer = setInterval(()=>{
                     this.countDown()

+ 1 - 1
src/views/login_manage/modelMixins.js

@@ -21,7 +21,7 @@ export default {
         },
         countDown(){
             /* if(!this.timer) return */
-            console.log('click down')
+            //console.log('click down')
             this.codeCountDown--
             this.codeStr=`重新获取(${this.codeCountDown})秒`
             if(this.codeCountDown<=0){

+ 21 - 8
src/views/operation_manage/AIQA/AIQA.vue

@@ -31,7 +31,7 @@
                     <span>{{activeWindowId<=0?'弘则AI助手使用说明':`${historyList.length||0} messages`}}</span>
                 </div>
                 <div class="select-box">
-                    <el-select v-model="model" :class="{'hint':showHint}" :disabled="isTyping||(windowContentLoading&&windowContentLoading.visible)" ref="modelSelect" 
+                    <!-- <el-select v-model="model" :class="{'hint':showHint}" :disabled="isTyping||(windowContentLoading&&windowContentLoading.visible)" ref="modelSelect" 
                         @click.native="selectClick"
                         @change="changeModel">
                         <el-option v-for="item in modelList" :key="item.label"
@@ -40,7 +40,7 @@
                             <span style="float:left">{{item.label}}</span>
                             <span style="float:right"><img :src="item.icon" style="margin-top:5px;width:24px;height:24px;"/></span>
                         </el-option>
-                    </el-select>
+                    </el-select> -->
                 </div>
             </div>
             <!-- 仅这一部分滚动 -->
@@ -86,17 +86,25 @@ export default {
             /* window-content*/
             historyList:[],//当前窗口历史记录
             inputText:'',
-            model:'',//当前选择的模型
+            model:'GPT-4 Turbo',//当前选择的模型
             modelOldValue:'',
             modelList:[
                 {
-                    label:'gpt-3.5-turbo',
-                    icon:require('@/assets/img/icons/chat-gpt.png'),
+                    label:'GPT-4 Turbo',
+                    icon:require('@/assets/img/icons/gpt-4-turbo.png'),
+                },
+                {
+                    label:'GPT4',
+                    icon:require('@/assets/img/icons/gpt-4.png'),
                 },
                 {
                     label:'gpt-3.5-turbo-16k',
                     icon:require('@/assets/img/icons/chat-gpt-16k.png'),
                 },
+                {
+                    label:'gpt-3.5-turbo',
+                    icon:require('@/assets/img/icons/chat-gpt.png'),
+                },
                 {
                     label:'eta',
                     icon:require('@/assets/img/icons/horizon.png'),
@@ -105,6 +113,7 @@ export default {
             showHint:false,//选择模型提示
             isTyping:false,//是否处于打字动画中
             windowContentLoading:null,
+            answerLoading:false,//回答中
         };
     },
     watch:{
@@ -153,7 +162,7 @@ export default {
                 this.historyList = List||[]
                 this.windowContentLoading&&this.windowContentLoading.close()
                 //使用模型
-                this.model = this.historyList.length?this.historyList[this.historyList.length-1].Model:''
+                this.model = this.historyList.length?this.historyList[this.historyList.length-1].Model:'GPT-4 Turbo'
                 //如果有历史记录,则滚动到底部
                 this.$nextTick(()=>{
                     const windowContentWrap = document.querySelector('.window-content-wrap')
@@ -199,7 +208,7 @@ export default {
             this.activeWindowId=0
             this.activeWindow=null
             this.historyList=[]
-            this.model=''
+            this.model='GPT-4 Turbo'
             //this.inputText=''
             this.isTyping = false
         },
@@ -285,7 +294,7 @@ export default {
                 this.inputText+='\n'
                 return
             }
-            if(this.isTyping){
+            if(this.isTyping||this.answerLoading){
                 this.$message.warning('请等待回答完成')
                 return
             }
@@ -302,6 +311,7 @@ export default {
                 this.$message.warning('请输入提问')
                 return
             }
+            this.answerLoading=true
             this.activeWindowId===0&&(this.activeWindowId = -1)
             //this.activeWindowId!==0&&this.getWindowDetail()
             //mock 加入到historyList中
@@ -331,6 +341,7 @@ export default {
                 Ask:inputText,
                 Model:this.model
             }).then(res=>{
+                this.answerLoading=false
                 //在回答未获取前切换了新窗口
                 if(this.historyList.length===0){
                     this.getWindowList()
@@ -365,6 +376,8 @@ export default {
                 msg.Model = Model
                 msg.isPlay = true
                 this.historyList.splice(this.historyList.length-1,1,msg)
+            }).catch(()=>{
+                this.answerLoading=false
             })
         },
         //获取窗口列表

+ 4 - 2
src/views/operation_manage/AIQA/components/messageItem.vue

@@ -31,7 +31,9 @@ export default {
                 'user':require('@/assets/img/set_m/user_img.png'),
                 'gpt-3.5-turbo':require('@/assets/img/icons/chat-gpt.png'),
                 'gpt-3.5-turbo-16k':require('@/assets/img/icons/chat-gpt-16k.png'),
-                'eta':require('@/assets/img/icons/horizon.png')
+                'eta':require('@/assets/img/icons/horizon.png'),
+                'GPT4':require('@/assets/img/icons/gpt-4.png'),
+                'GPT-4 Turbo':require('@/assets/img/icons/gpt-4-turbo.png'),
             },
             isPlay:false,//是否播放动画
             typingText:'',
@@ -57,7 +59,7 @@ export default {
     },
     methods: {
         async playTyping(){
-            const writeText = (text,delay=150)=>{
+            const writeText = (text,delay=20)=>{
                 return new Promise((res,rej)=>{
                     setTimeout(()=>{
                         this.typingText+=text

+ 2 - 3
src/views/operation_manage/AIQA/components/newWindowHint.vue

@@ -1,9 +1,8 @@
 <template>
     <div class="new-window-hint-wrap">
         <p class="title">使用说明:</p>
-        <p>1、每账号每天最高50次问答。</p>
-        <p>2、在同一个对话窗口内提问,选择同一模型可联系上下文回答,切换模型后不支持。</p>
-        <p>3、历史问答默认用该对话窗口内第一个提问命名,可修改。</p>
+        <p>1、每账号每天最高500次问答。</p>
+        <p>2、历史问答默认用该对话窗口内第一个提问命名,可修改。</p>
     </div>
 </template>
 

+ 119 - 132
src/views/rai_manage/components/addChoiceness.vue

@@ -11,7 +11,7 @@
           </el-select>
         </el-col>
         <el-col :span="12">
-          <el-select v-if="updateMode == '继承往期'" v-model="inheritNum" placeholder="选择继承第几期" clearable @clear="inheritNumClear" @change="getDetail">
+          <el-select v-if="updateMode == '继承往期'" v-model="inheritNum" placeholder="选择继承第几期" clearable @change="getDetail">
             <el-option v-for="item in updateModeList" :key="item.Periods" :label="item.InheritPeriodsName" :value="item.Periods"></el-option>
           </el-select>
         </el-col>
@@ -42,7 +42,7 @@
           </el-form-item>
           <!-- 变更说明 -->
           <!-- 富文本 -->
-          <rich-text ref="oneRich" :spareId="contentValue" :isText="contentText" />
+          <rich-text ref="oneRich" v-model="marketStrategy" :spareId="contentValue" :isText="contentText" />
           <el-form-item prop="reportLink">
             <div style="display: flex; align-items: center; margin-top: 10px">
               <span style="flex-shrink: 0">详细报告链接:</span>
@@ -58,47 +58,54 @@
             </div>
           </draggable>
           <div v-for="(item, index) in industryList" :key="item.ChartPermissionId">
-            <RichText v-show="industryIndex == index" :ref="'logic' + index" :spareId="'logictest' + index" :isText="contentTextLogic" />
-          </div>
-          <draggable :list="industryListItem" animation="300" class="classification" filter=".addIndustrial" :move="onMove" @update="ificationSortChange">
-            <div v-for="(val, num) in industryListItem" :key="val.IndustrialSubjectId" class="industrial" @click="ificationIndustrialBtn(val, num)" :class="num == ificationIndustrial ? 'pitch' : ''">
-              <span style="margin-right: 19px">{{ val.IndustrialSubjectName }}</span>
-              <span v-if="num == ificationIndustrial">
-                <img src="~@/assets/img/icons/edit1.png" style="width: 12px; height: 12px; marginright: 10px" @click="editText(val, num)" />
-                <i class="el-icon-close" @click="deleteClassify(val, num)"></i>
-              </span>
-            </div>
-            <div class="addIndustrial" @click="addMulti">
-              <i class="el-icon-plus"></i>
-              <span>添加标的</span>
-            </div>
-          </draggable>
-          <template v-for="(val, num) in industryListItem">
-            <div class="industrial-is-new" :key="val.IndustrialSubjectId" v-if="num == ificationIndustrial">
-              <el-checkbox v-model="val.IsNew" :true-label="1" :false-label="0">显示new标签</el-checkbox>
+            <div v-show="industryIndex == index">
+              <RichText v-model="item.BodyChartSummary" :ref="'logic' + index" :spareId="'logictest' + index" :isText="contentTextLogic" />
+              <draggable :list="item.List" animation="300" class="classification" filter=".addIndustrial" :move="onMove" @update="ificationSortChange">
+                <div v-for="(val, num) in item.List" :key="val.IndustrialSubjectId" class="industrial" @click="ificationIndustrialBtn(val, num)" :class="num == ificationIndustrial ? 'pitch' : ''">
+                  <span style="margin-right: 19px">{{ val.IndustrialSubjectName }}</span>
+                  <span v-if="num == ificationIndustrial">
+                    <img src="~@/assets/img/icons/edit1.png" style="width: 12px; height: 12px; marginright: 10px" @click="editText(val, num)" />
+                    <i class="el-icon-close" @click="deleteClassify(val, num)"></i>
+                  </span>
+                </div>
+                <div class="addIndustrial" @click="addMulti" v-if="industryIndex == index">
+                  <i class="el-icon-plus"></i>
+                  <span>添加标的</span>
+                </div>
+              </draggable>
+              <template v-for="(val, num) in item.List">
+                <div :key="val.IndustrialSubjectId" v-show="industryIndex == index">
+                  <div class="industrial-is-new" v-show="num == ificationIndustrial">
+                    <el-checkbox v-model="val.IsNew" :true-label="1" :false-label="0">显示new标签</el-checkbox>
+                  </div>
+                  <div style="margin-bottom: 20px; display: flex; align-items: center" v-show="num == ificationIndustrial">
+                    <div style="display: flex; align-items: center" v-for="(son, num) in val.CompanyLabel" :key="num">
+                      <el-input style="width: 260px; margin-right: 15px" v-model="son.name" placeholder="请输入公司标签"></el-input>
+                      <img class="delete-item-icon" v-if="num > 0" @click="deleteLabelItem(val, num)" src="~@/assets/img/icons/delete-Item.png" alt="" />
+                    </div>
+                    <el-tooltip class="item" effect="dark" content="添加标签" placement="top-start">
+                      <img @click="addLabelClick(val)" class="editsty" src="~@/assets/img/set_m/add_ico.png" />
+                    </el-tooltip>
+                  </div>
+                  <rich-text :ref="'twoRich' + num" v-model="val.Body" :spareId="contentValueTwo" :isText="contentTextTwo" v-show="num == ificationIndustrial" />
+                </div>
+              </template>
             </div>
-          </template>
-          <div v-if="industryListItem.length" style="margin-bottom: 20px; display: flex; align-items: center">
-            <div style="display: flex; align-items: center" v-for="(val, num) in industryListItem[ificationIndustrial].CompanyLabel" :key="num">
-              <el-input style="width: 260px; margin-right: 15px" v-model="val.name" placeholder="请输入公司标签"></el-input>
-              <img class="delete-item-icon" v-if="num > 0" @click="deleteLabelItem(val, num)" src="~@/assets/img/icons/delete-Item.png" alt="" />
-            </div>
-            <el-tooltip class="item" effect="dark" content="添加标签" placement="top-start">
-              <img @click="addLabelClick" class="editsty" src="~@/assets/img/set_m/add_ico.png" />
-            </el-tooltip>
           </div>
         </div>
 
-        <rich-text ref="twoRich" :spareId="contentValueTwo" :isText="contentTextTwo" />
-        <div class="content-resource">
-          <span class="resource">产业资源包:</span>
-          <span class="show">{{ industrialSubjectName }}</span>
-        </div>
-        <div class="content-resource">
-          <span class="resource">综述报告:</span>
-          <span class="show">{{ overviewList.Title }}</span>
-          <div style="margin-left: 20px">
-            <el-switch @change="switchChangeHandler" v-model="overviewList.IsShowOverviewArticle" :active-value="1" :inactive-value="0" active-text="显示链接" inactive-text="不显示链接"> </el-switch>
+        <div>
+          <div class="content-resource">
+            <span class="resource">产业资源包:</span>
+            <span class="show">{{ industrialSubjectName }}</span>
+          </div>
+          <div class="content-resource">
+            <span class="resource">综述报告:</span>
+            <span class="show">{{ overviewList.Title }}</span>
+            <div style="margin-left: 20px">
+              <el-switch @change="switchChangeHandler" v-model="overviewList.IsShowOverviewArticle" :active-value="1" :inactive-value="0" active-text="显示链接" inactive-text="不显示链接">
+              </el-switch>
+            </div>
           </div>
         </div>
         <div class="content-bottom">
@@ -131,10 +138,11 @@
 import RichText from "./richText.vue";
 import { raiInterface } from "@/api/api.js";
 import draggable from "vuedraggable";
+import TemplateMessage from "./apply/templateMessage.vue";
 
 export default {
   name: "",
-  components: { RichText, draggable },
+  components: { RichText, draggable, TemplateMessage },
   props: {},
   data() {
     return {
@@ -154,10 +162,6 @@ export default {
       },
       rules: {
         title: [{ required: true, message: "请输入标题", trigger: "blur" }],
-        // author: [{ required: true, message: "请输入作者", trigger: "blur" }],
-        // time: [{ required: true, message: "请输入时间", trigger: "change" }],
-        // explain: [{ required: true, message: "请输入产品说明", trigger: "blur" }],
-        // reportLink: [{ required: true, message: "请输入报告链接", trigger: "blur" }],
       },
       industryList: [], //行业
       industryIndex: 0, //
@@ -168,61 +172,76 @@ export default {
       companyList: [],
       timeout: null,
       isShowStatus: true,
-      industryListItem: [],
       industrialSubjectName: "",
       chartPermissionId: "", //分类id
       subjectList: [],
       updateModeList: [], //期数的数组
       editNum: "",
       overviewList: {},
+      marketStrategy: "",
+      timeInterval: null, // 定时器
     };
   },
   computed: {},
-  watch: {
-    industryListItem: {
-      handler(nval) {
-        if (nval.length > 0) {
-          this.industrialSubjectName = this.industryListItem[this.ificationIndustrial].IndustrialManagementName || "";
-          this.overviewList = {
-            ArticleId: this.industryListItem[this.ificationIndustrial].OverviewArticleId,
-            Title: this.industryListItem[this.ificationIndustrial].OverviewArticleTitle,
-            IsShowOverviewArticle: this.industryListItem[this.ificationIndustrial].IsShowOverviewArticle,
-          };
-        } else {
-          this.industrialSubjectName = "";
-          this.overviewList = { ArticleId: 0, Title: "", IsShowOverviewArticle: 0 };
-        }
-      },
-      deep: true,
-    },
-  },
-  created() {},
   mounted() {
     if (this.$route.query.id) {
       this.isShowStatus = this.$route.query.status == 0;
       this.getDetail();
     } else {
       this.getNoTacticsfirst();
+      this.dataInit();
     }
     this.getListPeriods();
   },
   methods: {
+    // 报告的缓存处理数据
+    dataInit() {
+      if (sessionStorage.getItem("addChoicenessQY")) {
+        let data = JSON.parse(sessionStorage.getItem("addChoicenessQY"));
+        setTimeout(async () => {
+          this.industryList = data.industryList;
+          this.industryIndex = data.industryIndex;
+          this.ificationIndustrial = data.ificationIndustrial;
+          this.updateMode = data.updateMode;
+          this.inheritNum = data.inheritNum;
+          this.companyList = data.companyList;
+          this.industrialSubjectName = data.industrialSubjectName;
+          this.chartPermissionId = data.chartPermissionId;
+          this.subjectList = data.subjectList;
+          this.updateModeList = data.updateModeList;
+          this.editNum = data.editNum;
+          this.overviewList = data.overviewList;
+          this.ruleForm = data.ruleForm;
+          this.marketStrategy = data.MarketStrategy;
+        }, 200);
+      }
+      this.timeInterval = setInterval(() => {
+        let params = {
+          industryList: this.industryList,
+          industryIndex: this.industryIndex,
+          ificationIndustrial: this.ificationIndustrial,
+          updateMode: this.updateMode,
+          inheritNum: this.inheritNum,
+          companyList: this.companyList,
+          industrialSubjectName: this.industrialSubjectName,
+          chartPermissionId: this.chartPermissionId,
+          subjectList: this.subjectList,
+          updateModeList: this.updateModeList,
+          editNum: this.editNum,
+          overviewList: this.overviewList,
+          ruleForm: this.ruleForm,
+          MarketStrategy: this.marketStrategy,
+        };
+        sessionStorage.setItem("addChoicenessQY", JSON.stringify(params));
+      }, 120000);
+    },
     updateModeChange() {
       if (this.updateMode == "重新编辑") {
         this.init();
         this.industryList = [];
-        this.industryListItem = [];
         this.getNoTacticsfirst();
       }
     },
-    inheritNumClear() {
-      if (this.inheritNum == "") {
-        // this.init();
-        // this.industryList=[]
-        // this.industryListItem=[]
-        // this.getNoTacticsfirst();
-      }
-    },
     //获取编辑详情
     async getDetail() {
       const res = await raiInterface.reportSelectionDetail({ ArticleId: this.$route.query.id || "", Periods: this.inheritNum || "" });
@@ -240,13 +259,12 @@ export default {
           explain: res.Data.ProductDescription, //说明
           reportLink: res.Data.ReportLink, //变更
         };
-        this.$refs["oneRich"].value = res.Data.MarketStrategy;
+        this.marketStrategy = res.Data.MarketStrategy;
         this.inheritNum = this.inheritNum ? this.inheritNum : res.Data.InheritPeriods;
         this.industryList = res.Data.List;
         setTimeout(() => {
           res.Data.List.forEach((item, index) => {
-            this.$refs["logic" + index][0].value = item.BodyChartSummary && item.BodyChartSummary;
-            item.List.forEach((key) => {
+            item.List.forEach((key, i) => {
               key.CompanyLabel = key.CompanyLabel
                 ? key.CompanyLabel.map((val, i) => {
                     let obj = {
@@ -265,8 +283,6 @@ export default {
           });
         }, 300);
         this.chartPermissionId = res.Data.List[0].ChartPermissionId;
-        this.industryListItem = res.Data.List[0].List || [];
-        this.$refs.twoRich.value = res.Data.List[0].List ? res.Data.List[0].List[0].Body : "";
         this.industrialSubjectName = res.Data.List[0].List ? res.Data.List[0].List[0].IndustrialManagementName : "";
         this.overviewList = {
           ArticleId: res.Data.List[0].List && res.Data.List[0].List[0].OverviewArticleId,
@@ -281,50 +297,20 @@ export default {
       if (res.Ret === 200) {
         this.industryList = res.Data.List;
         this.chartPermissionId = res.Data.List[0].ChartPermissionId;
-        this.industryListItem = res.Data.List[0].List || [];
       }
     },
     //点击产业的事件
     industryBtn(item, index) {
-      if (this.industryListItem.length > 0) {
-        this.industryListItem[this.ificationIndustrial].Body = this.$refs["twoRich"].value;
-      }
-      this.industryList[this.industryIndex].BodyChartSummary = this.$refs["logic" + this.industryIndex][0].value;
       if (index !== this.industryIndex) {
         this.industryIndex = index;
-        this.industryListItem = item.List || [];
-        this.industryListItem.forEach((item) => {
-          if (item.CompanyLabel && typeof item.CompanyLabel[0] === "string") {
-            item.CompanyLabel = item.CompanyLabel
-              ? item.CompanyLabel.map((key, index) => {
-                  let obj = {
-                    name: key,
-                    value: index + 1,
-                  };
-                  return obj;
-                })
-              : [
-                  {
-                    name: "",
-                    value: 1,
-                  },
-                ];
-          }
-        });
-
-        this.$refs.twoRich.value = item.List[0] ? item.List[0].Body : "";
         this.chartPermissionId = item.ChartPermissionId;
         this.ificationIndustrial = 0;
       }
     },
     //标的的点击事件 处理
     ificationIndustrialBtn(item, index) {
-      if (this.industryListItem.length > 0) {
-        this.industryListItem[this.ificationIndustrial].Body = this.$refs["twoRich"].value;
-      }
       if (index !== this.ificationIndustrial) {
         this.ificationIndustrial = index;
-        this.$refs.twoRich.value = item.Body || "";
         this.industrialSubjectName = item.IndustrialManagementName || "";
         this.overviewList = {
           ArticleId: item.OverviewArticleId,
@@ -351,7 +337,6 @@ export default {
         .then(() => {
           this.industryList[this.industryIndex].List.splice(index, 1);
           this.ificationIndustrial = 0;
-          this.$refs["twoRich"].value = this.industryList[this.industryIndex].List.length > 0 ? this.industryList[this.industryIndex].List[0].Body : "";
           this.$message({
             type: "success",
             message: "删除成功!",
@@ -440,8 +425,8 @@ export default {
               IndustrialManagementName: arr.IndustryName,
               IndustrialSubjectId: arr.IndustrialSubjectId + "",
               IndustrialSubjectName: arr.SubjectName,
-              CompanyLabel: item.List[this.editNum].CompanyLabel && item.List[this.editNum].CompanyLabel.length>0?
-                            item.List[this.editNum].CompanyLabel : [{ name: "", value: item.List.length + 1 }],
+              CompanyLabel:
+                item.List[this.editNum].CompanyLabel && item.List[this.editNum].CompanyLabel.length > 0 ? item.List[this.editNum].CompanyLabel : [{ name: "", value: item.List.length + 1 }],
               OverviewArticleId: overviewList.ArticleId,
               OverviewArticleTitle: overviewList.Title,
               IsShowOverviewArticle: overviewList.IsShowOverviewArticle,
@@ -473,12 +458,6 @@ export default {
     confirm(type) {
       this.$refs.ruleForm.validate(async (val) => {
         if (val) {
-          if (this.industryListItem.length > 0) {
-            this.industryListItem[this.ificationIndustrial].Body = this.$refs["twoRich"].value;
-          } else if (this.$refs["twoRich"].value) {
-            this.$message.error("文本内容无对应标的,请选择标的!");
-            return;
-          }
           let isText = [];
           this.industryList.forEach((item) => {
             item.List.forEach((key) => {
@@ -489,7 +468,6 @@ 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: "预览报告精选" });
@@ -497,6 +475,8 @@ export default {
           } else {
             const res = await raiInterface.industrialSubjectPreserveAndPublish(params);
             if (res.Ret === 200) {
+              clearInterval(this.timeInterval);
+              sessionStorage.removeItem("addChoicenessQY");
               this.$message.success("操作成功!");
               this.init();
               this.$router.back();
@@ -507,8 +487,10 @@ export default {
     },
     //取消
     cancel() {
-      this.$router.back();
+      clearInterval(this.timeInterval);
+      sessionStorage.removeItem("addChoicenessQY");
       this.$refs["ruleForm"].resetFields();
+      this.$router.back();
     },
     async getListPeriods() {
       const res = await raiInterface.industrialSubjectListPeriods();
@@ -525,12 +507,11 @@ export default {
         reportLink: "", //变更
       };
       this.$refs["ruleForm"].resetFields();
-      this.$refs["oneRich"].value = "";
-      this.$refs["twoRich"].value = "";
+      this.marketStrategy = "";
     },
     // 标的下添加公司标签
-    addLabelClick() {
-      this.industryListItem[this.ificationIndustrial].CompanyLabel.push({ name: "", value: this.industryListItem.length + 1 });
+    addLabelClick(item) {
+      item.CompanyLabel.push({ name: "", value: item.CompanyLabel.length + 1 });
     },
     // 处理保存的数据
     dataHandle(type) {
@@ -549,7 +530,7 @@ export default {
           ListSubject: [...item.List],
         });
       });
-      if (this.$refs["oneRich"].value == "") {
+      if (this.marketStrategy == "") {
         this.$message.error("市场策略核心逻辑汇总不能为空");
       }
       let params = {
@@ -558,7 +539,7 @@ export default {
         Department: this.ruleForm.author,
         Title: this.ruleForm.title,
         DoType: type == "发布" ? 1 : 0,
-        MarketStrategy: this.$refs["oneRich"].value,
+        MarketStrategy: this.marketStrategy,
         InheritPeriods: this.inheritNum,
         List: arr,
         ProductDescription: this.ruleForm.explain,
@@ -569,13 +550,15 @@ export default {
       return params;
     },
     deleteLabelItem(item, index) {
-      this.industryListItem[this.ificationIndustrial].CompanyLabel.splice(index, 1);
+      item.CompanyLabel.splice(index, 1);
     },
     switchChangeHandler(e) {
-      this.industryListItem.forEach((item) => {
-        if (item.OverviewArticleId === this.overviewList.ArticleId) {
-          item.IsShowOverviewArticle = e;
-        }
+      this.industryList.forEach((_) => {
+        _.List.forEach((item) => {
+          if (item.OverviewArticleId === this.overviewList.ArticleId) {
+            item.IsShowOverviewArticle = e;
+          }
+        });
       });
     },
     // 拖拽排序更新
@@ -588,7 +571,6 @@ export default {
     },
     // 排序更新后的逻辑
     sortChangeFun(currentIndex, oldIndex, newIndex) {
-      console.log({ currentIndex, oldIndex, newIndex });
       let bigger, smaller;
       if (oldIndex > newIndex) {
         bigger = oldIndex;
@@ -614,7 +596,12 @@ export default {
       // 返回false表示不允许停靠
       return !!e.relatedContext.element;
     },
-  }
+  },
+  // 路由离开了 清除定时器
+  beforeRouteLeave(to, from, next) {
+    clearInterval(this.timeInterval);
+    next();
+  },
 };
 </script>
 <style lang="scss">

+ 58 - 9
src/views/rai_manage/components/addRoadshow.vue

@@ -70,6 +70,7 @@
 import RichText from "./richText.vue";
 
 import { raiInterface } from "@/api/api.js";
+import { async } from "@antv/x6/lib/registry/marker/main";
 export default {
   name: "",
   components: { RichText },
@@ -101,6 +102,7 @@ export default {
       contentValue: "请输入内容",
       propertyDetai: [],
       isShowStatus: true,
+      timeInterval: null,
     };
   },
   computed: {},
@@ -110,14 +112,53 @@ export default {
     this.getIndustryList();
     if (this.$route.query.id) {
       this.getDetail();
+    } else {
+      this.dataInit();
     }
   },
   methods: {
-    //
+    // 报告的缓存处理数据
+    dataInit() {
+      if (sessionStorage.getItem("addRoadshowReportQY")) {
+        let data = JSON.parse(sessionStorage.getItem("addRoadshowReportQY"));
+        setTimeout(async () => {
+          this.listForm = {
+            title: data.Title, //标题
+            author: data.SellerAndMobile, //作者
+            time: data.PublishDate, //时间
+            industry: data.ChartPermissionId, //行业
+            abstract: data.Abstract,
+            reportLink: data.ReportLink,
+            property: data.IndustrialManagementId,
+            target: data.IndustrialSubjectIdStr,
+          };
+          this.$refs.twoRich.value = data.Body;
+          if (this.listForm.industry) {
+            await this.getPropertyList();
+            await this.getTargetList();
+          }
+        }, 200);
+      }
+      this.timeInterval = setInterval(() => {
+        let params = {
+          Abstract: this.listForm.abstract,
+          Body: this.$refs.twoRich.value,
+          ChartPermissionId: this.listForm.industry,
+          IndustrialManagementId: this.listForm.property,
+          IndustrialSubjectIdStr: this.listForm.target,
+          ReportLink: this.listForm.reportLink,
+          PublishDate: this.listForm.time,
+          SellerAndMobile: this.listForm.author,
+          Title: this.listForm.title,
+        };
+        sessionStorage.setItem("addRoadshowReportQY", JSON.stringify(params));
+      }, 120000);
+    },
+    // 获取数据
     async getDetail() {
       const res = await raiInterface.roadshowEssenceDetail({ ArticleId: Number(this.$route.query.id) });
       if (res.Ret === 200) {
-        this.isShowStatus=res.Data.PublishStatus==0
+        this.isShowStatus = res.Data.PublishStatus == 0;
         this.listForm = {
           title: res.Data.Title, //标题
           author: res.Data.SellerAndMobile, //作者
@@ -176,20 +217,21 @@ export default {
             Title: this.listForm.title,
             DoType: type == "发布" ? 1 : 0,
             ArticleId: this.$route.query.id ? Number(this.$route.query.id) : 0,
-          }
-          if(type == "预览"){
-            sessionStorage.setItem('roadShowPre', JSON.stringify(params));
-            let { href } = this.$router.resolve({ name: '预览路演精华' });
-            window.open(href, '_blank');
-          }else{
+          };
+          if (type == "预览") {
+            sessionStorage.setItem("roadShowPre", JSON.stringify(params));
+            let { href } = this.$router.resolve({ name: "预览路演精华" });
+            window.open(href, "_blank");
+          } else {
             const res = await raiInterface.roadshowEssencePreserveAndPublish(params);
             if (res.Ret === 200) {
               this.$message.success(`${type}成功!`);
               this.$refs.ruleForm.resetFields();
+              clearInterval(this.timeInterval);
+              sessionStorage.removeItem("addRoadshowReportQY");
               this.$router.back();
             }
           }
-
         }
       });
     },
@@ -205,10 +247,17 @@ export default {
     },
     //取消事件
     cancel() {
+      clearInterval(this.timeInterval);
+      sessionStorage.removeItem("addRoadshowReportQY");
       this.$refs.ruleForm.resetFields();
       this.$router.back();
     },
   },
+  // 路由离开了 清除定时器
+  beforeRouteLeave(to, from, next) {
+    clearInterval(this.timeInterval);
+    next();
+  },
 };
 </script>
 <style lang="scss">

+ 55 - 1
src/views/rai_manage/components/addSummary.vue

@@ -210,6 +210,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,
       synopsisText: [], //
       articleTypeName: "", //报告类型的名称
       isSource: "",
+      numNum: 0,
+      timeInterval: null,
     };
   },
   computed: {},
@@ -223,9 +225,53 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,
     if (this.$route.query.id) {
       // 编辑进来的
       this.getsummaryManagedetail();
+    } else {
+      this.dataInit();
     }
   },
   methods: {
+    // 报告的缓存处理数据
+    dataInit() {
+      if (sessionStorage.getItem(this.isSource == "HZ" ? "addSummaryParamsHZ" : "addSummaryParamsQY")) {
+        let data = JSON.parse(sessionStorage.getItem(this.isSource == "HZ" ? "addSummaryParamsHZ" : "addSummaryParamsQY"));
+        setTimeout(() => {
+          this.addOfEditForm = {
+            industry: data.ChartPermissionId, //HZ  行业
+            regions: data.ArticleTypeId,
+            title: data.Title,
+            content: data.Body,
+            synopsis: data.Abstract,
+            mobile: data.SellerAndMobile,
+            ImgUrl: data.ImgUrl,
+            nickName: data.NickName,
+            reportLink: data.ReportLink,
+            publishTime: data.PublishDate,
+            property: data.IndustrialManagementIds,
+          };
+          this.articleTypeName = data.ArticleTypeName;
+          this.markValue = data.IndustrialSubjectIds;
+          data.IndustrialManagementIds && this.markSelectFocus();
+        }, 200);
+      }
+      this.timeInterval = setInterval(() => {
+        let params = {
+          Abstract: this.addOfEditForm.synopsis,
+          Body: this.addOfEditForm.content,
+          SellerAndMobile: this.addOfEditForm.mobile,
+          NickName: this.addOfEditForm.nickName,
+          ImgUrl: this.addOfEditForm.ImgUrl,
+          Title: this.addOfEditForm.title,
+          ArticleTypeId: this.addOfEditForm.regions,
+          IndustrialSubjectIds: this.markValue,
+          IndustrialManagementIds: this.addOfEditForm.property, //产业
+          PublishDate: this.addOfEditForm.publishTime,
+          ReportLink: this.addOfEditForm.reportLink,
+          ChartPermissionId: this.addOfEditForm.industry,
+        };
+        sessionStorage.setItem(this.isSource == "HZ" ? "addSummaryParamsHZ" : "addSummaryParamsQY", JSON.stringify(params));
+        this.numNum++;
+      }, 120000);
+    },
     //点击了添加产业
     addIndustryDlgIsShow() {
       if (this.addOfEditForm.regions) {
@@ -305,7 +351,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,
         } else {
           const res = this.isSource === "HZ" ? await raiInterface.reportPreserveAndPublish(params) : await raiInterface.preserveAndPublish(params);
           if (res.Ret === 200) {
+            clearInterval(this.timeInterval);
             this.$message.success("操作成功!");
+            sessionStorage.removeItem(this.isSource == "HZ" ? "addSummaryParamsHZ" : "addSummaryParamsQY");
             this.$refs.addOfEditForm.resetFields();
             this.$router.back();
           }
@@ -314,7 +362,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,
     },
     //表单取消事件
     cancelBtn() {
+      clearInterval(this.timeInterval);
       this.$refs.addOfEditForm.resetFields();
+      sessionStorage.removeItem(this.isSource == "HZ" ? "addSummaryParamsHZ" : "addSummaryParamsQY");
       this.$router.back();
     },
     //获取行业
@@ -387,7 +437,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,
       }
     },
     propertyChange() {
-      console.log("change");
       this.markOptions = [];
       this.markValue = "";
     },
@@ -470,6 +519,11 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,
       });
     },
   },
+  // 路由离开了 清除定时器
+  beforeRouteLeave(to, from, next) {
+    clearInterval(this.timeInterval);
+    next();
+  },
 };
 </script>
 <style lang="scss">

+ 1 - 2
src/views/rai_manage/components/apply/applyDialog.vue

@@ -110,8 +110,7 @@ export default {
     isType() {
       if (this.selectionArr.length > 0) {
         return this.selectionArr.some(
-          (item) =>
-            (item.ActivityTypeName == "公司调研电话会" && item.LimitPeopleNum !== 0) || item.ActivityTypeName == "专家电话会" || item.ActivityTypeName == "分析师电话会" || item.IsYidongConduct == 1
+          (item) => item.ActivityTypeName == "公司调研电话会" || item.ActivityTypeName == "专家电话会" || item.ActivityTypeName == "分析师电话会" || item.IsYidongConduct == 1
         );
       }
     },

+ 1 - 0
src/views/rai_manage/components/reportComponents/RichTextMixins.js

@@ -3,6 +3,7 @@ export default {
     var that = this;
     return {
       froalaConfig: {
+        key: "BWC6D-16D3B2F3C2H1A6A7wdwgacxuB-33c1fB2twtfG3A7A6B6A3B3B2G3D2H2==",
         toolbarButtons: [
           "textColor",
           "bold",

+ 14 - 1
src/views/rai_manage/components/richText.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="richtext">
-    <froala :id="'editor' + spareId" :tag="'textarea'" :config="froalaConfig" v-model="value"></froala>
+    <froala :id="'editor' + spareId" :tag="'textarea'" :config="froalaConfig" v-model="valueText" @input="inputHandler"></froala>
   </div>
 </template>
 
@@ -9,6 +9,10 @@ import VueFroala from "vue-froala-wysiwyg";
 export default {
   name: "",
   components: {},
+  model: {
+    prop: "valueText",
+    event: "contentText",
+  },
   props: {
     spareId: {
       type: String,
@@ -19,6 +23,10 @@ export default {
       required: true,
       default: "",
     },
+    valueText: {
+      type: String,
+      required: true,
+    },
   },
   watch: {
     isText: {
@@ -105,6 +113,11 @@ export default {
       value: "",
     };
   },
+  methods: {
+    inputHandler() {
+      this.$emit("contentText", this.valueText);
+    },
+  },
 };
 </script>
 <style lang="scss">

+ 9 - 2
src/views/rai_manage/cygxManage/lableManage.vue

@@ -30,7 +30,7 @@
           <span v-if="index == 0" class="divide">|</span>
         </div>
       </div>
-      <el-table border :data="tableList">
+      <el-table border :data="tableList" @sort-change="sortChangeHandle">
         <el-table-column align="center" key="name" prop="TagName" label="标签名称" width=""></el-table-column>
         <el-table-column align="center" key="series" prop="ArticleTypes" label="报告类型" width=""></el-table-column>
         <el-table-column align="center" key="type" prop="ActivityTypes" label="活动类型" width=""></el-table-column>
@@ -38,7 +38,7 @@
         <el-table-column align="center" key="subject" prop="SubjectNames" label="相关标的" width=""></el-table-column>
         <el-table-column align="center" key="tiem" prop="OnlineTime" label="上线时间" width="180"></el-table-column>
         <el-table-column align="center" key="remove" prop="OfflineTime" label="撤下时间" width="180" v-if="tableSelectActive == 0"></el-table-column>
-        <el-table-column align="center" key="pvuv" prop="Sort" label="pv/uv" width="90">
+        <el-table-column align="center" key="pvuv" prop="Sort" label="pv/uv" width="90" sortable="custom">
           <template slot-scope="{ row }">
             <div class="pv-uv-download">
               <span>{{ row.Pv }}/{{ row.Uv }}</span>
@@ -169,6 +169,7 @@ export default {
       dlgTitle: "添加",
       showRegularDlg: false,
       dataRegular: {},
+      sortType: "",
     };
   },
   computed: {},
@@ -187,6 +188,8 @@ export default {
         Status: this.tableSelectActive,
         PageSize: this.pageSize,
         CurrentIndex: this.page_no,
+        SortParam: "pv",
+        SortType: this.sortType,
       });
       if (res.Ret === 200) {
         this.total = res.Data.Paging.Totals;
@@ -401,6 +404,10 @@ export default {
         this.optionsSubject = [];
       }
     },
+    sortChangeHandle(column) {
+      this.sortType = column.order == "descending" ? "desc" : column.order == "ascending" ? "asc" : "";
+      this.getDataList();
+    },
   },
 };
 </script>

+ 56 - 43
src/views/rai_manage/reportManage/components/addHaveReport.vue

@@ -9,45 +9,19 @@
           <el-input style="width: 360px" clearable v-model="addOfEditForm.title" placeholder="请输入报告标题"></el-input>
         </el-form-item>
         <el-form-item prop="publishTime">
-          <el-date-picker
-            style="width: 360px"
-            v-model="addOfEditForm.publishTime"
-            type="date"
-            placeholder="请选择发布时间"
-            format="yyyy-MM-dd"
-            value-format="yyyy-MM-dd"
-          >
-          </el-date-picker>
+          <el-date-picker style="width: 360px" v-model="addOfEditForm.publishTime" type="date" placeholder="请选择发布时间" format="yyyy-MM-dd" value-format="yyyy-MM-dd"> </el-date-picker>
         </el-form-item>
         <el-form-item>
           <el-input style="width: 360px" clearable v-model="addOfEditForm.department" placeholder="请输入作者(选填)"></el-input>
         </el-form-item>
         <el-form-item prop="industry">
           <el-select placeholder="请选择行业" style="width: 360px" clearable v-model="addOfEditForm.industry" @change="industryChangeHandler">
-            <el-option
-              v-for="item in chartPermissionList"
-              :label="item.PermissionName"
-              :key="item.ChartPermissionId"
-              :value="item.ChartPermissionId"
-            />
+            <el-option v-for="item in chartPermissionList" :label="item.PermissionName" :key="item.ChartPermissionId" :value="item.ChartPermissionId" />
           </el-select>
         </el-form-item>
         <el-form-item prop="property">
-          <el-select
-            v-model="addOfEditForm.property"
-            multiple
-            placeholder="请选择关联产业(选填)"
-            @change="propertyChangeHandler"
-            clearable
-            filterable
-            style="width: 360px"
-          >
-            <el-option
-              :label="item.IndustryName"
-              :value="item.IndustrialManagementId"
-              v-for="item in selectedIndustryArr"
-              :key="item.IndustrialManagementId"
-            />
+          <el-select v-model="addOfEditForm.property" multiple placeholder="请选择关联产业(选填)" @change="propertyChangeHandler" clearable filterable style="width: 360px">
+            <el-option :label="item.IndustryName" :value="item.IndustrialManagementId" v-for="item in selectedIndustryArr" :key="item.IndustrialManagementId" />
           </el-select>
         </el-form-item>
         <el-form-item prop="subject">
@@ -72,16 +46,7 @@
         </div>
       </el-card>
     </el-form>
-    <el-dialog
-      v-dialogDrag
-      :close-on-click-modal="false"
-      :modal-append-to-body="false"
-      center
-      title="新建报告类型"
-      :visible.sync="addMatchTypeDlg"
-      :before-close="confirmMatchType"
-      width="500px"
-    >
+    <el-dialog v-dialogDrag :close-on-click-modal="false" :modal-append-to-body="false" center title="新建报告类型" :visible.sync="addMatchTypeDlg" :before-close="confirmMatchType" width="500px">
       <p style="margin-bottom: 10px">所属行业:{{ dlgTextRender }}</p>
       <el-form :model="addMatchTypeData" :rules="matchTypeRules" ref="addMatchTypeData">
         <el-form-item prop="type">
@@ -143,6 +108,7 @@ export default {
         type: [{ required: true, message: "请选择类型归属", trigger: "change" }],
       },
       dlgTextRender: "",
+      timeInterval: null,
     };
   },
   mixins: [RichTextMixins],
@@ -152,10 +118,50 @@ export default {
     if (this.$route.query.id) {
       // 编辑进来的
       this.getDetail();
+    } else {
+      this.dataInit();
     }
     this.chartPermission();
   },
   methods: {
+    // 报告的缓存处理数据
+    dataInit() {
+      if (sessionStorage.getItem("addHaveReportQY")) {
+        let data = JSON.parse(sessionStorage.getItem("addHaveReportQY"));
+        setTimeout(async () => {
+          this.addOfEditForm = {
+            regions: data.Detail.ColumnName,
+            content: data.Detail.Body,
+            title: data.Detail.Title,
+            synopsis: data.Detail.Abstract,
+            department: data.Detail.Department,
+            publishTime: data.Detail.PublishTime,
+            property: data.Detail.ListIndustrial,
+            subject: data.Detail.ListSubject,
+            industry: data.Detail.ChartPermissionId,
+            matchTypeName: data.Detail.MatchTypeId,
+          };
+          this.isShowStatus = data.Detail.Status == 0;
+          await this.industryChangeHandler();
+          await this.propertyChangeHandler();
+        }, 200);
+      }
+      this.timeInterval = setInterval(() => {
+        let params = {
+          PublishTime: this.addOfEditForm.publishTime,
+          ColumnName: this.addOfEditForm.regions,
+          Title: this.addOfEditForm.title,
+          Abstract: this.addOfEditForm.synopsis,
+          Department: this.addOfEditForm.department,
+          Body: this.addOfEditForm.content,
+          IndustrialManagementIds: this.addOfEditForm.property,
+          IndustrialSubjectIds: this.addOfEditForm.subject,
+          ChartPermissionId: this.addOfEditForm.industry,
+          MatchTypeId: this.addOfEditForm.matchTypeName,
+        };
+        sessionStorage.setItem("addHaveReportQY", JSON.stringify(params));
+      }, 120000);
+    },
     // 产业的change事件
     propertyChangeHandler(val) {
       if (this.addOfEditForm.property && this.addOfEditForm.property.length) {
@@ -177,9 +183,7 @@ export default {
         }
         this.getIndustryList();
         this.getMatchTypeNameList();
-        this.chartPermissionList.forEach(
-          (item) => item.ChartPermissionId === this.addOfEditForm.industry && (this.dlgTextRender = item.PermissionName)
-        );
+        this.chartPermissionList.forEach((item) => item.ChartPermissionId === this.addOfEditForm.industry && (this.dlgTextRender = item.PermissionName));
       } else {
         this.industryDataInit();
       }
@@ -276,6 +280,8 @@ export default {
           const res = await raiInterface.internalPreserveAndPublish(params);
           if (res.Ret === 200) {
             this.$message.success("操作成功!");
+            clearInterval(this.timeInterval);
+            sessionStorage.removeItem("addHaveReportQY");
             this.$refs.addOfEditForm.resetFields();
             this.$router.push("/internalTesting");
           }
@@ -284,6 +290,8 @@ export default {
     },
     //表单取消事件
     cancelBtn() {
+      clearInterval(this.timeInterval);
+      sessionStorage.removeItem("addHaveReportQY");
       this.$refs.addOfEditForm.resetFields();
       this.$router.push("/internalTesting");
     },
@@ -317,6 +325,11 @@ export default {
       };
     },
   },
+  // 路由离开了 清除定时器
+  beforeRouteLeave(to, from, next) {
+    clearInterval(this.timeInterval);
+    next();
+  },
 };
 </script>
 <style scoped lang="scss">

+ 79 - 0
src/views/rai_manage/reportManage/components/collectFansDlg.vue

@@ -0,0 +1,79 @@
+<template>
+  <div class="container">
+    <!-- 选择图片的弹框 -->
+    <el-dialog :title="collectFansDlgText" :visible.sync="iscollectFansDlgShow" width="50%" :before-close="handleClose" v-dialogDrag :close-on-click-modal="false" :modal-append-to-body="false" center>
+      <div>
+        <el-table :data="tableData" style="width: 100%; margin-bottom: 20px" border>
+          <el-table-column prop="RealName" align="center" label="姓名"></el-table-column>
+          <el-table-column prop="CompanyName" align="center" label="公司名称"></el-table-column>
+          <el-table-column prop="SellerName" align="center" label="所属销售"></el-table-column>
+          <el-table-column width="160" prop="CreateTime" align="center" :label="this.collectFansDlgText == '收藏详情' ? '收藏时间' : '关注时间'"></el-table-column>
+        </el-table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="handleClose">关闭</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { raiInterface } from "@/api/api.js";
+
+export default {
+  name: "",
+  components: {},
+  props: {
+    iscollectFansDlgShow: {
+      type: Boolean,
+      default: false,
+    },
+    collectFansDlgText: {
+      type: String,
+      default: "",
+    },
+    collectFansDlgItem: {
+      type: Object,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      tableData: [],
+    };
+  },
+  computed: {},
+  watch: {
+    iscollectFansDlgShow: {
+      handler(newVal) {
+        newVal && this.getTableList();
+      },
+    },
+  },
+  created() {},
+  mounted() {},
+  methods: {
+    // 关闭弹框
+    handleClose() {
+      this.$emit("update:iscollectFansDlgShow", false);
+      this.$emit("update:collectFansDlgText", "");
+      this.$emit("update:collectFansDlgItem", {});
+    },
+    // 获取表格数据
+    async getTableList() {
+      const res =
+        this.collectFansDlgText == "收藏详情"
+          ? await raiInterface.getYanxuanSpecialCollect({
+              SpecialId: this.collectFansDlgItem.Id,
+            })
+          : await raiInterface.getYanxuanSpecialFans({
+              SpecialAuthorId: this.collectFansDlgItem.Id,
+            });
+      if (res.Ret === 200) {
+        this.tableData = res.Data.List || [];
+      }
+    },
+  },
+};
+</script>
+<style scoped lang="scss"></style>

+ 1 - 1
src/views/rai_manage/reportManage/components/specialDlg.vue

@@ -97,7 +97,7 @@ export default {
       if (res.Ret === 200) {
         this.handleCloseAuthor();
         this.$message.success("添加成功!");
-        this.$parent.getAuthorList();
+        this.$parent.getyanxuanReportSpecial();
       }
     },
     /* **************************************************** */

+ 183 - 0
src/views/rai_manage/reportManage/components/yanXuanLable.js

@@ -0,0 +1,183 @@
+export const TopLableList = [
+  {
+    name: "文章管理",
+    value: 1,
+  },
+  {
+    name: "作者管理",
+    value: 2,
+  },
+];
+export const ReportStutsList = [
+  {
+    name: "待审核",
+    value: 1,
+  },
+  {
+    name: "已发布",
+    value: 2,
+  },
+  {
+    name: "驳回记录",
+    value: 3,
+  },
+];
+
+export const TableColums = (type) => {
+  return type === 1
+    ? [
+        {
+          label: "文章标题",
+          key: "Title",
+        },
+        {
+          label: "文章类型",
+          key: "Type",
+          widthsty: 80,
+        },
+        {
+          label: "专栏名称",
+          key: "SpecialName",
+        },
+        {
+          label: "作者昵称",
+          key: "NickName",
+        },
+        {
+          label: "提交审核时间",
+          key: "PublishTime",
+          widthsty: 160,
+        },
+      ]
+    : type === 2
+    ? [
+        {
+          label: "文章标题",
+          key: "Title",
+        },
+        {
+          label: "文章类型",
+          key: "Type",
+          widthsty: 80,
+        },
+        {
+          label: "专栏名称",
+          key: "SpecialName",
+        },
+        {
+          label: "作者昵称",
+          key: "NickName",
+        },
+        {
+          label: "发布(审核通过)时间",
+          key: "PublishTime",
+          widthsty: 200,
+        },
+        {
+          label: "审核人",
+          key: "AdminName",
+          widthsty: 100,
+        },
+        {
+          label: "PV/UV",
+          key: "pv",
+          widthsty: 100,
+        },
+        {
+          label: "收藏数",
+          key: "ArticleCollectNum",
+          widthsty: 100,
+        },
+      ]
+    : [
+        {
+          label: "文章标题",
+          key: "Title",
+        },
+        {
+          label: "文章类型",
+          key: "Type",
+          widthsty: 80,
+        },
+        {
+          label: "文章ID",
+          key: "YanxuanSpecialId",
+          widthsty: 100,
+        },
+        {
+          label: "专栏名称",
+          key: "SpecialName",
+        },
+        {
+          label: "作者昵称",
+          key: "NickName",
+        },
+        {
+          label: "审核时间",
+          key: "CreateTime",
+          widthsty: 160,
+        },
+        {
+          label: "审核人",
+          key: "AdminName",
+          widthsty: 100,
+        },
+      ];
+};
+export const AuthorTableColums = [
+  {
+    label: "专栏名称",
+    key: "SpecialName",
+    // widthsty: 200,
+  },
+  {
+    label: "作者昵称",
+    key: "NickName",
+    widthsty: 90,
+  },
+  {
+    label: "姓名",
+    key: "RealName",
+    widthsty: 90,
+  },
+  {
+    label: "手机号",
+    key: "Mobile",
+    widthsty: 130,
+  },
+  {
+    label: "公司名称",
+    key: "CompanyName",
+    widthsty: 200,
+  },
+  {
+    label: "开通时间",
+    key: "CreateTime",
+    widthsty: 170,
+  },
+  {
+    label: "最近发布时间",
+    key: "ArticlePublishTime",
+    widthsty: 170,
+  },
+  {
+    label: "已发布文章",
+    key: "ArticleNum",
+    widthsty: 130,
+  },
+  {
+    label: "总PV/UV",
+    key: "pv",
+    widthsty: 160,
+  },
+  {
+    label: "被收藏",
+    key: "ArticleCollectNum",
+    widthsty: 80,
+  },
+  {
+    label: "粉丝",
+    key: "FansNum",
+    widthsty: 80,
+  },
+];

+ 355 - 297
src/views/rai_manage/reportManage/yanXuanSpecial.vue

@@ -1,147 +1,296 @@
 <template>
   <div class="container yanxuan-special_container">
-    <div class="author-content">
-      <div class="top">
-        <div>专栏作者</div>
-        <el-button type="primary" @click="addAuthorDlgVisible = true">新建作者</el-button>
-      </div>
-      <div class="author-ul">
-        <div class="author-li" v-for="item in authorInfoData" :key="item.Id">
-          <div class="avatar">
-            <img :src="item.HeadImg" alt="" />
-          </div>
-          <div class="info-content">
-            <p class="info-name">{{ item.SpecialName }}</p>
-            <p>昵称:{{ item.NickName }}</p>
-            <p>{{ item.RealName }}-{{ item.Mobile }}</p>
-            <p>{{ item.CompanyName }}</p>
-          </div>
-          <div class="switch-box">
-            <el-switch style="display: block" @change="switchAuthorChange(item)" v-model="item.Status" :active-value="1" :inactive-value="2" active-color="#13ce66" inactive-color="#ff4949">
-            </el-switch>
-          </div>
+    <el-card style="margin-bottom: 20px">
+      <span @click="tlableClickHandler(item)" :class="['top-table-item', item.value == topLableActive && 'top-table-item-active']" v-for="item in topLableList" :key="item.value">{{ item.name }}</span>
+    </el-card>
+    <el-card>
+      <template v-if="topLableActive == 1">
+        <div class="report-stuts-content">
+          <span
+            @click="reportStatusClickHandler(item)"
+            :class="['top-table-item', 'report-stuts-list', item.value == reportStatusActive && 'top-table-item-active']"
+            v-for="item in reportStutsList"
+            :key="item.value"
+            >{{ item.name }}</span
+          >
         </div>
-      </div>
-    </div>
-    <div class="examine-content">
-      <p>待审核内容</p>
-      <template v-if="specialListData.length > 0">
-        <div class="content-box-examine" v-for="item in specialListData" :key="item.Id">
-          <div class="info-box" style="margin-bottom: 20px">
-            <div class="avatar">
-              <img :src="item.HeadImg" alt="" />
-            </div>
-            <div class="info-content">
-              <p class="info-name">{{ item.NickName || item.RealName }}</p>
-              <p>{{ item.PublishTime }}</p>
-            </div>
-          </div>
-          <div class="content-detial" v-html="item.Content"></div>
-          <div class="look-all-txt" v-if="item.ContentHasImg || item.isShowBtn" @click="lookAllDetails(item)">查看全文</div>
-          <div class="file-box" v-for="(key, indexs) in item.Docs" :key="indexs" @click="handleOperation(key)">
-            <img :src="key.DocIcon" alt="" />
-            {{ key.DocName }}.{{ key.DocSuffix }}
-          </div>
-          <div class="img-box">
-            <template v-if="item.ImgUrl">
-              <!-- <el-image style="width: 112px; height: 112px" fit="fill" v-for="(key, index) in item.ImgUrl.split(',')" :key="index" :src="key" :preview-src-list="item.ImgUrl.split(',')"> </el-image> -->
-              <img style="width: 112px; height: 112px" v-for="(key, index) in item.ImgUrl.split(',')" :key="index" :src="key" @click="showPreviewHandles(key)" />
-            </template>
-          </div>
-          <div>
-            <template v-if="item.Tags">
-              <div class="lable-li" v-for="(key, index) in item.Tags.split(',')" :key="index">{{ key }}</div>
-            </template>
-          </div>
-          <div class="bottom-button">
-            <div @click="submitRejectDlgHandler(item)">驳回</div>
-            <div @click="openMessage(item)">通过</div>
-          </div>
+        <div style="margin-bottom: 20px" v-if="reportStatusActive == 2">
+          <el-select placeholder="请选择文章类型" clearable v-model="reportStatus" @change="conditionChange">
+            <el-option
+              v-for="item in [
+                { label: '笔记', value: 1 },
+                { label: '观点', value: 2 },
+              ]"
+              :label="item.label"
+              :key="item.value"
+              :value="item.value"
+            />
+          </el-select>
+          <date-picker style="margin: 0 20px; width: 240px" v-model="issueTime" type="date" range placeholder="发布时间" value-type="format" @change="conditionChange"> </date-picker>
+          <el-input @input="reportTitleHandle" v-model="reportTitle" placeholder="请输入文章标题" clearable style="display: inline-block; width: 240px">
+            <i slot="prefix" class="el-input__icon el-icon-search"></i>
+          </el-input>
         </div>
       </template>
-      <div class="no-data" v-else>
-        <div style="text-align: center">
-          <img src="~@/assets/img/data_m/table_no.png" alt="" style="display: block; width: 135px; height: 112px; margin: 0 auto" />
-          <span>暂无数据</span>
+      <div v-else style="margin-bottom: 20px; display: flex; justify-content: space-between">
+        <div>
+          <el-select style="margin-right: 20px" placeholder="作者状态" clearable v-model="authorStatus" @change="conditionChange">
+            <el-option
+              v-for="item in [
+                { label: '启用', value: 1 },
+                { label: '禁用', value: 2 },
+              ]"
+              :label="item.label"
+              :key="item.value"
+              :value="item.value"
+            />
+          </el-select>
+          <el-input @input="authorColumnValueHandler" v-model="authorColumnValue" placeholder="请输入专栏名称" clearable style="display: inline-block; width: 240px">
+            <i slot="prefix" class="el-input__icon el-icon-search"></i>
+          </el-input>
         </div>
+        <div>
+          <el-button type="primary" @click="addAuthorDlgVisible = true">新建作者</el-button>
+        </div>
+      </div>
+      <div>
+        <el-table :data="tableData" border @sort-change="sortChangeHandle">
+          <template v-if="topLableActive == 1">
+            <el-table-column
+              v-for="item in reportTableColums"
+              :width="item.widthsty"
+              :key="item.key"
+              :prop="item.key"
+              :label="item.label"
+              align="center"
+              :sortable="item.label == 'PV/UV' ? 'custom' : false"
+            >
+              <template slot-scope="{ row }">
+                <span v-if="item.label != 'PV/UV'" @click="handleRowClick(row, item.key)" :style="handleRowStyle(item.key)">{{ handleRowContent(row, item.key) }}</span>
+                <div class="pv-uv-download" v-else>
+                  <span>{{ row.Pv }} / {{ row.Uv }}</span>
+                  <a :href="exportPvUv(row.Id)" download>
+                    <img src="~@/assets/img/rai_m/pvuv_download.png" alt="" />
+                  </a>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" v-if="reportStatusActive != 2">
+              <template slot-scope="{ row }">
+                <span class="editsty" v-if="reportStatusActive == 3" @click="reasonRejection(row)">驳回理由</span>
+                <span class="editsty" v-if="reportStatusActive == 1" @click="toExamineHandler(row)">审核</span>
+              </template>
+            </el-table-column>
+          </template>
+          <template v-else>
+            <el-table-column v-for="item in authorTableColums" :width="item.widthsty" :key="item.key" :prop="item.key" :label="item.label" align="center" :sortable="isShowSortable(item)">
+              <template slot-scope="{ row }">
+                <span v-if="item.label != '总PV/UV'" @click="handleRowClick(row, item.key)" :style="handleRowStyle(item.key)">{{ handleRowContent(row, item.key) }}</span>
+                <span v-else>{{ row.Pv }} / {{ row.Uv }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="状态" align="center" width="200">
+              <template slot-scope="{ row }">
+                <el-switch
+                  active-color="#13ce66"
+                  inactive-color="#ff4949"
+                  @change="switchChangeHandler(row)"
+                  v-model="row.Status"
+                  :active-value="1"
+                  :inactive-value="2"
+                  active-text="已启用"
+                  inactive-text="已禁用"
+                ></el-switch>
+              </template>
+            </el-table-column>
+          </template>
+        </el-table>
+        <!-- 分页 -->
+        <el-col :span="24" class="toolbar">
+          <m-page :total="total" :page_no="page_no" :pageSize="10" @handleCurrentChange="handleCurrentChange" />
+        </el-col>
       </div>
-    </div>
+    </el-card>
+    <collect-fans-dlg :iscollectFansDlgShow.sync="iscollectFansDlgShow" :collectFansDlgText.sync="collectFansDlgText" :collectFansDlgItem.sync="collectFansDlgItem" />
     <special-dlg :addAuthorDlgVisible.sync="addAuthorDlgVisible" :submitRejectDlgVisible.sync="submitRejectDlgVisible" :submitRejectId="submitRejectId" />
-    <el-image-viewer v-if="showPreview" :urlList="previewImages" :on-close="closeViewer" :zIndex="99999"></el-image-viewer>
   </div>
 </template>
 
 <script>
-import ElImageViewer from "element-ui/packages/image/src/image-viewer";
-import SpecialDlg from "./components/specialDlg.vue";
+import { TopLableList, ReportStutsList, TableColums, AuthorTableColums } from "./components/yanXuanLable";
 import { raiInterface } from "@/api/api.js";
-import { async } from "@antv/x6/lib/registry/marker/async";
+import mPage from "@/components/mPage.vue";
+import CollectFansDlg from "./components/collectFansDlg.vue";
+import SpecialDlg from "./components/specialDlg.vue";
+
 export default {
   name: "",
-  components: { SpecialDlg, ElImageViewer },
+  components: { mPage, CollectFansDlg, SpecialDlg },
   props: {},
   data() {
     return {
+      page_no: 1,
+      total: 0, //条数
+      PageSize: 10, //每页显示几条
+      topLableActive: 1,
+      reportStatusActive: 1,
+      tableData: [],
+      reportStatus: "", //文章类型
+      authorStatus: "", // 作者状态
+      reportTitle: "", //文章标题
+      issueTime: [], // 文章发布时间
+      authorColumnValue: "", // 专栏名称
+      iscollectFansDlgShow: false,
+      collectFansDlgText: "",
+      collectFansDlgItem: {},
       addAuthorDlgVisible: false,
-      submitRejectDlgVisible: false, // 驳回的显示
-      submitRejectId: 0, // 驳回的ID
-      authorInfoData: [], // 作者信息列表
-      specialListData: [], // 审核列表
-      showPreview: false, //
-      previewImages: [],
+      topLableList: [],
+      sortType: "",
+      sortParam: "",
     };
   },
-  watch: {},
-  created() {},
+  computed: {
+    // 头部lable
+
+    // 文章的状态
+    reportStutsList() {
+      return ReportStutsList;
+    },
+    reportTableColums() {
+      return TableColums(this.reportStatusActive);
+    },
+    authorTableColums() {
+      return AuthorTableColums;
+    },
+  },
   mounted() {
-    this.getAuthorList();
-    this.getSpecialList();
-    this.$nextTick(() => {});
-    // let rowNum = Math.round($(".content-detial").height() / parseFloat($(".content-detial").css("line-height")));
+    this.getYanxuanShowButton();
+    this.getyanxuanReportSpecial();
   },
   methods: {
-    showPreviewHandles(item) {
-      console.log(123);
-      this.showPreview = true;
-      this.previewImages = [item];
+    // 点击了头部的tlble
+    tlableClickHandler(item) {
+      this.topLableActive = item.value;
+      this.page_no = 1;
+      this.getyanxuanReportSpecial();
     },
-    closeViewer() {
-      this.showPreview = false;
-      document.querySelector("body").classList.remove("el-popup-imageView--hidden");
+    // 文章的状态点击
+    reportStatusClickHandler(item) {
+      this.reportStatusActive = item.value;
+      this.page_no = 1;
+      this.getyanxuanReportSpecial();
     },
-    // 审核通过的确认按钮
-    openMessage(item) {
-      this.$confirm("确定通过此内容在小程序展示吗?", "审核通过", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning",
-      })
-        .then(async () => {
-          const res = await raiInterface.yanxuan_specialEnable({
-            Id: item.Id,
-            Status: 1,
-          });
-          if (res.Ret === 200) {
-            this.$message.success("审核成功!");
-            this.getSpecialList();
-          }
-        })
-        .catch(() => {
-          this.$message({
-            type: "info",
-            message: "已取消",
-          });
-        });
+    /* 表格行的样式 */
+    handleRowStyle(key) {
+      if (key == "Title" && this.reportStatusActive == 2) {
+        return "color: #409eff; cursor: pointer";
+      } else if ((key == "SpecialName" && (this.reportStatusActive == 2 || this.reportStatusActive == 3)) || (key == "SpecialName" && this.topLableActive == 2)) {
+        return "color: #409eff; cursor: pointer";
+      } else if (key == "ArticleCollectNum" && this.topLableActive == 1) {
+        return "color: #409eff; cursor: pointer";
+      } else {
+        const style = {
+          FansNum: "color: #409eff; cursor: pointer",
+        };
+        return style[key] ? style[key] : "";
+      }
     },
-    // 获取作者列表
-    async getAuthorList() {
-      const res = await raiInterface.yanxuan_specialAuthorList();
+    /* 表格行的点击事件 */
+    handleRowClick(row, key) {
+      if (key === "Title" && this.reportStatusActive == 2) {
+        let href = `${process.env.CYGX_WEB}/column/detail/${row.Id}`;
+        window.open(href, "_blank");
+      } else if (key === "SpecialName" && (this.reportStatusActive == 2 || this.reportStatusActive == 3 || this.topLableActive == 2)) {
+        let href = `${process.env.CYGX_WEB}/column/view/${row.SpecialAuthorId}`;
+        window.open(href, "_blank");
+      } else if ((key === "ArticleCollectNum" && this.topLableActive == 1) || key === "FansNum") {
+        // 收藏的数量
+        this.iscollectFansDlgShow = true;
+        this.collectFansDlgText = key === "ArticleCollectNum" ? "收藏详情" : "粉丝详情";
+        this.collectFansDlgItem = row;
+      }
+    },
+    /* 表格行的数据处理 */
+    handleRowContent(row, key) {
+      if (key == "Type") {
+        return row[key] == 1 ? "笔记" : "观点";
+      } else if (key == "Source") {
+        return row[key] == 1 ? "纪要" : row[key] == 2 ? "图表" : row[key] == 3 ? "纪要/图表" : row[key] == 4 ? "产业资源包" : row[key] == 5 ? "报告" : "活动";
+      } else if (key == "ActivityType") {
+        return row[key] == 1 ? "线上" : `线下(${row["City"]})`;
+      } else if (key == "RegisterPlatform") {
+        return row[key] == 1 ? "小程序" : row[key] == 2 ? "网页版" : row[key] == 3 ? "策略平台" : "";
+      } else {
+        return row[key];
+      }
+    },
+    // 是否显示
+    isShowSortable(item) {
+      return item.label == "总PV/UV" || item.label == "开通时间" || item.label == "已发布文章" ? "custom" : false;
+    },
+    // 排序事件
+    sortChangeHandle(params) {
+      this.page_no = 1;
+      this.sortType = params.order === "descending" ? "desc" : "asc";
+      this.sortParam = params.prop;
+      this.getyanxuanReportSpecial();
+    },
+    // 选择的change事件
+    conditionChange() {
+      this.page_no = 1;
+      this.getyanxuanReportSpecial();
+    },
+    // 获取数据
+    async getyanxuanReportSpecial() {
+      let params = {
+        CurrentIndex: this.page_no,
+        PageSize: this.PageSize,
+        Status: this.topLableActive == 1 ? this.reportStatusActive : this.authorStatus,
+        KeyWord: this.topLableActive == 1 ? this.reportTitle : this.authorColumnValue,
+        Type: this.reportStatus,
+        StartDate: this.issueTime[0],
+        EndDate: this.issueTime[1],
+        SortType: this.sortType,
+        SortParam: this.sortParam,
+      };
+      const res =
+        this.topLableActive == 1 && (this.reportStatusActive == 1 || this.reportStatusActive == 2)
+          ? await raiInterface.yanxuanReportSpecial(params)
+          : this.topLableActive == 1 && this.reportStatusActive == 3
+          ? await raiInterface.yanxuanApprovalLogList(params)
+          : this.topLableActive == 2
+          ? await raiInterface.getYanxuanSpecialAuthor(params)
+          : "";
       if (res.Ret === 200) {
-        this.authorInfoData = res.Data || [];
+        this.tableData = res.Data.List || [];
+        this.total = res.Data.Paging.Totals;
       }
     },
-    // 作者的关闭或者打开
-    async switchAuthorChange(item) {
+    // 审核
+    toExamineHandler(item) {
+      let href = `${process.env.CYGX_WEB}/column/check/${item.Id}`;
+      window.open(href, "_blank");
+    },
+    // 下载pv/uv 地址
+    exportPvUv(id) {
+      const url = process.env.API_ROOT + "/cygx/yanxuan_special/list_pv?SpecialId=" + id + "&" + localStorage.getItem("auth") || "";
+      return url;
+    },
+    // 分页
+    handleCurrentChange(page) {
+      this.page_no = page;
+      this.getyanxuanReportSpecial();
+    },
+    // 驳回理由
+    reasonRejection(item) {
+      this.$alert(item.Reason, "驳回理由", {
+        confirmButtonText: "确定",
+        customClass: "yanxuan-special-msg-box",
+        callback: (action) => {},
+      });
+    },
+    // 作者的禁用启用
+    async switchChangeHandler(item) {
       const res = await raiInterface.yanxuan_specialAuthorEnable({
         UserId: item.UserId,
         Status: item.Status,
@@ -150,207 +299,116 @@ export default {
         this.$message.success("操作成功!");
       }
     },
-    // 审核列表
-    async getSpecialList() {
-      const res = await raiInterface.yanxuan_specialList();
-      if (res.Ret === 200) {
-        this.specialListData = res.Data || [];
-
-        this.$nextTick(() => {
-          this.specialListData.forEach((item, index) => {
-            let h = document.getElementsByClassName("content-detial")[index].clientHeight;
-            this.$set(item, "isShowBtn", h >= 134 ? true : false);
-          });
-        });
-      }
+    authorColumnValueHandler() {
+      this.reportStatus = ""; //文章类型
+      this.authorStatus = ""; // 作者状态
+      this.reportTitle = ""; //文章标题
+      this.issueTime = []; // 文章发布时间
+      this.page_no = 1;
+      this.getyanxuanReportSpecial();
     },
-    // 驳回的弹框显示
-    submitRejectDlgHandler(item) {
-      this.submitRejectId = item.Id;
-      this.submitRejectDlgVisible = true;
+    reportTitleHandle() {
+      this.reportStatus = ""; //文章类型
+      this.authorStatus = ""; // 作者状态
+      this.issueTime = []; // 文章发布时间
+      this.authorColumnValue = "";
+      this.page_no = 1;
+      this.getyanxuanReportSpecial();
     },
-    handleOperation: _.debounce(function (item) {
-      const url = item.DocUrl;
-      if (!url) {
-        this.$message.warning("文件错误");
-        return;
-      }
-      const reg = /\.(pdf)$/;
-      // pdf
-      if (reg.test(url)) {
-        window.open(url, "_blank");
-      } else {
-        window.open("https://view.officeapps.live.com/op/view.aspx?src=" + url, "_blank");
+    // 隐藏作者按钮
+    async getYanxuanShowButton() {
+      const res = await raiInterface.getYanxuanShowButton();
+      if (res.Ret === 200) {
+        let { IsShowSpecialAuthor } = res.Data;
+        if (IsShowSpecialAuthor) {
+          this.topLableList = TopLableList;
+        } else {
+          this.topLableList = [TopLableList[0]];
+        }
       }
-    }, 200),
-    lookAllDetails(item) {
-      let url =
-        process.env.NODE_ENV === "production"
-          ? `https://web.hzinsights.com/column/detail/${item.Id}`
-          : process.env.NODE_ENV === `test`
-          ? `https://clpttest.hzinsights.com/column/detail/${item.Id}`
-          : `https://clpttest.hzinsights.com/column/detail/${item.Id}`;
-      window.open(url, "_blank");
     },
   },
 };
 </script>
-<style lang="scss">
-div {
-  box-sizing: border-box;
-}
+<style scoped lang="scss">
 .yanxuan-special_container {
-  display: flex;
-  justify-content: space-between;
-  .author-content {
-    width: 400px;
-    height: calc(100vh - 118px);
+  .top-table-item {
+    display: inline-block;
+    margin-right: 30px;
+    text-align: center;
+    width: 120px;
+    height: 40px;
+    line-height: 40px;
     border-radius: 4px;
-    background-color: #fff;
-    padding: 20px;
-    box-sizing: border-box;
-    flex-shrink: 0;
-    .top {
-      display: flex;
-      align-items: center;
-      justify-content: space-between;
-    }
-    .author-ul {
-      padding-bottom: 10px;
-      height: 100%;
-      overflow: hidden;
-      overflow-y: auto;
-      .author-li {
-        flex: 1;
-        padding: 20px;
-        display: flex;
-        justify-content: space-between;
-        border-bottom: 1px solid #dcdfe6;
-        margin: 10px 0;
-        .switch-box {
-          width: 30px;
-          flex-shrink: 0;
-        }
+    color: #409eff;
+    background-color: #ecf5ff;
+    border: 1px solid #b3d8ff;
+    cursor: pointer;
+  }
+  .report-stuts-content {
+    margin-bottom: 20px;
+    span:nth-child(2) {
+      position: relative;
+      margin: 0 60px 0 30px;
+      &::before {
+        content: "";
+        position: absolute;
+        left: -30px;
+        top: 10px;
+        display: inline-block;
+        width: 2px;
+        height: 20px;
+        background: #000;
+      }
+      &::after {
+        content: "";
+        position: absolute;
+        right: -30px;
+        top: 10px;
+        display: inline-block;
+        width: 2px;
+        height: 20px;
+        background: #000;
       }
     }
   }
-  .info-content {
-    flex: 1;
-    padding-left: 16px;
-    color: #999999;
-    p {
-      margin: 5px 0;
-    }
+  .report-stuts-list {
+    color: #000;
+    background-color: rgba(255, 255, 255, 0.5);
+    border: none;
   }
-  .avatar {
-    width: 48px;
-    height: 48px;
-    border-radius: 50%;
-    overflow: hidden;
-    background: #d9d9d9;
-    flex-shrink: 0;
+  .top-table-item-active {
+    color: #fff;
+    background-color: #409eff;
+    border: none;
+    opacity: 1;
+  }
+  .pv-uv-download {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
     img {
-      width: 48px;
-      height: 48px;
+      width: 14px;
+      height: 14px;
+      margin-left: 10px;
     }
   }
-  .info-name {
-    font-size: 16px;
-    color: #333;
-    font-weight: 500;
-  }
-  .examine-content {
-    margin-left: 20px;
-    padding: 20px;
-    flex: 1;
-    background: #fff;
-    flex-direction: 0;
-    overflow: hidden;
-    .no-data {
-      width: 100%;
-      height: 100%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-    }
-    .content-box-examine {
-      padding: 30px 0;
-      border-bottom: 1px solid #dcdfe6;
-    }
-    .info-box {
-      display: flex;
-    }
-    .content-detial {
-      overflow: hidden;
-      text-overflow: ellipsis;
-      display: -webkit-box;
-      -webkit-box-orient: vertical;
-      -webkit-line-clamp: 8;
-      img {
-        width: 100%;
-        max-height: 300px;
-      }
-    }
-    .look-all-txt {
-      color: #409eff;
-      font-size: 16px;
-      margin-top: 20px;
-      cursor: pointer;
-    }
-    .file-box {
-      display: flex;
-      align-items: center;
-      margin-top: 20px;
-      height: 64px;
-      cursor: pointer;
-      img {
-        width: 27px;
-        height: 27px;
-        margin-right: 15px;
-      }
-    }
-    .img-box {
-      margin: 20px 0;
-      height: 112px;
-      img {
-        object-fit: fill !important;
-        cursor: pointer;
-        margin-right: 20px;
-      }
-    }
-    .lable-li {
-      display: inline-block;
-      padding: 4px 20px;
-      height: 28px;
-      border-radius: 48px;
-      margin: 0 15px 15px 0;
-      border: 1px solid #409eff;
-      background-color: #eaf3fe;
-      color: #409eff;
-    }
-    .bottom-button {
-      margin: 50px;
-      display: flex;
-      justify-content: center;
-      color: #fff;
-      div {
-        cursor: pointer;
-        width: 120px;
-        height: 40px;
-        padding: 10px 46px 10px 46px;
-        border-radius: 4px;
-        background: #c54322;
-      }
-      div:nth-child(2) {
-        margin-left: 20px;
-        background: #67c23a;
-      }
+}
+</style>
+<style lang="scss">
+.yanxuan-special-msg-box {
+  border: none;
+  .el-message-box__header {
+    background: #3385ff;
+    .el-message-box__title,
+    .el-message-box__close {
+      color: #fff !important;
     }
   }
-}
-/deep/.el-image {
-  img {
-    object-fit: fill !important;
+  .el-message-box__btns {
+    text-align: center;
+    margin-top: 20px;
   }
 }
 </style>

+ 356 - 0
src/views/rai_manage/reportManage/yanxuan.vue

@@ -0,0 +1,356 @@
+<template>
+  <div class="container yanxuan-special_container">
+    <div class="author-content">
+      <div class="top">
+        <div>专栏作者</div>
+        <el-button type="primary" @click="addAuthorDlgVisible = true">新建作者</el-button>
+      </div>
+      <div class="author-ul">
+        <div class="author-li" v-for="item in authorInfoData" :key="item.Id">
+          <div class="avatar">
+            <img :src="item.HeadImg" alt="" />
+          </div>
+          <div class="info-content">
+            <p class="info-name">{{ item.SpecialName }}</p>
+            <p>昵称:{{ item.NickName }}</p>
+            <p>{{ item.RealName }}-{{ item.Mobile }}</p>
+            <p>{{ item.CompanyName }}</p>
+          </div>
+          <div class="switch-box">
+            <el-switch style="display: block" @change="switchAuthorChange(item)" v-model="item.Status" :active-value="1" :inactive-value="2" active-color="#13ce66" inactive-color="#ff4949">
+            </el-switch>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="examine-content">
+      <p>待审核内容</p>
+      <template v-if="specialListData.length > 0">
+        <div class="content-box-examine" v-for="item in specialListData" :key="item.Id">
+          <div class="info-box" style="margin-bottom: 20px">
+            <div class="avatar">
+              <img :src="item.HeadImg" alt="" />
+            </div>
+            <div class="info-content">
+              <p class="info-name">{{ item.NickName || item.RealName }}</p>
+              <p>{{ item.PublishTime }}</p>
+            </div>
+          </div>
+          <div class="content-detial" v-html="item.Content"></div>
+          <div class="look-all-txt" v-if="item.ContentHasImg || item.isShowBtn" @click="lookAllDetails(item)">查看全文</div>
+          <div class="file-box" v-for="(key, indexs) in item.Docs" :key="indexs" @click="handleOperation(key)">
+            <img :src="key.DocIcon" alt="" />
+            {{ key.DocName }}.{{ key.DocSuffix }}
+          </div>
+          <div class="img-box">
+            <template v-if="item.ImgUrl">
+              <!-- <el-image style="width: 112px; height: 112px" fit="fill" v-for="(key, index) in item.ImgUrl.split(',')" :key="index" :src="key" :preview-src-list="item.ImgUrl.split(',')"> </el-image> -->
+              <img style="width: 112px; height: 112px" v-for="(key, index) in item.ImgUrl.split(',')" :key="index" :src="key" @click="showPreviewHandles(key)" />
+            </template>
+          </div>
+          <div>
+            <template v-if="item.Tags">
+              <div class="lable-li" v-for="(key, index) in item.Tags.split(',')" :key="index">{{ key }}</div>
+            </template>
+          </div>
+          <div class="bottom-button">
+            <div @click="submitRejectDlgHandler(item)">驳回</div>
+            <div @click="openMessage(item)">通过</div>
+          </div>
+        </div>
+      </template>
+      <div class="no-data" v-else>
+        <div style="text-align: center">
+          <img src="~@/assets/img/data_m/table_no.png" alt="" style="display: block; width: 135px; height: 112px; margin: 0 auto" />
+          <span>暂无数据</span>
+        </div>
+      </div>
+    </div>
+    <special-dlg :addAuthorDlgVisible.sync="addAuthorDlgVisible" :submitRejectDlgVisible.sync="submitRejectDlgVisible" :submitRejectId="submitRejectId" />
+    <el-image-viewer v-if="showPreview" :urlList="previewImages" :on-close="closeViewer" :zIndex="99999"></el-image-viewer>
+  </div>
+</template>
+
+<script>
+import ElImageViewer from "element-ui/packages/image/src/image-viewer";
+import SpecialDlg from "./components/specialDlg.vue";
+import { raiInterface } from "@/api/api.js";
+import { async } from "@antv/x6/lib/registry/marker/async";
+export default {
+  name: "",
+  components: { SpecialDlg, ElImageViewer },
+  props: {},
+  data() {
+    return {
+      addAuthorDlgVisible: false,
+      submitRejectDlgVisible: false, // 驳回的显示
+      submitRejectId: 0, // 驳回的ID
+      authorInfoData: [], // 作者信息列表
+      specialListData: [], // 审核列表
+      showPreview: false, //
+      previewImages: [],
+    };
+  },
+  watch: {},
+  created() {},
+  mounted() {
+    this.getAuthorList();
+    this.getSpecialList();
+    this.$nextTick(() => {});
+    // let rowNum = Math.round($(".content-detial").height() / parseFloat($(".content-detial").css("line-height")));
+  },
+  methods: {
+    showPreviewHandles(item) {
+      console.log(123);
+      this.showPreview = true;
+      this.previewImages = [item];
+    },
+    closeViewer() {
+      this.showPreview = false;
+      document.querySelector("body").classList.remove("el-popup-imageView--hidden");
+    },
+    // 审核通过的确认按钮
+    openMessage(item) {
+      this.$confirm("确定通过此内容在小程序展示吗?", "审核通过", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+          const res = await raiInterface.yanxuan_specialEnable({
+            Id: item.Id,
+            Status: 1,
+          });
+          if (res.Ret === 200) {
+            this.$message.success("审核成功!");
+            this.getSpecialList();
+          }
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消",
+          });
+        });
+    },
+    // 获取作者列表
+    async getAuthorList() {
+      const res = await raiInterface.yanxuan_specialAuthorList();
+      if (res.Ret === 200) {
+        this.authorInfoData = res.Data || [];
+      }
+    },
+    // 作者的关闭或者打开
+    async switchAuthorChange(item) {
+      const res = await raiInterface.yanxuan_specialAuthorEnable({
+        UserId: item.UserId,
+        Status: item.Status,
+      });
+      if (res.Ret === 200) {
+        this.$message.success("操作成功!");
+      }
+    },
+    // 审核列表
+    async getSpecialList() {
+      const res = await raiInterface.yanxuan_specialList();
+      if (res.Ret === 200) {
+        this.specialListData = res.Data || [];
+
+        this.$nextTick(() => {
+          this.specialListData.forEach((item, index) => {
+            let h = document.getElementsByClassName("content-detial")[index].clientHeight;
+            this.$set(item, "isShowBtn", h >= 134 ? true : false);
+          });
+        });
+      }
+    },
+    // 驳回的弹框显示
+    submitRejectDlgHandler(item) {
+      this.submitRejectId = item.Id;
+      this.submitRejectDlgVisible = true;
+    },
+    handleOperation: _.debounce(function (item) {
+      const url = item.DocUrl;
+      if (!url) {
+        this.$message.warning("文件错误");
+        return;
+      }
+      const reg = /\.(pdf)$/;
+      // pdf
+      if (reg.test(url)) {
+        window.open(url, "_blank");
+      } else {
+        window.open("https://view.officeapps.live.com/op/view.aspx?src=" + url, "_blank");
+      }
+    }, 200),
+    lookAllDetails(item) {
+      let url =
+        process.env.NODE_ENV === "production"
+          ? `https://web.hzinsights.com/column/detail/${item.Id}`
+          : process.env.NODE_ENV === `test`
+          ? `https://clpttest.hzinsights.com/column/detail/${item.Id}`
+          : `https://clpttest.hzinsights.com/column/detail/${item.Id}`;
+      window.open(url, "_blank");
+    },
+  },
+};
+</script>
+<style lang="scss">
+div {
+  box-sizing: border-box;
+}
+.yanxuan-special_container {
+  display: flex;
+  justify-content: space-between;
+  .author-content {
+    width: 400px;
+    height: calc(100vh - 118px);
+    border-radius: 4px;
+    background-color: #fff;
+    padding: 20px;
+    box-sizing: border-box;
+    flex-shrink: 0;
+    .top {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+    }
+    .author-ul {
+      padding-bottom: 10px;
+      height: 100%;
+      overflow: hidden;
+      overflow-y: auto;
+      .author-li {
+        flex: 1;
+        padding: 20px;
+        display: flex;
+        justify-content: space-between;
+        border-bottom: 1px solid #dcdfe6;
+        margin: 10px 0;
+        .switch-box {
+          width: 30px;
+          flex-shrink: 0;
+        }
+      }
+    }
+  }
+  .info-content {
+    flex: 1;
+    padding-left: 16px;
+    color: #999999;
+    p {
+      margin: 5px 0;
+    }
+  }
+  .avatar {
+    width: 48px;
+    height: 48px;
+    border-radius: 50%;
+    overflow: hidden;
+    background: #d9d9d9;
+    flex-shrink: 0;
+    img {
+      width: 48px;
+      height: 48px;
+    }
+  }
+  .info-name {
+    font-size: 16px;
+    color: #333;
+    font-weight: 500;
+  }
+  .examine-content {
+    margin-left: 20px;
+    padding: 20px;
+    flex: 1;
+    background: #fff;
+    flex-direction: 0;
+    overflow: hidden;
+    .no-data {
+      width: 100%;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .content-box-examine {
+      padding: 30px 0;
+      border-bottom: 1px solid #dcdfe6;
+    }
+    .info-box {
+      display: flex;
+    }
+    .content-detial {
+      overflow: hidden;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      -webkit-box-orient: vertical;
+      -webkit-line-clamp: 8;
+      img {
+        width: 100%;
+        max-height: 300px;
+      }
+    }
+    .look-all-txt {
+      color: #409eff;
+      font-size: 16px;
+      margin-top: 20px;
+      cursor: pointer;
+    }
+    .file-box {
+      display: flex;
+      align-items: center;
+      margin-top: 20px;
+      height: 64px;
+      cursor: pointer;
+      img {
+        width: 27px;
+        height: 27px;
+        margin-right: 15px;
+      }
+    }
+    .img-box {
+      margin: 20px 0;
+      height: 112px;
+      img {
+        object-fit: fill !important;
+        cursor: pointer;
+        margin-right: 20px;
+      }
+    }
+    .lable-li {
+      display: inline-block;
+      padding: 4px 20px;
+      height: 28px;
+      border-radius: 48px;
+      margin: 0 15px 15px 0;
+      border: 1px solid #409eff;
+      background-color: #eaf3fe;
+      color: #409eff;
+    }
+    .bottom-button {
+      margin: 50px;
+      display: flex;
+      justify-content: center;
+      color: #fff;
+      div {
+        cursor: pointer;
+        width: 120px;
+        height: 40px;
+        padding: 10px 46px 10px 46px;
+        border-radius: 4px;
+        background: #c54322;
+      }
+      div:nth-child(2) {
+        margin-left: 20px;
+        background: #67c23a;
+      }
+    }
+  }
+}
+/deep/.el-image {
+  img {
+    object-fit: fill !important;
+  }
+}
+</style>