瀏覽代碼

merge master

bding 1 年之前
父節點
當前提交
22b27ea8f0
共有 49 個文件被更改,包括 2224 次插入527 次删除
  1. 1 0
      config/index.js
  2. 7 0
      src/api/modules/crmApi.js
  3. 7 0
      src/api/modules/rai/raiApi.js
  4. 4 0
      src/api/modules/rai/reportApi.js
  5. 65 0
      src/api/modules/statisticApi.js
  6. 二進制
      src/assets/img/icons/like-heart.png
  7. 16 0
      src/routes/modules/sellerRoutes.js
  8. 6 0
      src/routes/modules/statisticRoutes.js
  9. 177 74
      src/views/Login.vue
  10. 4 6
      src/views/business_ETA_manage/businessAuth.vue
  11. 15 11
      src/views/custom_manage/compontents/Contactdialog.vue
  12. 2 1
      src/views/custom_manage/compontents/Ctimeline.vue
  13. 44 1
      src/views/custom_manage/customList/customDetail.vue
  14. 83 10
      src/views/custom_manage/customList/customShareList.vue
  15. 13 2
      src/views/custom_manage/customList/regionCustomDetail.vue
  16. 213 0
      src/views/dataReport_manage/components/RenewalRateDetail.vue
  17. 162 0
      src/views/dataReport_manage/components/abnormalRenewalChart.vue
  18. 142 42
      src/views/dataReport_manage/equityCustomStatistics.vue
  19. 466 0
      src/views/dataReport_manage/equityPackageStatistics.vue
  20. 1 0
      src/views/dataReport_manage/index.scss
  21. 172 0
      src/views/dataReport_manage/statistic/abnormalRenewal.vue
  22. 100 22
      src/views/dataReport_manage/statistic/contractCustom.vue
  23. 52 13
      src/views/dataReport_manage/statistic/mixin.js
  24. 42 3
      src/views/dataReport_manage/statistic/newCustom.vue
  25. 0 3
      src/views/dataReport_manage/statistic/todoTask.vue
  26. 6 1
      src/views/login_manage/EmailModel.vue
  27. 3 0
      src/views/login_manage/ForgetPassModel.vue
  28. 7 1
      src/views/login_manage/MobileModel.vue
  29. 1 1
      src/views/login_manage/modelMixins.js
  30. 11 6
      src/views/operation_manage/AIQA/AIQA.vue
  31. 1 1
      src/views/operation_manage/AIQA/components/messageItem.vue
  32. 1 2
      src/views/operation_manage/AIQA/components/newWindowHint.vue
  33. 11 5
      src/views/rai_manage/activityManage/activityManage.vue
  34. 2 2
      src/views/rai_manage/activityManage/components/addActivity.vue
  35. 1 1
      src/views/rai_manage/activityManage/specialResearch.vue
  36. 13 67
      src/views/rai_manage/activityManage/specialResearch/addResearch.vue
  37. 1 1
      src/views/rai_manage/activityManage/specialResearch/determineTravel.vue
  38. 121 134
      src/views/rai_manage/components/addChoiceness.vue
  39. 40 50
      src/views/rai_manage/components/addMorningMeeting.vue
  40. 60 11
      src/views/rai_manage/components/addRoadshow.vue
  41. 1 1
      src/views/rai_manage/components/addSummarizing.vue
  42. 57 4
      src/views/rai_manage/components/addSummary.vue
  43. 1 1
      src/views/rai_manage/components/addThisWeek.vue
  44. 1 2
      src/views/rai_manage/components/apply/applyDialog.vue
  45. 1 0
      src/views/rai_manage/components/reportComponents/RichTextMixins.js
  46. 14 1
      src/views/rai_manage/components/richText.vue
  47. 9 2
      src/views/rai_manage/cygxManage/lableManage.vue
  48. 58 45
      src/views/rai_manage/reportManage/components/addHaveReport.vue
  49. 9 0
      src/views/rai_manage/reportManage/summaryManage.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:{

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

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

@@ -318,6 +318,13 @@ const raiInterface = {
   getNoTacticsfirst: (params) => {
     return http.get("/cygx/chartPermission/noTacticsfirst", params);
   },
+    /**
+   * 专项调研活动行业分类接口
+   * @returns
+   */
+    getActivitySpecial: (params) => {
+      return http.get("/cygx/chartPermission/activitySpecial", params);
+    },
   /**
    * 通过多个产业获取标的列表接口
    * @param {IndustrialManagementIdStr } params 分类ID,多个使用 ,隔开列如 1,3,5

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

@@ -33,6 +33,10 @@ const raiReport = {
   reportSelectionTarryList: (params) => {
     return http.get("/cygx/reportSelection/tarryList", params);
   },
+  // 文章置顶、取消置顶
+  summaryManageTopChange: (params) => {
+    return http.post("/cygx/summaryManage/top_change", params);
+  },
   
 };
 

+ 65 - 0
src/api/modules/statisticApi.js

@@ -103,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
@@ -123,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 
@@ -233,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
@@ -341,7 +366,47 @@ 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);
+ },
+  /**
+  * 权益客户续约率统计
+  * @param {PageSize} params 
+  * @param {CurrentIndex} params 
+  * @param {EndDate} params 结束日期
+  * @param {StartDate} params 开始日期
+  * @param {ContractDataType} params 到期合同
+  * @param {AdminId} params 销售id
 
+  * @returns  
+  */
+  incrementalCompanyContractPercentageList:params => {
+	return http.get('/statistic_report/merge_company/company_contract_percentage/list',params);
+},
+incrementalCompanyContractPercentageListV2:params => {
+	return http.get('/statistic_report/merge_company/company_contract_percentage/listV2',params);
+},
+  /**
+  * 权益客户续约率统计所能查询的年份
+  * @returns  
+  */
+  incrementalCompanyContractGetYearList:params => {
+	return http.get('/statistic_report/merge_company/get_year_list',params);
+},
 }
 
 export {

二進制
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
+			},
 		]
 	},
 ]

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

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

+ 177 - 74
src/views/Login.vue

@@ -73,11 +73,13 @@
 				</el-form-item>
 			</el-form> -->
 			<div class="login-box" id="login-container" v-if="activeModel!=='forgetPassModel'">
+				<div class="fixed-login-wrapper">
+
 				<h1 style="font-size: 38px;text-align: center;color: #333;margin-bottom: 30px;">
 					运营管理系统
 				</h1>
-				<el-tabs v-model="activeModel" @tab-click="handleClick">
-					<el-tab-pane label="账号登录" name="ordinaryModel">
+				<el-tabs v-model="activeModel">
+					<!-- <el-tab-pane label="账号登录" name="ordinaryModel">
 						<OrdinaryModel ref="ordinaryModel"
 							:loginCheck="loginCheck"
 							:accountCheck="accountCheck"
@@ -89,10 +91,22 @@
 						<MobileModel ref="mobileModel"
 							:areaCode="areaCode"
 						/>
-					</el-tab-pane>
-					<el-tab-pane label="邮箱登录" name="emailModel">
-						<EmailModel ref="emailModel"/>
-					</el-tab-pane>
+					</el-tab-pane> -->
+
+					<OrdinaryModel ref="ordinaryModel"
+							:loginCheck="loginCheck"
+							:accountCheck="accountCheck"
+							@clearnHint="clearnHint"
+							@changeModel="changeModel('forgetPassModel')"
+							v-show="activeModel=='ordinaryModel'"
+					/>
+
+					<MobileModel ref="mobileModel"
+							:areaCode="areaCode"
+							v-show="activeModel=='mobileModel'"
+					/>
+
+					<EmailModel ref="emailModel" v-show="activeModel=='emailModel'"/>
 				</el-tabs>
 				<el-button
 					type="primary"
@@ -101,12 +115,46 @@
 					: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-box">
+								<div class="login-type-item" @click="activeModel='ordinaryModel';handleClick({name:'ordinaryModelMobile'})"
+								v-show="activeModel!=='ordinaryModel'">
+									<img src="~@/assets/img/icons/account-login-type.png">
+									<span>账号登录</span>
+								</div>
+								<div class="login-type-item" @click="activeModel='mobileModel';handleClick({name:'mobileModelMobile'})"
+								v-show="activeModel!=='mobileModel'">
+									<img src="~@/assets/img/icons/phone-login-type.png">
+									<span>手机号登录</span>
+								</div>
+								<div class="login-type-item" v-show="activeModel!=='emailModel'" 
+								@click="activeModel='emailModel';handleClick({name:'emailModelMobile'})">
+									<img src="~@/assets/img/icons/email-login-type.png">
+									<span>邮箱登录</span>
+								</div>
+							</div>
+							<!-- <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>
 			<div class="login-box" v-else>
-				<ForgetPassModel 
-					ref="forgetPassModel"
-					:autoAccount="$refs.ordinaryModel?$refs.ordinaryModel.form.account:''"
-					@changeModel="changeModel('ordinaryModel')"/>
+				<div class="fixed-login-wrapper">
+					<ForgetPassModel 
+						ref="forgetPassModel"
+						:autoAccount="$refs.ordinaryModel?$refs.ordinaryModel.form.account:''"
+						@changeModel="changeModel('ordinaryModel')"/>
+				</div>	
 			</div>
 		</div>
 
@@ -646,74 +694,129 @@ export default {
 			width: 8%;
 		}
 
-		#login-container,.login-box{
-			width: 31%;
-			max-width: 570px;
-			box-sizing: border-box;
-			border-radius: 10px;
-			position: absolute;
-			top: 31%;
-			right: 14%;
-			z-index: 100;
-			font-size: 30px;
-			input::-webkit-input-placeholder {
-				color: #595959 !important;
-			}
-			.remember {
-				margin: 0px 0 20px;
-			}
-			.submit_btn {
-				width: 100%;
-				height: 50px;
-				background: #007eff;
-				font-size: 16px;
-				border-radius: 5px;
-				margin-top: 30px;
-			}
-			.el-input input {
-				width: 100%;
-				height: 40px;
-				color: #333333;
-				font-size: 16px;
-			}
-			.el-input-group__append,
-			.el-input-group__prepend {
-				background-color: rgba(255, 255, 255, 0.8);
-				color: rgb(51, 51, 51);
-				border: none;
-			}
-			.el-input.el-input-group.el-input-group--prepend input {
-				background-color: rgba(255, 255, 255, 0.8);
-				color: rgb(51, 51, 51);
-				border: none;
-			}
-			.el-checkbox__label {
-				color: rgb(51, 51, 51);
-				font-size: 14px;
-			}
-			.el-checkbox__input.is-checked + .el-checkbox__label {
-				color: rgb(51, 51, 51);
-				font-size: 14px;
-			}
-			.el-form-item__content .el-input-group,
-			.el-form-item__label,
-			.el-tag .el-icon-close {
-				padding-bottom: 5px;
-				vertical-align: middle;
-				border-bottom: 1px solid #eaeaea;
-			}
-			.el-button--primary {
-				background: #007eff !important;
-				border: none;
-			}
-			.el-form-item__content {
-				padding-bottom: 5px;
+	}
+	#login-container,.login-box{
+		width: 31%;
+		
+		box-sizing: border-box;
+		border-radius: 10px;
+		position: absolute;
+		top: 18%;
+		right: 14%;
+		z-index: 100;
+		font-size: 30px;
+		.fixed-login-wrapper {
+			width: 460px;
+			margin: 0 auto;
+		}
+		input::-webkit-input-placeholder {
+			color: #595959 !important;
+		}
+		.remember {
+			margin: 0px 0 20px;
+		}
+		.submit_btn {
+			width: 100%;
+			height: 50px;
+			background: #007eff;
+			font-size: 16px;
+			border-radius: 5px;
+			// margin-top: 30px;
+		}
+		.el-input input {
+			width: 100%;
+			height: 40px;
+			color: #333333;
+			font-size: 16px;
+		}
+		.el-input-group__append,
+		.el-input-group__prepend {
+			background-color: rgba(255, 255, 255, 0.8);
+			color: rgb(51, 51, 51);
+			border: none;
+		}
+		.el-input.el-input-group.el-input-group--prepend input {
+			background-color: rgba(255, 255, 255, 0.8);
+			color: rgb(51, 51, 51);
+			border: none;
+		}
+		.el-checkbox__label {
+			color: rgb(51, 51, 51);
+			font-size: 14px;
+		}
+		.el-checkbox__input.is-checked + .el-checkbox__label {
+			color: rgb(51, 51, 51);
+			font-size: 14px;
+		}
+		.el-form-item__content .el-input-group,
+		.el-form-item__label,
+		.el-tag .el-icon-close {
+			padding-bottom: 5px;
+			vertical-align: middle;
+			border-bottom: 1px solid #eaeaea;
+		}
+		.el-button--primary {
+			background: #007eff !important;
+			border: none;
+		}
+		.el-form-item__content {
+			padding-bottom: 5px;
+		}
+		.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;
+				}
 			}
-			.el-form-item {
-				margin-bottom: 30px;
+			.another-type{
+				.login-type-box {
+					display: flex;
+					justify-content: center;
+					gap: 10%;
+				}
+				.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:1201px) {
+		.login-bg { display: none; }
+		#login-container ,.login-box{
+				width: 70%;
+				top:15%;
+				left: 50%;
+				transform: translateX(-50%);
+			}
+	}
 	@media screen and (max-width:650px) {
 		#login_wrapper_mobile{
 			// display: block;

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

+ 2 - 1
src/views/custom_manage/compontents/Ctimeline.vue

@@ -17,7 +17,7 @@
 					<span v-if="activity.Operation=='freeze'&&activity.ApproveContent" class="freeze-text" @click="showFreeze(activity)">冻结理由</span>
 					<span v-if="(specialOperationList.includes(activity.Operation))&&activity.ApproveContent" @click="showRemark(activity)" class="freeze-text">未续约说明</span>
 					<!-- <span v-if="activity.Operation=='try_out'&&!isHasTryOutRenewalReason" class="freeze-text" @click="showAddRemark(activity)">添加说明</span> -->
-					<span v-if="isShowBtn&&index==firstTryOutIdx" class="freeze-text" @click="showAddRemark(activity)">添加未续约说明</span>
+					<span v-if="activity.Remark=='正式转试用'" class="freeze-text" @click="showAddRemark(activity)">添加未续约说明</span>
 					<span v-if="activity.Operation==='close'&&activity.ApproveContent" @click="showCloseRemark(activity)" class="freeze-text">关闭理由</span>
 				</el-timeline-item>
 			</el-timeline>
@@ -177,6 +177,7 @@ export default {
 		},
 		// 显示添加说明弹窗
 		showAddRemark(e){
+			console.log(e);
 			this.activeActivity=e
 			this.isShowAddDia=true
 		},

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

@@ -212,6 +212,7 @@
 				ref="userTable"
 				:data="userTable"
 				v-loading="isShowloadding"
+				:row-class-name="setRowClass"
 				element-loading-text="数据加载中..."
 				border>
 					<el-table-column
@@ -226,6 +227,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>
@@ -370,6 +372,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 
@@ -1324,7 +1329,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.如果是非管理员用户则直接根据数量判断
@@ -1639,6 +1666,12 @@ export default {
         });
 	 }
     },
+	// 设置表格行的样式
+	setRowClass({row}){
+		if(row.NotRead && row.IsFollow==1){
+			return "not-read-seven-days"
+		}
+	}
 	},
 	mounted() {
 		this.getDetail();
@@ -1778,6 +1811,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()
 	}
 }

+ 13 - 2
src/views/custom_manage/customList/regionCustomDetail.vue

@@ -10,14 +10,14 @@
                 @cell-mouse-enter="getCustomDetail"
             >
                 <el-table-column
-                    v-for="item in tableColumns"
+                    v-for="item in tableColumnsComputed"
                     :key="item.label"
                     :label="item.label"
                     :width="item.widthsty"
                     :min-width="item.minwidthsty"
                     :prop="item.key"
                     align="center"
-                    :sortable="['viewTotal','RoadShowTotal','LastViewTime','ExpireDay','createTime'].includes(item.key) ? 'custom' : false"
+                    :sortable="['viewTotal','RoadShowTotal','LastViewTime','ExpireDay'].includes(item.key) ? 'custom' : false"
                 >
                     <template slot-scope="{row}">
 
@@ -155,6 +155,10 @@ export default {
             label: '所属销售',
             key: 'SellerName',
           },
+          {
+            label: '分配销售',
+            key: 'ShareSeller',
+          },
           {
             label: '客户状态',
             key: 'Status',
@@ -198,6 +202,13 @@ export default {
       showMore(){
         const AdminName = localStorage.getItem('AdminName')
         return AdminName==='ydlou'
+      },
+      tableColumnsComputed(){
+        if(this.title.includes('正式')){
+          return this.tableColumns
+        }else{
+          return this.tableColumns.filter(item => item.label!='分配销售')
+        }
       }
     },
     methods: {

+ 213 - 0
src/views/dataReport_manage/components/RenewalRateDetail.vue

@@ -0,0 +1,213 @@
+<template>
+  <div class="renewal-rate-detail-content">
+    <el-dialog
+      :visible.sync="showRenewalRateDetailDlg"
+      title="不续约率详情"
+      top="5vh"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      :append-to-body="true"
+      @close="cancelHandle"
+      width="1000px"
+      v-dialogDrag
+      center
+      custom-class="renewal-rate-detail-content-dlg"
+    >
+      <div>
+        <el-tabs v-model="activeName" @tab-click="handleClick">
+          <el-tab-pane label="确认不续约合同" name="确认不续约合同"></el-tab-pane>
+          <el-tab-pane label="到期合同" name="到期合同"></el-tab-pane>
+        </el-tabs>
+      </div>
+      <p v-if="activeName === '确认不续约合同'">共有确认不续约合同 {{ RenewalDataFormSon.RenewalContractTotal }} 份,不续约总金额 {{ RenewalDataFormSon.RenewalContractMoney }} 元</p>
+      <p v-if="activeName === '到期合同'">共有到期合同 {{ RenewalDataFormSon.ExpireRenewalContractTotal }} 份,到期总金额 {{ RenewalDataFormSon.ExpireRenewalContractMoney }} 元</p>
+      <div class="table-wrap">
+        <el-table :data="RenewalDataFormSon.List" max-height="600" border style="width: 100%; margin-bottom: 20px">
+          <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 align="center" prop="SellerName" label="所属销售" width="100"> </el-table-column>
+          <el-table-column align="center" prop="Money" label="合同金额" width="130"> </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>
+          <el-table-column align="center" prop="Money" label="不续约归因" width="130">
+            <template slot-scope="{ row }">
+              <span style="color: #409eff; cursor: pointer" @click="editReasonLabel(row)">
+                {{ row.AscribeContent }}
+              </span>
+            </template></el-table-column
+          >
+        </el-table>
+        <el-pagination
+          layout="total,prev,pager,next"
+          background
+          :current-page="pageNo"
+          @current-change="handleCurrentChange"
+          :page-size="pageSize"
+          :total="total"
+          style="text-align: right; padding: 20px 0"
+        >
+        </el-pagination>
+      </div>
+    </el-dialog>
+    <el-dialog
+      :visible.sync="isConfirmNoRenewalShowSon"
+      title="确认不续约"
+      top="5vh"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      :append-to-body="true"
+      @close="cancelHandleSon"
+      width="652px"
+      v-dialogDrag
+      center
+      custom-class="custom-class-confirm-no-renewal-show-dlg"
+    >
+      <div class="user-title">{{ confirmNoRenewalFormSon.AscribeContent }}</div>
+      <div class="content-reason">{{ confirmNoRenewalFormSon.Content }}</div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { dataMainInterface } from "@/api/api.js";
+import confirmedNoRenewal from "./noRenewalReasonDia/confirmedNoRenewal.vue";
+
+export default {
+  props: {
+    showRenewalRateDetailDlg: {
+      default: false,
+      type: Boolean,
+    },
+    renewalRateDetailForm: {
+      default: "",
+      type: String,
+    },
+  },
+  data() {
+    return {
+      pageNo: 1,
+      pageSize: 10,
+      total: 0,
+      tableData: [],
+      activeName: "确认不续约合同",
+      RenewalDataFormSon: {},
+      confirmNoRenewalFormSon: {},
+      isConfirmNoRenewalShowSon: false,
+    };
+  },
+  components: {
+    confirmedNoRenewal,
+  },
+  watch: {
+    showRenewalRateDetailDlg: {
+      handler(val) {
+        if (val) {
+          this.getTableData();
+        }
+      },
+      deep: true,
+    },
+  },
+  methods: {
+    cancelHandle() {
+      this.pageNo = 1;
+      this.activeName = "确认不续约合同";
+      this.tableData = [];
+      this.pageNo = 1;
+      this.pageSize = 10;
+      this.total = 0;
+      this.$emit("update:showRenewalRateDetailDlg", false);
+      this.$emit("update:renewalRateDetailForm", {});
+    },
+    async getTableData() {
+      let params = {
+        ...this.renewalRateDetailForm,
+        PageSize: this.pageSize,
+        CurrentIndex: this.pageNo,
+        ContractDataType: this.activeName,
+      };
+      const res = await dataMainInterface.incrementalCompanyContractPercentageListV2(params);
+      if (res.Ret === 200) {
+        this.RenewalDataFormSon = res.Data;
+        this.total = res.Data.Paging.Totals;
+      }
+    },
+    // 分页
+    handleCurrentChange(page) {
+      this.pageNo = page;
+      this.getTableData();
+    },
+    // 去往公司详情
+    goCompanyHandle(row) {
+      let { href } = this.$router.resolve({
+        path: "/customDetail",
+        query: {
+          id: row.CompanyId,
+        },
+      });
+      window.open(href, "_blank");
+    },
+    // 头部的点击事件
+    handleClick() {
+      this.pageNo = 1;
+      this.getTableData();
+    },
+    cancelHandleSon() {
+      this.confirmNoRenewalFormSon = {};
+      this.isConfirmNoRenewalShowSon = false;
+    },
+    editReasonLabel(row) {
+      dataMainInterface.contractInfoNoRenewedAscribe({ CompanyContractId: row.CompanyContractId }).then((res) => {
+        if (res.Ret == 200) {
+          this.confirmNoRenewalFormSon = res.Data.Detail;
+          this.isConfirmNoRenewalShowSon = true;
+        }
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss">
+.renewal-rate-detail-content-dlg {
+  .table-wrap {
+    margin-top: 20px;
+  }
+  .el-tabs__nav-wrap::after {
+    background-color: #fff;
+  }
+}
+
+.custom-class-confirm-no-renewal-show-dlg {
+  div {
+    box-sizing: border-box;
+  }
+  .user-title {
+    width: 100%;
+    height: 40px;
+    padding-left: 20px;
+    line-height: 40px;
+    border: 1px solid #dcdfe6;
+  }
+  .content-reason {
+    padding: 20px;
+    margin: 20px 0;
+    width: 100%;
+    height: 201px;
+    border: 1px solid #dcdfe6;
+  }
+}
+</style>

+ 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('2023-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>

+ 142 - 42
src/views/dataReport_manage/equityCustomStatistics.vue

@@ -30,38 +30,72 @@
         </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 v-for="item in data_typeArr" :key="item.label">
+          <el-card style="margin-right: 50px" :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 === '新签客户' ? '<br />' : item.label === '续约客户' ? '起始时间在所选时间段内的续约合同' : ''" placement="top">
+                  <template slot="content">
+                    <div v-if="item.label === '新签客户'">
+                      <p>起始时间在所选时间段内的新签合同</p>
+                      <p>(第一份合同起始时间一年内的再次签约仍属于新签合同)</p>
+                    </div>
+                    <div v-else-if="item.label === '续约客户'">
+                      <p>起始时间在所选时间段内的续约合同</p>
+                      <p>(第一份合同起始时间一年以后的再次签约均属于续约合同)</p>
+                    </div>
+                    <p v-else>合同截止时间在所选时间段内的非正式、非永续客户</p>
+                  </template>
+                  <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>
+        </div>
+        <div class="annual-select-content">
+          <div class="select-content">
+            <div class="lable-text">
+              不续约率
+              <el-tooltip style="margin-right: 16px" class="item" effect="dark" content="所选年度的续约合同/所选年度的到期合同" placement="top-start">
+                <template slot="content">
+                  <div>
+                    <p>所选时间段的已确认不续约的合同金额/所选时间段的到期的合同金额</p>
+                    <p>(剔除非业务不续约的金额)</p>
+                  </div>
+                </template>
+                <i class="el-icon-info" style="color: #999"></i>
+              </el-tooltip>
+            </div>
+            <el-date-picker
+              v-model="yearValue"
+              type="daterange"
+              format="yyyy-MM-dd"
+              value-format="yyyy-MM-dd"
+              :clearable="false"
+              @change="getIncrementalCompanyContractPercentageList"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+            >
+            </el-date-picker>
+          </div>
+          <div class="select-content">
+            <span class="editsty" v-if="RenewalDataForm.RenewalRateMoney" @click="renewalRateLableHandler">&nbsp;&nbsp;{{ RenewalDataForm.RenewalRateMoney }}&nbsp;&nbsp;</span>
+            {{ RenewalDataForm.RenewalRateTotalContent ? `(${RenewalDataForm.RenewalRateTotalContent})` : " -  -" }}
+          </div>
+        </div>
       </div>
       <div class="tabs-box" v-if="filterObj.data_type == '续约客户'">
         <div class="tabs-box-confirm">
@@ -81,9 +115,6 @@
           <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>
@@ -168,8 +199,10 @@
       :noRenewalReasonList="noRenewalReasonList"
       @refreshReasonList="getNORenewalReasonList"
       @saveLabel="saveLabel"
+      equityType="权益客户统计"
     />
     <previous-detail :previousDetailDlg.sync="previousDetailDlg" :rowInfo="rowInfo" />
+    <RenewalRateDetail :showRenewalRateDetailDlg.sync="showRenewalRateDetailDlg" :renewalRateDetailForm.sync="renewalRateDetailForm" :noRenewalReasonListSon="noRenewalReasonList" />
   </div>
 </template>
 
@@ -182,12 +215,12 @@ 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";
-
+import RenewalRateDetail from "./components/renewalRateDetail.vue";
 var moment = require("moment");
 moment().format();
 export default {
   name: "",
-  components: { mPage, renewalListDia, addRemark, viewRemark, confirmedNoRenewal, PreviousDetail },
+  components: { mPage, renewalListDia, addRemark, viewRemark, confirmedNoRenewal, PreviousDetail, RenewalRateDetail },
   computed: {
     exportExcel() {
       let baseUrl = process.env.API_ROOT + "/statistic_report/merge_company_list";
@@ -306,6 +339,10 @@ export default {
       PackageDifference: "",
       previousDetailDlg: false,
       packageTypeList: ["增加套餐", "减少套餐", "维持套餐"],
+      yearValue: "",
+      showRenewalRateDetailDlg: false,
+      renewalRateDetailForm: {},
+      RenewalDataForm: {},
     };
   },
   /* 页面跳转前记录参数 */
@@ -461,6 +498,9 @@ export default {
       this.page_no = 1;
       this.searchVal = "";
       this.getTableData();
+      if (this.yearValue.length > 0) {
+        this.getIncrementalCompanyContractPercentageList();
+      }
     },
     /* 切换页码 */
     handleCurrentChange(page) {
@@ -546,7 +586,7 @@ export default {
       this.isConfirmNoRenewalShow = true;
     },
     editReasonLabel(row) {
-      dataMainInterface.infoNoRenewedAscribe({ CompanyId: row.CompanyId, ProductId: row.ProductId }).then((res) => {
+      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 || "" : "";
@@ -557,12 +597,11 @@ export default {
     },
     saveLabel(item) {
       let params = {
-        CompanyId: this.selectItemRow.CompanyId,
-        ProductId: this.selectItemRow.ProductId,
+        CompanyContractId: this.selectItemRow.CompanyContractId,
         CompanyAscribeId: item.CompanyAscribeId,
         Content: item.Content,
       };
-      dataMainInterface.addNoRenewedAscribe(params).then((res) => {
+      dataMainInterface.addAscribContract(params).then((res) => {
         if (res.Ret == 200) {
           this.$message.success("确认成功");
           this.isConfirmNoRenewalShow = false;
@@ -572,7 +611,6 @@ export default {
       });
     },
     previousDetailHadler(row) {
-      console.log(123);
       this.rowInfo = row;
       this.previousDetailDlg = true;
     },
@@ -580,6 +618,39 @@ export default {
       let str = text == "新签客户" ? "新签合同" : text == "续约客户" ? "续约合同" : "未续约客户";
       return str;
     },
+    // 年度续约的标签点击事件
+    annualSelectHandler(item) {
+      this.annualSelectActivue = item.name;
+      this.getIncrementalCompanyContractPercentageList();
+    },
+    // 点击了续约率
+    renewalRateLableHandler() {
+      this.showRenewalRateDetailDlg = true;
+      this.renewalRateDetailForm = this.initCompanyContractPercentageList();
+    },
+    // 获取年度续约的数据
+    async getIncrementalCompanyContractPercentageList() {
+      let params = this.initCompanyContractPercentageList();
+      const res = await dataMainInterface.incrementalCompanyContractPercentageListV2(params);
+      if (res.Ret === 200) {
+        this.RenewalDataForm = res.Data;
+      }
+    },
+    // 处理年度续约的数据
+    initCompanyContractPercentageList() {
+      let salesArr = [];
+      if (this.filterObj.sale.length) {
+        salesArr = this.filterObj.sale.map((item) => {
+          return item[item.length - 1];
+        });
+      }
+      let params = {
+        EndDate: this.yearValue.length > 0 ? this.yearValue[1] : "",
+        StartDate: this.yearValue.length > 0 ? this.yearValue[0] : "",
+        AdminId: salesArr.join(","),
+      };
+      return params;
+    },
   },
   created() {},
   mounted() {
@@ -659,6 +730,35 @@ export default {
 .package-difference {
   cursor: pointer;
 }
+.annual-select-content {
+  .select-content {
+    display: flex;
+    align-items: center;
+    margin-bottom: 15px;
+    .lable-text {
+      flex-shrink: 0;
+    }
+    .select-lable {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      box-sizing: border-box;
+      margin-left: 10px;
+      width: 92px;
+      height: 40px;
+      color: #409eff;
+      background-color: #ecf5ff;
+      border: 1px solid #b3d8ff;
+      border-radius: 4px;
+      cursor: pointer;
+    }
+    .act-select-lable {
+      color: #fff;
+      background-color: #409eff;
+      border: none;
+    }
+  }
+}
 </style>
 <style lang="scss">
 #dataReport-container {

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

+ 3 - 0
src/views/login_manage/ForgetPassModel.vue

@@ -320,6 +320,9 @@ export default {
                     }).then(res=>{
                         if(res.Ret!==200) return
                         this.$message.success('重置密码成功,请登陆')
+                        localStorage.setItem('timeKey',Date.now())
+                        localStorage.setItem("account", new http.Base64().encode(this.form.account));
+                        localStorage.setItem("checkPass", new http.Base64().encode(this.passForm.pass1));
                         this.resetPassCountDown()
                         this.resetPassTimer = setInterval(()=>{
                             this.resetPassCountDown()

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

+ 11 - 6
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,7 +86,7 @@ export default {
             /* window-content*/
             historyList:[],//当前窗口历史记录
             inputText:'',
-            model:'',//当前选择的模型
+            model:'GPT-4 Turbo',//当前选择的模型
             modelOldValue:'',
             modelList:[
                 {
@@ -113,6 +113,7 @@ export default {
             showHint:false,//选择模型提示
             isTyping:false,//是否处于打字动画中
             windowContentLoading:null,
+            answerLoading:false,//回答中
         };
     },
     watch:{
@@ -161,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')
@@ -207,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
         },
@@ -293,7 +294,7 @@ export default {
                 this.inputText+='\n'
                 return
             }
-            if(this.isTyping){
+            if(this.isTyping||this.answerLoading){
                 this.$message.warning('请等待回答完成')
                 return
             }
@@ -310,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中
@@ -339,6 +341,7 @@ export default {
                 Ask:inputText,
                 Model:this.model
             }).then(res=>{
+                this.answerLoading=false
                 //在回答未获取前切换了新窗口
                 if(this.historyList.length===0){
                     this.getWindowList()
@@ -373,6 +376,8 @@ export default {
                 msg.Model = Model
                 msg.isPlay = true
                 this.historyList.splice(this.historyList.length-1,1,msg)
+            }).catch(()=>{
+                this.answerLoading=false
             })
         },
         //获取窗口列表

+ 1 - 1
src/views/operation_manage/AIQA/components/messageItem.vue

@@ -59,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

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

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

+ 11 - 5
src/views/rai_manage/activityManage/activityManage.vue

@@ -7,11 +7,11 @@
         <div class="tabs-box">
           <span v-for="(item, index) in listTitle" :key="item.ChartPermissionId" @click="tabsBoxBtn(item, index)" :class="index == tabsPitchon ? 'pitch' : ''">{{ item.PermissionName }}</span>
         </div>
-        <div style="display: flex">
-          <el-upload ref="imgUpload" action="#" :http-request="handleUploadImg" :show-file-list="false" accept="image/*">
-            <el-button type="primary">识图建会</el-button>
+        <div style="display: flex;align-items: center">
+          <el-upload style="height:40px" ref="imgUpload" action="#" :http-request="handleUploadImg" :show-file-list="false" accept="image/*">
+            <el-button style="height:40px" type="primary">识图建会</el-button>
           </el-upload>
-          <el-button style="margin-left: 20px" type="primary" @click="$router.push(!isResearch ? '/addActivity' : '/addPurchaserActivity')">添加活动</el-button>
+          <el-button style="margin-left: 20px;height:40px" type="primary" @click="$router.push(!isResearch ? '/addActivity' : '/addPurchaserActivity')">添加活动</el-button>
         </div>
       </div>
     </el-card>
@@ -72,7 +72,9 @@
               &nbsp;&nbsp;
               <p class="deletesty" v-if="row.PublishStatus == 0 && tabsPitchon == 0" @click="operationBtn(row.ActivityId, '删除')">删除</p>
               <p class="editsty" v-if="row.IsShowSigninButton" @click="handleDownLoadImg(row)">下载签到码</p>
-              <p v-if="row.ChartPermissionId === 31 && tabsPitchon == 0" class="editsty" @click="overheadHandler(row.ActivityId, '置顶')">&nbsp;&nbsp;{{ row.TopTime == 0 ? "置顶" : "取消置顶" }}</p>
+              <p v-if="row.ChartPermissionId === 31 && tabsPitchon == 0 && row.PublishStatus == 1" class="editsty" @click="overheadHandler(row.ActivityId, '置顶')">
+                &nbsp;&nbsp;{{ row.TopTime == 0 ? "置顶" : "取消置顶" }}
+              </p>
             </div>
           </template>
         </el-table-column>
@@ -437,5 +439,9 @@ export default {
       flex-shrink: 0;
     }
   }
+  .el-upload  {
+    height: 40px !important;
+    min-height: 40px !important;
+  }
 }
 </style>

+ 2 - 2
src/views/rai_manage/activityManage/components/addActivity.vue

@@ -643,7 +643,7 @@ export default {
       this.saveTheRelease(type, arr, VoiceList, VideoDetail[0]);
     },
     //保存或发布
-    async saveTheRelease(type, arr, VoiceList, VideoDetail) {
+    saveTheRelease: _.debounce(async function (type, arr, VoiceList, VideoDetail) {
       let RefPage = this.$refs.researchSelect;
       let PointsSet = RefPage.PointsSet;
       const res = await raiInterface.preserveAndPublishAdd({
@@ -683,7 +683,7 @@ export default {
       if (res.Ret !== 200) return;
       this.$message.success("操作成功!");
       this.$router.back();
-    },
+    }, 500),
     //获取行业
     chartPermission() {
       raiInterface.chartPermissionList({ IsHideResearch: !this.isResearch }).then((res) => {

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

@@ -177,7 +177,7 @@ export default {
     },
     //获取行业
     chartPermission() {
-      raiInterface.getNoTacticsfirst().then((res) => {
+      raiInterface.getActivitySpecial().then((res) => {
         if (res.Ret === 200) {
           this.chartPermissionList = res.Data.List;
         }

+ 13 - 67
src/views/rai_manage/activityManage/specialResearch/addResearch.vue

@@ -4,12 +4,7 @@
       <el-form :model="ruleForm" :rules="rules" ref="ruleFormList" label-width="100px" class="demo-ruleForm">
         <el-form-item label="所属行业:" prop="industry">
           <el-select placeholder="请选择行业" style="width: 396px" clearable v-model="ruleForm.industry" @change="changeHandel">
-            <el-option
-              v-for="item in chartPermissionList"
-              :label="item.PermissionName"
-              :key="item.PermissionName"
-              :value="item.PermissionName"
-            ></el-option>
+            <el-option v-for="item in chartPermissionList" :label="item.PermissionName" :key="item.PermissionName" :value="item.PermissionName"></el-option>
           </el-select>
         </el-form-item>
         <el-form-item label="调研主题:" prop="theme">
@@ -22,12 +17,7 @@
           <el-radio-group v-model="ruleForm.modality">
             <el-radio v-for="item in modalityRadio" :key="item.id" :label="item.id">{{ item.name }}</el-radio>
           </el-radio-group>
-          <el-input
-            v-model="ruleForm.city"
-            v-if="ruleForm.modality == 2"
-            style="width: 248px; margin-left: 10px"
-            placeholder="请输入调研城市,多个城市以','隔开"
-          ></el-input>
+          <el-input v-model="ruleForm.city" v-if="ruleForm.modality == 2" style="width: 248px; margin-left: 10px" placeholder="请输入调研城市,多个城市以','隔开"></el-input>
         </el-form-item>
         <el-form-item label="主题标签:">
           <div style="display: flex; align-items: center; flex-wrap: wrap">
@@ -47,25 +37,13 @@
               </el-cascader>
             </el-form-item>
             <el-form-item>
-              <el-select
-                style="margin: 0 15px 10px 0"
-                v-model="ruleForm.mark"
-                :disabled="selectDisabled"
-                @focus="markSelectFocus"
-                multiple
-                placeholder="请选择关联标的"
-              >
-                <el-option v-for="item in markOptions" :key="item.IndustrialSubjectId" :value="item.IndustrialSubjectId" :label="item.SubjectName">
-                </el-option>
+              <el-select style="margin: 0 15px 10px 0" v-model="ruleForm.mark" :disabled="selectDisabled" @focus="markSelectFocus" multiple placeholder="请选择关联标的">
+                <el-option v-for="item in markOptions" :key="item.IndustrialSubjectId" :value="item.IndustrialSubjectId" :label="item.SubjectName"> </el-option>
               </el-select>
             </el-form-item>
             <div v-for="(item, index) in addSubjectData" :key="index" style="display: inline-block">
               <el-input style="width: 220px; margin: 0 5px 10px 0" v-model="item.subjectVal" placeholder="请输入标的名称" type="text"> </el-input>
-              <img
-                @click="deleteSubject(item, index)"
-                style="width: 18px; margin-right: 20px; vertical-align: middle"
-                src="~@/assets/img/icons/delete-Item.png"
-              />
+              <img @click="deleteSubject(item, index)" style="width: 18px; margin-right: 20px; vertical-align: middle" src="~@/assets/img/icons/delete-Item.png" />
             </div>
             <el-tooltip class="item" effect="dark" content="添加标的" placement="top-start">
               <img @click="addLabelClick" class="editsty" src="~@/assets/img/set_m/add_ico.png" style="margin: 0 10px 10px" />
@@ -74,27 +52,14 @@
           <div style="display: flex; align-items: center; margin-top: 10px">
             <el-checkbox v-model="ruleForm.isMark">小程序内显示标的名称</el-checkbox>
             <el-checkbox style="margin-left: 10px" v-model="radioTemporary">临时标签</el-checkbox>
-            <el-input
-              style="width: 300px; margin: 0 10px"
-              v-model="valTemporary"
-              @focus="radioTemporary = true"
-              placeholder="请输入标签名称"
-              type="text"
-            ></el-input>
+            <el-input style="width: 300px; margin: 0 10px" v-model="valTemporary" @focus="radioTemporary = true" placeholder="请输入标签名称" type="text"></el-input>
             <div class="editsty" @click="dialogVisibleSubject = true">查询标的</div>
           </div>
         </el-form-item>
         <el-form-item label="活动可见:" prop="checkedCities">
           <div style="display: flex">
             <span style="width: 70px" class="text-right"> 套餐类型: </span>
-            <el-checkbox
-              :indeterminate="isIndeterminate"
-              v-model="ruleForm.checkAll"
-              @change="handleCheckAllChange"
-              :disabled="checkAllIs"
-              style="margin-right: 30px"
-              >全选</el-checkbox
-            >
+            <el-checkbox :indeterminate="isIndeterminate" v-model="ruleForm.checkAll" @change="handleCheckAllChange" :disabled="checkAllIs" style="margin-right: 30px">全选</el-checkbox>
             <el-checkbox-group v-model="ruleForm.checkedCities" @change="handleCheckedCitiesChange">
               <el-checkbox v-for="item in cities" :label="item.CustomerTypeId" :key="item.CustomerTypeId">
                 {{ item.CustomerName }}
@@ -130,29 +95,10 @@
         </div>
       </el-form>
     </el-card>
-    <el-dialog
-      width="500px"
-      v-dialogDrag
-      :close-on-click-modal="false"
-      :modal-append-to-body="false"
-      center
-      title="查询标的"
-      :visible.sync="dialogVisibleSubject"
-      :before-close="handleCloseSubject"
-    >
+    <el-dialog width="500px" v-dialogDrag :close-on-click-modal="false" :modal-append-to-body="false" center title="查询标的" :visible.sync="dialogVisibleSubject" :before-close="handleCloseSubject">
       <div>
-        <el-select
-          style="width: 100%"
-          v-model="addSubjectName"
-          remote
-          :remote-method="remoteMethod"
-          clearable
-          filterable
-          @change="searchInfo"
-          placeholder="请输入标的名称"
-        >
-          <el-option v-for="item in addSubjectOptions" :key="item.IndustrialSubjectId" :label="item.SubjectName" :value="item.SubjectName">
-          </el-option>
+        <el-select style="width: 100%" v-model="addSubjectName" remote :remote-method="remoteMethod" clearable filterable @change="searchInfo" placeholder="请输入标的名称">
+          <el-option v-for="item in addSubjectOptions" :key="item.IndustrialSubjectId" :label="item.SubjectName" :value="item.SubjectName"> </el-option>
         </el-select>
       </div>
       <p class="subject-text" v-if="isShowSubject">暂无数据</p>
@@ -263,7 +209,7 @@ export default {
   methods: {
     //获取行业
     chartPermission() {
-      raiInterface.getNoTacticsfirst().then((res) => {
+      raiInterface.getActivitySpecial().then((res) => {
         if (res.Ret === 200) {
           this.chartPermissionList = res.Data.List;
         }
@@ -424,7 +370,7 @@ export default {
       this.dialogVisibleSubject = false;
     },
     //保持或者发布
-    submitForm(type) {
+    submitForm: _.debounce(function (type) {
       if (this.selectDisabled) {
         if (!this.valTemporary) return this.$message.error("请输入临时标签");
         let validateFieldList = [];
@@ -450,7 +396,7 @@ export default {
           }
         });
       }
-    },
+    }, 500),
     async postPublish(type) {
       let arr = this.ruleForm.property.map((item) => {
         return item[1];

+ 1 - 1
src/views/rai_manage/activityManage/specialResearch/determineTravel.vue

@@ -317,7 +317,7 @@ export default {
   methods: {
     //获取行业
     chartPermission() {
-      raiInterface.getNoTacticsfirst().then((res) => {
+      raiInterface.getActivitySpecial().then((res) => {
         if (res.Ret === 200) {
           this.chartPermissionList = res.Data.List;
         }

+ 121 - 134
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>
-          </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 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>
-            <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,
@@ -470,15 +455,9 @@ export default {
       }
     },
     //保存 发布
-    confirm(type) {
+    confirm: _.debounce(function (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();
@@ -504,11 +484,13 @@ export default {
           }
         }
       });
-    },
+    }, 500),
     //取消
     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">

+ 40 - 50
src/views/rai_manage/components/addMorningMeeting.vue

@@ -12,23 +12,19 @@
               <h3>段落{{ index + 1 }}:</h3>
               <span class="dele" v-if="index !== 0" @click="deleteSection(index)"> <img src="~@/assets/img/icons/delete-Item.png" /></span>
             </div>
+            <div>
+              <el-checkbox v-model="item.isJumpNot">可跳转报告详情</el-checkbox>
+              <template v-if="item.isJumpNot">
+                <el-input style="margin: 20px 0" v-model="item.reportLink" placeholder="请输入报告链接"></el-input>
+                <el-input v-model="item.headTitle" placeholder="请输入首行标题"></el-input>
+              </template>
+            </div>
             <div class="fr-wrapper">
-              <froala
-              :id="`froala-editor-${index}`"
-              :ref="`froalaEditor${index}`"
-              :tag="'textarea'"
-              :config="froalaConfig"
-              v-model="item.content"
-              ></froala>
+              <froala :id="`froala-editor-${index}`" :ref="`froalaEditor${index}`" :tag="'textarea'" :config="froalaConfig" v-model="item.content"></froala>
             </div>
           </div>
           <div class="classify-box">
-            <el-select
-              placeholder="请选择行业"
-              v-model="item.industry"
-              value-key="ChartPermissionId"
-              @change="handleSelectChange(item, index, 'industry')"
-            >
+            <el-select placeholder="请选择行业" v-model="item.industry" value-key="ChartPermissionId" @change="handleSelectChange(item, index, 'industry')">
               <el-option
                 v-for="industry in industryData"
                 :key="industry.ChartPermissionId"
@@ -36,27 +32,11 @@
                 :value="{ ChartPermissionId: industry.ChartPermissionId, PermissionName: industry.PermissionName }"
               />
             </el-select>
-            <el-select
-              placeholder="请选择产业"
-              filterable
-              v-model="item.property"
-              value-key="ChartPermissionId"
-              @change="handleSelectChange(item, index, 'property')"
-            >
-              <el-option
-                v-for="property in getPropertyData(item.industry)"
-                :key="property.ChartPermissionId"
-                :label="property.PermissionName"
-                :value="property"
-              />
+            <el-select placeholder="请选择产业" filterable v-model="item.property" value-key="ChartPermissionId" @change="handleSelectChange(item, index, 'property')">
+              <el-option v-for="property in getPropertyData(item.industry)" :key="property.ChartPermissionId" :label="property.PermissionName" :value="property" />
             </el-select>
             <el-select multiple placeholder="请选择标的" v-model="item.subject" @focus="getSubjectData(item.property)">
-              <el-option
-                v-for="subject in subjectData"
-                :key="subject.IndustrialSubjectId"
-                :label="subject.SubjectName"
-                :value="subject.IndustrialSubjectId"
-              />
+              <el-option v-for="subject in subjectData" :key="subject.IndustrialSubjectId" :label="subject.SubjectName" :value="subject.IndustrialSubjectId" />
             </el-select>
           </div>
         </div>
@@ -74,25 +54,15 @@
 
 <script>
 import { raiInterface } from "@/api/api.js";
-export default {    
+export default {
   data() {
     var that = this;
     return {
       meettingDate: "",
       meetingId: 0,
       froalaConfig: {
-        toolbarButtons: [
-          "bold",
-          "italic",
-          "underline",
-          "strikeThrough",
-          "insertHR",
-          "fontSize",
-          "align",
-          "undo",
-          "redo",
-        ],
-        height: 150,
+        toolbarButtons: ["bold", "italic", "underline", "strikeThrough", "insertHR", "fontSize", "align", "undo", "redo"],
+        height: 260,
         fontSizeDefaultSelection: "16",
         quickInsertEnabled: false,
         theme: "dark", //主题
@@ -107,6 +77,9 @@ export default {
       },
       sectionData: [
         {
+          isJumpNot: false, //是否跳转
+          reportLink: "", //报告链接
+          headTitle: "", //报告标题
           content: "", //晨会内容
           industry: "", //行业
           property: "", //行业
@@ -130,6 +103,9 @@ export default {
         industry: "",
         property: "",
         subject: "",
+        isJumpNot: false, //是否跳转
+        reportLink: "", //报告链接
+        headTitle: "", //报告标题
       };
       this.sectionData.push(section);
     },
@@ -200,6 +176,9 @@ export default {
           content: item.content,
           industry: { ChartPermissionId: item.chartPermissionId, PermissionName: item.chartPermissionName },
           property: { ChartPermissionId: item.industryId, PermissionName: item.industryName },
+          reportLink: item.reportLink,
+          headTitle: item.title,
+          isJumpNot: item.reportLink ? true : false,
         };
         let subject = [];
         let industrialSubjectList = item.industrialSubjectList || [];
@@ -213,7 +192,7 @@ export default {
       this.dataLoading = false;
     },
     //保存 发布 取消 操作
-    async comfirm(type) {
+    comfirm: _.debounce(async function (type) {
       if (type === "cancel") {
         this.$router.back();
         return;
@@ -229,7 +208,7 @@ export default {
       /* if(type==="cancel"){} */
 
       this.isGoBack && this.$router.back();
-    },
+    }, 500),
     async pubMeeting() {
       const list = this.getSectionData();
       const res = await raiInterface.publishMorningMeeting({
@@ -288,6 +267,8 @@ export default {
           IndustryId: item.property.ChartPermissionId,
           IndustryName: item.property.PermissionName,
           IndustrialSubjectIds: item.subject.join(),
+          ReportLink: item.reportLink,
+          Title: item.headTitle,
         };
         list.push(temp);
       });
@@ -296,6 +277,14 @@ export default {
     //检查晨会内容
     checkContent() {
       for (let i = 0; i < this.sectionData.length; i++) {
+        if (this.sectionData[i].isJumpNot && this.sectionData[i].reportLink.length === 0) {
+          this.$message.warning(`请输入段落${i + 1}报告链接`);
+          return false;
+        }
+        if (this.sectionData[i].isJumpNot && this.sectionData[i].headTitle.length === 0) {
+          this.$message.warning(`请输入段落${i + 1}报告标题`);
+          return false;
+        }
         //所有的段落有值
         if (this.sectionData[i].content.length === 0) {
           this.$message.warning(`请输入段落${i + 1}的内容`);
@@ -400,8 +389,9 @@ export default {
     }
   }
   .fr-wrapper {
-  border-top: 1px solid #cccccc !important;
-  border-bottom: 1px solid #cccccc !important;
-}
+    margin-top: 20px;
+    border-top: 1px solid #cccccc !important;
+    border-bottom: 1px solid #cccccc !important;
+  }
 }
 </style>

+ 60 - 11
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, //作者
@@ -161,7 +202,7 @@ export default {
       }
     },
     //保存 / 发布
-    confirm(type) {
+    confirm: _.debounce(function (type) {
       this.$refs.ruleForm.validate(async (value) => {
         if (value) {
           let params = {
@@ -176,23 +217,24 @@ 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();
             }
           }
-
         }
       });
-    },
+    }, 500),
     industryClear() {
       this.listForm.property = [];
       this.optionsProperty = [];
@@ -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">

+ 1 - 1
src/views/rai_manage/components/addSummarizing.vue

@@ -227,7 +227,7 @@ export default {
           }
         }
       });
-    }, 300),
+    }, 500),
     fnConFirm() {
       let flag = false;
       let isCydyjy = this.ListCydyjy.some((item) => item.List.length > 0);

+ 57 - 4
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) {
@@ -239,7 +285,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,
     regionsChange(e) {
       this.articleTypeName = this.chartPermissionList.find((item) => item.ArticleTypeId == e).ArticleTypeName;
       let str = this.synopsisText.find((item) => item.ArticleTypeId == e);
-      this.addOfEditForm.synopsis = str ? str.Abstract : "";
     },
     //进来编辑的 获取内容的事件
     async getsummaryManagedetail() {
@@ -270,7 +315,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,
       this.markSelectFocus();
     },
     //表单保存发布事件
-    async submitForm(type) {
+    submitForm: _.debounce(async function (type) {
       let validateFieldList = [];
       this.$refs.addOfEditForm.validateField([this.isSource === "HZ" ? "industry" : "regions", "property", "publishTime", "title", "synopsis", "mobile"], (valid) => {
         validateFieldList.push(valid);
@@ -306,16 +351,20 @@ 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();
           }
         }
       }
-    },
+    }, 500),
     //表单取消事件
     cancelBtn() {
+      clearInterval(this.timeInterval);
       this.$refs.addOfEditForm.resetFields();
+      sessionStorage.removeItem(this.isSource == "HZ" ? "addSummaryParamsHZ" : "addSummaryParamsQY");
       this.$router.back();
     },
     //获取行业
@@ -388,7 +437,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,
       }
     },
     propertyChange() {
-      console.log("change");
       this.markOptions = [];
       this.markValue = "";
     },
@@ -471,6 +519,11 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,
       });
     },
   },
+  // 路由离开了 清除定时器
+  beforeRouteLeave(to, from, next) {
+    clearInterval(this.timeInterval);
+    next();
+  },
 };
 </script>
 <style lang="scss">

+ 1 - 1
src/views/rai_manage/components/addThisWeek.vue

@@ -335,7 +335,7 @@ export default {
           }
         }
       });
-    }, 300),
+    }, 500),
     fnConFirm() {
       let flag = false;
       let isSdbg = this.ListSdbg.some((item) => item.List.length > 0); //深度报告篇

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

+ 58 - 45
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();
       }
@@ -256,7 +260,7 @@ export default {
       await this.propertyChangeHandler();
     },
     //表单保存发布事件
-    async submitForm(type) {
+    submitForm: _.debounce(async function (type) {
       this.$refs.addOfEditForm.validate(async (valid) => {
         if (valid) {
           let params = {
@@ -276,14 +280,18 @@ 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");
           }
         }
       });
-    },
+    }, 500),
     //表单取消事件
     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">

+ 9 - 0
src/views/rai_manage/reportManage/summaryManage.vue

@@ -72,6 +72,7 @@
             <span class="editsty" @click="operationBtn(scope.row.ArticleId, '发布')">{{ scope.row.PublishStatus == 0 ? "发布" : "取消发布" }} &nbsp;&nbsp;</span>
             <span class="editsty" @click="editBtn(scope.row.ArticleId)">编辑 &nbsp;&nbsp;</span>
             <span class="deletesty" v-if="scope.row.PublishStatus == 0" @click="operationBtn(scope.row.ArticleId, '删除')">删除 &nbsp;&nbsp;</span>
+            <span class="editsty" v-if="scope.row.PublishStatus != 0" @click="toppingHandler(scope.row)">{{ scope.row.TopTime > 0 ? "取消置顶" : "置顶" }} &nbsp;&nbsp;</span>
           </template>
         </el-table-column>
       </el-table>
@@ -351,6 +352,14 @@ export default {
     clearAuthor() {
       this.remoteMethodAuthor();
     },
+    // 置顶 取消置顶
+    async toppingHandler(item) {
+      const res = await raiInterface.summaryManageTopChange({ ArticleId: item.ArticleId });
+      if (res.Ret === 200) {
+        this.getsummaryManageList();
+        this.$message.success("操作成功");
+      }
+    },
   },
   //路由离开
   beforeRouteLeave(to, from, next) {