Эх сурвалжийг харах

Merge branch 'master' into crm_cygx_14.3

bding 1 жил өмнө
parent
commit
07f40f4f03

+ 26 - 0
src/api/modules/rai/YanXuanApi.js

@@ -0,0 +1,26 @@
+import http from "@/api/http.js";
+/* 权益小程序管理 报告模块*/
+const YanXuanApi = {
+  // 作者列表
+  yanxuan_specialAuthorList: (params) => {
+    return http.get("/cygx/yanxuan_special/author/list", params);
+  },
+  // 新增研选专栏作者
+  yanxuan_specialAuthorAdd: (params) => {
+    return http.post("/cygx/yanxuan_special/author/add", params);
+  },
+  // 禁用/启用研选专栏作者
+  yanxuan_specialAuthorEnable: (params) => {
+    return http.post("/cygx/yanxuan_special/author/enable", params);
+  },
+  // 审核列表
+  yanxuan_specialList: (params) => {
+    return http.get("/cygx/yanxuan_special/list", params);
+  },
+  // 审批研选专栏
+  yanxuan_specialEnable: (params) => {
+    return http.post("/cygx/yanxuan_special/enable", params);
+  },
+};
+
+export default YanXuanApi;

+ 3 - 1
src/api/modules/rai/raiApi.js

@@ -3,8 +3,9 @@ import timeLineApi from "./timeLine.js";
 import raiReport from "./reportApi";
 import raiBanner from "./bannerApi.js";
 import internalInterface from "./internalApi.js";
-import lableApi from "./lableApi.js"
+import lableApi from "./lableApi.js";
 import raiPoints from "./pointsApi.js";
+import YanXuanApi from "./YanXuanApi.js";
 /* 权益小程序管理 */
 const raiInterface = {
   ...raiReport,
@@ -13,6 +14,7 @@ const raiInterface = {
   ...internalInterface,
   ...lableApi,
   ...raiPoints,
+  ...YanXuanApi,
   /* 
 		优化建议列表
 		PageSize CurrentIndex KeyWord  

BIN
src/assets/img/icons/account-login-type.png


BIN
src/assets/img/icons/email-login-type.png


BIN
src/assets/img/icons/phone-login-type.png


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

@@ -289,6 +289,12 @@ export default [
           keepAlive: false,
         },
       },
+      {
+        path: "yanXuanSpecial",
+        component: () => import("@/views/rai_manage/reportManage/yanXuanSpecial.vue"),
+        name: "研选专栏",
+        hidden: false,
+      },
     ],
   },
 

+ 3 - 1
src/styles/vars.scss

@@ -46,7 +46,9 @@ a[href="https://froala.com/wysiwyg-editor"], a[href="https://www.froala.com/wysi
 @charset "utf-8";
 body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,button,input,textarea,th,td { margin:0; padding:0; }
 body{ font-size:12px; font-style:normal; font-family:"\5FAE\8F6F\96C5\9ED1", Helvetica, sans-serif,; }
-html{ overflow:auto; min-width:1000px; }
+html{ overflow:auto; 
+  // min-width:1000px;
+ }
 small{ font-size:12px; }
 h1{ font-size:18px; }
 h2{ font-size:16px; }

+ 1 - 0
src/views/Home.vue

@@ -998,6 +998,7 @@ export default {
   }
 }
 #containercon {
+  min-width: 1000px;
   width: 100%;
   position: absolute;
   top: 0px;

+ 156 - 23
src/views/Login.vue

@@ -1,6 +1,6 @@
 <template>
 	<div id="login">
-		<div id="login_wrapper">
+		<div id="login_wrapper" v-if="!isMobile">
 			<img class="login-bg" src="https://hzstatic.hzinsights.com/static/hz_crm_web/imgs/login_bg.png" alt />
 			<img class="login-icon" src="https://hzstatic.hzinsights.com/static/hz_crm_web/imgs/login_logo.png" alt />
 			<!-- <el-form
@@ -109,6 +109,58 @@
 					@changeModel="changeModel('ordinaryModel')"/>
 			</div>
 		</div>
+
+		<!-- 移动端的登录页面跟移动ETA的一模一样 单独整一份 -->
+		<div id="login_wrapper_mobile" v-else>
+			<template v-if="activeModel!=='forgetPassModel'">
+				<div class="login-logo">
+					<img src="https://hzstatic.hzinsights.com/static/hz_crm_web/imgs/login_logo.png" >
+				</div>
+				<div class="login-title">sign in to continue</div>
+				<OrdinaryModel ref="ordinaryModelMobile"
+					:loginCheck="loginCheck"
+					:accountCheck="accountCheck"
+					:isMobile="isMobile"
+					@clearnHint="clearnHint"
+					@changeModel="changeModel('forgetPassModel')"
+					v-show="activeModel=='ordinaryModel'"
+				/>
+				<MobileModel ref="mobileModelMobile"
+					:areaCode="areaCode" :isMobile="isMobile" 
+					v-show="activeModel=='mobileModel'"
+				/>
+				<EmailModel ref="emailModelMobile" :isMobile="isMobile" v-show="activeModel=='emailModel'" />
+
+				<el-button type="primary" @click.native="handleLogin" 
+				:loading="logining" class="submit_btn_mobile">登录</el-button>
+				<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>
+			</template>
+			<div class="login-box" v-else>
+				<!-- 忘记密码就不重新搞了,太麻烦了,就写一起吧 -->
+				<ForgetPassModel 
+					ref="forgetPassModelMobile"
+					:isMobile="isMobile" 
+					:autoAccount="$refs.ordinaryModelMobile?$refs.ordinaryModelMobile.form.account:''"
+					@changeModel="changeModel('ordinaryModel')"/>
+			</div>
+		</div>
+
 		<!-- 验证弹窗 -->
 		<el-dialog
 			class="check-dialog"
@@ -185,7 +237,34 @@ export default {
 			areaCode:[],
 
 			isCheckDialogShow:false,
-			checkActiveModel:'checkMobileModel'
+			checkActiveModel:'checkMobileModel',
+			isMobile:false
+		}
+	},
+	computed:{
+		activeModelForm(){
+			return this.isMobile?this.activeModel+'Mobile':this.activeModel
+		},
+		ordinaryModelForm(){
+			return this.isMobile?'ordinaryModelMobile':'ordinaryModel'
+		},
+		mobileModelForm(){
+			return this.isMobile?'mobileModelMobile':'mobileModel'
+		},
+		emailModelForm(){
+			return this.isMobile?'emailModelMobile':'emailModel'
+		}
+	},
+	watch:{
+		isMobile(value){
+			// 移动端变PC或相反的情况监听
+			// 重新获取验证码
+			this.$nextTick(()=>{
+				// console.log(this.activeModelForm);
+				if((this.activeModel=="mobileModel" || this.activeModel=="emailModel")&&
+				(!this.$refs[this.activeModelForm].picSrc))
+				this.$refs[this.activeModelForm].getCodePic()
+			})
 		}
 	},
 	created() {
@@ -201,8 +280,16 @@ export default {
 	},
 	mounted(){
 		this.getRememberedInfo()
+		this.isMobile=!(window.innerWidth>650)
+		window.addEventListener('resize',this.setIsMobile)
+	},
+	beforeDestroy() {
+		window.removeEventListener('resize',this.setIsMobile)
 	},
 	methods: {
+		setIsMobile(){
+			this.isMobile=!(window.innerWidth>650)
+		},
 		keyupSubmit() {
 			//回车登录
 			document.onkeydown = e => {
@@ -332,7 +419,7 @@ export default {
 		},
 		handleLogin(){
 			//先进行判空的表单验证
-			this.$refs[this.activeModel].$refs.modelForm.validate((valid)=>{
+			this.$refs[this.activeModelForm].$refs.modelForm.validate((valid)=>{
 				if(valid){
 					this.logining = true
 					//根据activeName 调用不同的登陆接口
@@ -364,7 +451,7 @@ export default {
 			})
 		},
 		ordinaryModelLogin(){
-			const {account,checkPass,checked} = this.$refs.ordinaryModel.form
+			const {account,checkPass,checked} = this.$refs[this.ordinaryModelForm].form
 			departInterence.userLogin({
 				LoginType:1,
 				Username:account,
@@ -401,7 +488,7 @@ export default {
 				this.loginSys(res)
 			})
 		},
-		mobileModelLogin(model='mobileModel'){
+		mobileModelLogin(model=this.mobileModelForm){
 			const {mobile,checkCode} = this.$refs[model].form
 			departInterence.userLogin({
 				LoginType:2,
@@ -412,15 +499,15 @@ export default {
 					//刷新图形验证码
 					this.$refs[model].getCodePic()
 					this.$refs[model].form.picCode = ''
-					model==='mobileModel'&&(this.logining = false)
-					model!=='mobileModel'&&(this.checkLogining = false)
+					model===this.mobileModelForm&&(this.logining = false)
+					model!==this.mobileModelForm&&(this.checkLogining = false)
 					return
 				}
 				this.setLoginInfo(res)
 				this.loginSys(res)
 			})
 		},
-		emailModelLogin(model='emailModel'){
+		emailModelLogin(model=this.emailModelForm){
 			const {email,checkCode} = this.$refs[model].form
 			departInterence.userLogin({
 				LoginType:3,
@@ -431,8 +518,8 @@ export default {
 					//刷新图形验证码
 					this.$refs[model].getCodePic()
 					this.$refs[model].form.picCode = ''
-					model==='emailModel'&&(this.logining = false)
-					model!=='emailModel'&&(this.checkLogining = false)
+					model===this.emailModelForm&&(this.logining = false)
+					model!==this.emailModelForm&&(this.checkLogining = false)
 					return
 				}
 				this.setLoginInfo(res)
@@ -515,6 +602,7 @@ export default {
 	background: #fff;
 	position: relative;
 	overflow: hidden;
+	overflow-y: auto;
 	#login_wrapper {
 		width: 100%;
 		height: 100%;
@@ -609,20 +697,65 @@ export default {
 			}
 		}
 	}
-	.remember-cont {
-		position: relative;
-		margin-bottom: 20px;
-		.warn-check-tip {
-			position: absolute;
-			min-width: 300px;
-			left: 130px;
-			top: 0;
-			padding: 2px 10px;
-			border: 1px solid #D1433A;
-			background: #FFEAE9;
-			color: #B72E18;
-			font-size: 14px;
+	@media screen and (max-width:650px) {
+		#login_wrapper_mobile{
+			// display: block;
+			padding: 15% 40px 20px;
+			.login-logo{
+				margin-bottom: 30px;
+				img{
+					width: 250px;
+				}
+			}
+			.login-title{
+				font-size: 14px;
+				color: #999999;
+			}
+			.submit_btn_mobile{
+				height: 44px;
+				width: 100%;
+				border-radius: 44px;
+			}
+			.login-type-box{
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				width: 54%;
+				margin: 0 auto;
+				.login-type-item{
+					display: flex;
+					flex-direction: column;
+					justify-content: center;
+					align-items: center;
+					margin-top: 50px;
+					img{
+						height: 40px;
+						width: 40px;
+						margin-bottom: 4px;
+					}
+					span{
+						font-size: 12px;
+						color: #666666;
+					}
+				}
+			}
 		}
 	}
+	// .remember-cont {
+	// 	position: relative;
+	// 	margin-bottom: 20px;
+	// 	.warn-check-tip {
+	// 		position: absolute;
+	// 		min-width: 300px;
+	// 		left: 130px;
+	// 		top: 0;
+	// 		padding: 2px 10px;
+	// 		border: 1px solid #D1433A;
+	// 		background: #FFEAE9;
+	// 		color: #B72E18;
+	// 		font-size: 14px;
+	// 	}
+	// }
 }
 </style>
+

+ 2 - 2
src/views/business_ETA_manage/businessAuth.vue

@@ -62,7 +62,7 @@ export default {
                 const {List,ChoiceList=[],HalfChoiceList=[]} = res.Data
                 this.authList = List||[]
                 this.defaultCheckedKeys = ChoiceList.filter((item)=>!HalfChoiceList.some((halfItem)=>item===halfItem))
-                this.handleCheckChange(ChoiceList,HalfChoiceList)
+                this.handleCheckChange(this.defaultCheckedKeys,HalfChoiceList)
             })
         },
         async handleBtnClik(type){
@@ -90,7 +90,7 @@ export default {
         handleCheckChange(choiceList,HalfChoiceList){
             const keys = choiceList||this.$refs.checkboxTree.getCheckedKeys()
             const halfKeys = HalfChoiceList||this.$refs.checkboxTree.getHalfCheckedKeys()
-            const ChoiceList = Array.from(new Set([...keys,...halfKeys]))
+            const ChoiceList = Array.from(new Set([...keys]))
             const topLevelNodes = this.authList.map(i=>i.MenuId)
             let nodeLength = 0
             topLevelNodes.forEach(i=>{

+ 24 - 6
src/views/custom_manage/compontents/ReadDialog.vue

@@ -20,7 +20,7 @@
 			</el-select>
 		</div>
 		<p style="margin:15px 0;">共有{{total}}条阅读记录</p>
-		<el-table :data="newList" border style="marginBottom:40px;" height="350">
+		<el-table :data="newList" border style="marginBottom:40px;" height="350" ref="reportTableRef">
 			<el-table-column align="center" label="标题">
 				<template slot-scope="scope">{{scope.row.ResearchReportName}}</template>
 			</el-table-column>
@@ -78,6 +78,10 @@ export default {
 			this.getReportList();
 		},
 		valueType(){
+			this.newList = [];
+			if(this.$refs.reportTableRef.bodyWrapper) {
+				this.$refs.reportTableRef.bodyWrapper.scrollTop = 0;
+			}
 			this.getReportList()
 		}
 	},
@@ -116,25 +120,31 @@ export default {
 				label: 'ficc'
 				}, 
 			],
-			total:0
+			total:0,
+
+			haveMore: false,
+			page_no: 1,
 		};
 	},
 	methods: {
 		cancelHandle() {
 			this.valueType=''
 			this.type = '';
-			this.newList = this.readList;
+			this.newList = [];
 			this.$emit('cancelRead');
 		},
 		getReportList() {
 			customInterence.readList({
 				UserId:Number(this.readId),
 				TxtType:this.valueType?Number(this.valueType):0,
+				LastViewTime: this.newList.length?this.newList[this.newList.length-1].CreatedTime:''
 			}).then(res => {
 				if(res.Ret === 200) {
 					this.total=res.Data.Total
-					this.readList = res.Data.List?res.Data.List:[];
-					this.newList = res.Data.List?res.Data.List:[];
+					this.haveMore = res.Data.List.length ? true : false;
+					this.newList = [...this.newList,...res.Data.List]
+
+					if(this.page_no===1) this.$refs.reportTableRef.bodyWrapper.addEventListener('scroll',this.loadMoreList);
 				}
 			})
 		},
@@ -146,7 +156,15 @@ export default {
 			}else {
 				this.newList = this.readList;
 			}
-		}
+		},
+
+		loadMoreList:_.throttle(function(){
+			const {scrollTop,clientHeight,scrollHeight} = this.$refs.reportTableRef.bodyWrapper
+      if(scrollTop + clientHeight >= scrollHeight-10 && this.haveMore){
+					this.page_no++;
+					this.getReportList();
+			} 
+		},300)
 	},
 	created() {},
 	mounted() {},

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

@@ -63,7 +63,11 @@ export default {
         Source:{//请求验证码来源:1登陆
             type:Number,
             default:1
-        }
+        },
+        isMobile:{
+            type:Boolean,
+            default:false
+        },
     },
     data() {
         return {

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

@@ -2,7 +2,8 @@
     <div class="forget-pass-model">
         <div class="header-nav" @click="changeModel">
             <span><i class="el-icon-back"></i></span>
-            <span>忘记密码</span>
+            <span v-if="!isMobile">忘记密码</span>
+            <span v-else>{{ forgetPassTextMobile }}</span>
         </div>
         <div class="step-container model-wrap" v-show="currentStep===0">
             <el-form 
@@ -40,7 +41,7 @@
                 <p>您正在找回账号{{form.account}}的密码</p>
                 <ModelSteps :active-step="currentStep"/>
             </div>
-            <div class="container-inner model-wrap" v-show="currentStep===1">
+            <div class="container-inner model-wrap" v-show="currentStep===1 && (!isMobile)">
                 <VerificationBox
                     verifies-type="mobile"
                     :info-text="userMobile||'暂未绑定'"
@@ -54,6 +55,24 @@
                     @goNext="getCode"
                 />
             </div>
+            <div v-show="currentStep===1 && isMobile">
+                <div class="verification-item" 
+                    :class="{'active':choosedWay==='mobile','disabled':!userMobile.length}" @click="choosedWay = 'mobile'">
+                    <!-- <div class="icon"> -->
+                        <img src="~@/assets/img/icons/phone-login-type.png" />
+                    <!-- </div> -->
+                    <div class="text">{{userMobile||'暂未绑定'}}</div>
+                </div>
+                <div class="verification-item"
+                    :class="{'active':choosedWay==='email','disabled':!userEmail.length}" @click="choosedWay = 'email'">
+                    <!-- <div class="icon"> -->
+                        <img src="~@/assets/img/icons/email-login-type.png" />
+                    <!-- </div> -->
+                    <div class="text">{{userEmail||'暂未绑定'}}</div>
+                </div>
+                <el-button class="verification-button" type="primary" round @click="getCode(choosedWay)"
+                v-show="userMobile.length || userEmail.length">获取验证码</el-button>
+            </div>
             <div class="container-inner" v-show="currentStep===2">
                 <CaptchaInput 
                     ref="captInput"
@@ -62,7 +81,6 @@
                     <el-button type="primary" plain @click="changeModel">上一步</el-button>
                     <el-button type="primary" @click="checkInput">下一步</el-button>
                 </div>
-                
             </div>
             <div class="container-inner model-wrap" v-show="currentStep===3">
                 <el-form 
@@ -114,6 +132,10 @@ export default {
         autoAccount:{//自动填写的账号,如果有,作为form.accout的初始值
             type:String,
             default:''
+        },
+        isMobile:{
+            type:Boolean,
+            default:false
         }
     },
     components: { VerificationBox, ModelSteps, CaptchaInput },
@@ -171,8 +193,25 @@ export default {
             checkPassStr:'确定',//重置密码按钮
             countDownNum:5,
             resetPassTimer:0,
+            choosedWay:'mobile',
         };
     },
+    computed:{
+        forgetPassTextMobile(){
+            switch (this.currentStep) {
+                case 0:
+                    return "忘记密码"
+                case 1:
+                    return "安全验证"
+                case 2:
+                    return "请输入验证码"
+                case 3:
+                    return "设置密码"
+                default:
+                    break;
+            }
+        }
+    },
     created(){
         this.getCodePic()
     },
@@ -335,5 +374,57 @@ export default {
             }
         }
     }
+    .verification-item{
+        display: flex;
+        align-items: center;
+        width:100%;
+        box-sizing: border-box;
+        padding:10px 15px;
+        margin-bottom: 30px;
+        border: 1px solid #DCDFE6;
+        border-radius: 8px;
+        background-color: #fff;
+        &.active{
+            border: 1px solid #0052D9;
+            background-color: #F2F3FF;
+        }
+        &.disabled{
+            user-select: none;
+            pointer-events: none;
+        }
+        img{
+            width: 40px;
+            margin-right: 10px;
+        }
+    }
+    .verification-button{
+        width: 100%;
+        margin-top: 20px;
+    }
+    @media screen and (max-width:650px) {
+        .header-nav{
+            font-size: 24px;
+        }
+        .submit_btn{
+            border-radius: 50px;
+        }
+        .step-container{
+            .container-header{
+                display: none;
+            }
+            .container-inner{
+                .btn-wrap{
+                    .el-button{
+                        width:100%;
+                        margin-left: 0;
+                        border-radius: 42px;
+                        &:first-child{
+                            margin-bottom: 30px;
+                        }
+                    }
+                }
+            }
+        }
+    }
 }
 </style>

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

@@ -72,7 +72,11 @@ export default {
         Source:{//请求验证码来源:1登陆
             type:Number,
             default:1
-        }
+        },
+        isMobile:{
+            type:Boolean,
+            default:false
+        },
     },
     data() {
         return {

+ 9 - 3
src/views/login_manage/OrdinaryModel.vue

@@ -20,14 +20,16 @@
             </el-form-item>
             <el-form-item prop="checkPass">
                 <el-input
-                    type="password" show-password
+                    type="password" :show-password="isMobile?false:true"
                     v-model="form.checkPass"
                     auto-complete="off"
                     placeholder="请输入密码"
                     @copy.native.capture.prevent="()=>{return false}"
                     @cut.native.capture.prevent="()=>{return false}"
                     @paste.native.capture.prevent="()=>{return false}"
-                />
+                >
+                    <span slot="append" @click="changeModel" v-if="isMobile">忘记密码?</span>
+                </el-input>
                 <span class="inline-message el-form-item__error" 
                     v-show="(loginCheck||accountCheck)&&form.checkPass.length">
                     {{hintMessage}}</span>
@@ -59,7 +61,11 @@ export default {
         accountCheck:{
             type:Boolean,
             default:false
-        }
+        },
+        isMobile:{
+            type:Boolean,
+            default:false
+        },
     },
     data() {
         const validateClearn = (rule,value,callBack)=>{

+ 9 - 0
src/views/login_manage/components/CaptchaInput.vue

@@ -105,4 +105,13 @@ export default {
 .active {
     border: 1px solid #3654C1 !important;
 }
+
+@media screen and (max-width:650px) {
+  .row-center {
+    gap:10px;
+  }
+  .captcha_input_box{
+    box-sizing: border-box;
+  }
+}
 </style>

+ 44 - 0
src/views/login_manage/css/formStyle.scss

@@ -108,4 +108,48 @@
             font-size: 16px;
         }
     }
+}
+
+@media screen and (max-width:650px) {
+    .model-wrap{
+        margin-top: 60px;
+        .el-form-item{
+            margin-bottom: 40px;
+            .el-input{
+                .el-input-group__prepend{
+                    border: none;
+                    border-radius: 0;
+                    border-bottom:solid 1px #DCDFE6;
+                    width: 70px;
+                    .el-input--suffix{
+                        width: 40px;
+                        .el-input__suffix{
+                            display: none;
+                        }
+                    }
+                }
+                .el-input__inner{
+                    border-radius: 0;
+                    border: none;
+                    border-bottom:solid 1px #DCDFE6;
+                    padding-left: 0;
+                }
+                .el-input-group__append{
+                    background-color: transparent;
+                    border: none;
+                    border-radius: 0;
+                    border-bottom:solid 1px #DCDFE6;
+                    padding: 0;
+                    span{
+                        color:#257EFF ;
+                        font-size: 14px;
+                    }
+                }
+            }
+
+        }
+        .remember-cont{
+            display: none;
+        }
+    }
 }

+ 140 - 0
src/views/rai_manage/reportManage/components/specialDlg.vue

@@ -0,0 +1,140 @@
+<template>
+  <div class="container special-dlg-container">
+    <el-dialog title="新建专栏作者" :visible.sync="addAuthorDlgVisible" width="500px" v-dialogDrag :close-on-click-modal="false" :modal-append-to-body="false" center @close="handleCloseAuthor">
+      <el-autocomplete
+        class="inline-input"
+        style="width: 100%; margin-bottom: 20px"
+        v-model="keyAuthor"
+        :fetch-suggestions="querySearchHandler"
+        @blur="changeHandler"
+        @select="selectCompany"
+        placeholder="请输入客户姓名"
+        :trigger-on-focus="false"
+      ></el-autocomplete>
+      <p v-show="!isShowKey" style="color: #f00">系统中无此人,请先将其添加到对应公司的联系人列表下</p>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleCloseAuthor">取 消</el-button>
+        <el-button type="primary" @click="addAuthorHandler">确 定</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog title="驳回" :visible.sync="submitRejectDlgVisible" width="500px" v-dialogDrag :close-on-click-modal="false" :modal-append-to-body="false" center @close="handleCloseReject">
+      <el-input type="textarea" :rows="4" style="margin-bottom: 20px" v-model.trim="textReject" placeholder="请输入驳回原因"></el-input>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleCloseReject">取 消</el-button>
+        <el-button type="primary" @click="submitRejectHandler">确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { raiInterface } from "@/api/api.js";
+export default {
+  name: "",
+  components: {},
+  props: {
+    addAuthorDlgVisible: {
+      default: false,
+      type: Boolean,
+    },
+    submitRejectDlgVisible: {
+      default: false,
+      type: Boolean,
+    },
+    submitRejectId: {
+      default: 0,
+      type: Number,
+    },
+  },
+  data() {
+    return {
+      keyAuthor: "",
+      companyList: [],
+      textReject: "",
+      isShowKey: true,
+    };
+  },
+  computed: {},
+  watch: {},
+  created() {},
+  mounted() {},
+  methods: {
+    // 关闭添加作者的弹框
+    handleCloseAuthor() {
+      this.keyAuthor = "";
+      this.$emit("update:addAuthorDlgVisible", false);
+    },
+    // 作者弹框的搜索事件
+    async querySearchHandler(query, cb) {
+      cb([]);
+      if (!query) return;
+      const res = await raiInterface.activitySignupUserList({ KeyWord: query });
+      if (res.Ret === 200) {
+        console.log(res);
+        let arr =
+          res.Data.List && res.Data.List.length
+            ? res.Data.List.map((item) => {
+                return {
+                  ...item,
+                  value: item.RealName + " - " + item.Mobile + " - " + item.CompanyName,
+                };
+              })
+            : [];
+        this.companyList = arr;
+        cb(arr);
+      }
+    },
+    // 作者添加的事件
+    async addAuthorHandler() {
+      const isKey = this.companyList.some((item) => item.value === this.keyAuthor);
+      if (!isKey) return this.$message.error("请输入客户姓名!");
+      let params = this.companyList.filter((item) => item.value === this.keyAuthor);
+      const res = await raiInterface.yanxuan_specialAuthorAdd({
+        UserId: params[0].UserId,
+        RealName: params[0].RealName,
+        Mobile: params[0].Mobile,
+      });
+      if (res.Ret === 200) {
+        this.handleCloseAuthor();
+        this.$message.success("添加成功!");
+        this.$parent.getAuthorList();
+      }
+    },
+    /* **************************************************** */
+    // 驳回的弹框关闭事件
+    handleCloseReject() {
+      this.textReject = "";
+      this.$emit("update:submitRejectDlgVisible", false);
+    },
+    // 驳回的弹框确定事件
+    async submitRejectHandler() {
+      if (!this.textReject) return this.$message.error("请输入驳回原因");
+      // 提交成功后刷新页面
+      const res = await raiInterface.yanxuan_specialEnable({
+        Id: this.submitRejectId,
+        Status: 2,
+        Reason: this.textReject,
+      });
+      if (res.Ret === 200) {
+        this.handleCloseReject();
+        this.$message.success("操作成功!");
+        this.$parent.getSpecialList();
+      }
+    },
+    changeHandler() {
+      if (!this.keyAuthor) return;
+      this.isShowKey = this.companyList.some((item) => item.value === this.keyAuthor);
+    },
+    selectCompany() {
+      this.isShowKey = this.companyList.some((item) => item.value === this.keyAuthor);
+    },
+  },
+};
+</script>
+<style lang="scss">
+.special-dlg-container {
+  .el-dialog .el-input {
+    width: 100%;
+  }
+}
+</style>

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

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

+ 13 - 3
src/views/report_manage/dayilyNews.vue

@@ -14,10 +14,17 @@
       <div class="list-item" v-for="(item,index) in newsList" :key="item.MsgId">
         <div class="item-cont">
           <p class="news">
-            <span style="font-weight: bold;margin-right: 10px;" v-if="item.MsgTime">{{item.MsgTime.substr(10)}}</span>
+            <span style="font-weight: bold;margin-right: 10px;" v-if="item.MsgTime">
+              {{transformTimeType(item.MsgTime)}}
+            </span>
             {{item.Content}} 
           </p>
-          <p class="news-en" :style="item.showEn ? 'display:block' : 'display:none'">{{item.ContentEn}}</p>
+          <p class="news-en" :style="item.showEn ? 'display:block' : 'display:none'">
+            <span style="font-weight: bold;margin-right: 10px;" v-if="item.MsgTime">
+              {{transformTimeType(item.MsgTime)}}
+            </span>
+            {{item.ContentEn}}
+          </p>
         </div>
 
         <div class="item-bot">
@@ -389,7 +396,10 @@ export default {
         this.page_no++;
         this.getList()
       }
-    },300)
+    },300),
+    transformTimeType(date){
+      return date.replaceAll('-','/').substr(0,16)
+    }
   },
 
   mounted() {