Przeglądaj źródła

Merge branch 'master' of http://8.136.199.33:3000/hongze/hz_crm_web

hbchen 1 rok temu
rodzic
commit
f8737a202f

+ 74 - 0
src/api/modules/setApi.js

@@ -244,6 +244,80 @@ const departInterence = {
 	//从其他系统跳转来用code换token
 	useCodeLogin:params=>{
 		return http.get('/sysuser/auth_code_login',params)
+	},
+    /**
+	 * 获取图形验证码 返回Base64格式数据
+	 * @returns 
+	 */
+	getCodePic:params=>{
+		return http.get('/user_login/get_captcha',params)
+	},
+	/**
+	 * 获取短信/邮箱验证码
+	 * @param {Number} VerifyType 验证方式: 1-手机号; 2-邮箱
+	 * @param {String} CaptchaId 图形验证码ID
+	 * @param {String} CaptchaCode 图形验证码的值
+	 * @param {String} Mobile 手机号 验证方式为1时必填
+	 * @param {String} Email 邮箱 验证方式为2时必填
+	 * @param {String} TelAreaCode 手机区号
+	 * @param {Number} Source 来源:1-登录;2-异常登录校验;3-忘记密码
+	 * @returns 
+	 */
+	getCodeVerify:params=>{
+		return http.post('/user_login/verify_code',params)
+	},
+	/**
+	 * ETA1.4后,用户登录
+	 * @param {Number} LoginType 登录方式: 1-账号; 2-手机号; 3-邮箱
+	 * @param {Number} AbnormalCheckType 异常登陆校验方式: 1-手机号; 2-邮箱
+	 * @param {String} Username 用户名
+	 * @param {String} Password 密码
+	 * @param {String} Mobile 手机号
+	 * @param {String} Email 邮箱
+	 * @param {String} VerifyCode 手机号/邮箱的验证码
+	 * @returns 
+	 */
+	userLogin:params=>{
+		return http.post('/user_login/login',params)
+	},
+	/**
+	 * 忘记密码账号校验,获取账号信息
+	 * @param {String} CaptchaId 
+	 * @param {String} CaptchaCode 
+	 * @param {String} UserName 
+	 * @returns 
+	 */
+	accountCheck:params=>{
+		return http.post('/user_login/forget/account_get',params)
+	},
+	/**
+	 * 忘记密码-手机/邮箱的验证码校验
+	 * @param {Number} FindType 密码找回方式:1-手机号;2-邮箱
+	 * @param {String} VerifyCode 验证码
+	 * @param {String} UserName 用户名
+	 * @param {String} Mobile 找回方式为手机号时必填
+	 * @param {String} Email 找回方式为邮箱时必填
+	 * @returns 
+	 */
+	checkCodeVerify:params=>{
+		return http.post('/user_login/forget/code_verify',params)
+	},
+	/**
+	 * 忘记密码-重置密码
+	 * @param {String} UserName 
+	 * @param {String} Password 
+	 * @param {String} RePassword 
+	 * @returns 
+	 */
+	resetPass:params=>{
+		return http.post('/user_login/forget/reset_pass',params)
+	},
+	/**
+	 * 获取手机号区号
+	 * @returns 
+	 */
+	getPhoneAreaCode:params=>{
+		return http.get('/user_login/area_code/list',params)
 	}
 }
 

BIN
src/assets/img/home/email_icon.png


BIN
src/assets/img/home/phone_icon.png


+ 2 - 2
src/components/calendar.vue

@@ -347,7 +347,7 @@ export default {
         const {ActivityType,RoadshowType} = this.selectEventInfo
         const {Province,City} = this.selectEventInfo
         //ActivityType为路演时,需要显示的内容
-        const {RoadshowPlatform,CompanyName} = this.selectEventInfo
+        const {RoadshowPlatform,CompanyName,CompanyStatus} = this.selectEventInfo
         const RoadshowContent = [{
             key:'RoadshowPlatform',
             label:'路演平台:',
@@ -361,7 +361,7 @@ export default {
         },{
             key:'CompanyName',
             label:'客户名称:',
-            content:`${CompanyName}`,
+            content:`${CompanyName}${CompanyStatus ? '('+ CompanyStatus + ')' : ''}`,
             RoadshowType:RoadshowType,
         }].filter(item=>item.RoadshowType===RoadshowType)
         //ActivityType为公开会议时,需要显示的内容

+ 47 - 0
src/utils/commonOptions.js

@@ -0,0 +1,47 @@
+
+//验证密码的正则 产品定的规则是:8位及以上,包含数字、大写字母、小写字母、特殊字符中的三个类型
+export const patternPassWord = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/
+export function checkPassWord(pwd){
+    let num = 0
+    const patternArr = [
+        /^(?=.*[0-9])/,
+        /^(?=.*[a-z])/,
+        /^(?=.*[A-Z])/,
+        /^(?=.*[@#$%^&+=.])/,
+    ]
+    patternArr.forEach(pattern=>{
+        if(pattern.test(pwd)){
+            num++
+        }
+    })
+    if(pwd.length<8){
+        num = 0
+    }
+    return num>=3
+}
+//验证手机号的正则 仅支持国内大陆的
+export const patternPhone = /0?(13|14|15|18|17)[0-9]{9}/
+export function isMobileNo(account) {
+    // 手机号正则
+    var isChinaMobile = new RegExp(
+      "(^1(3[4-9]|4[78]|5[0-27-9]|7[28]|8[2-478]|98)\\d{8}$)"
+    ); // 中国移动
+    // 手机段:134,135,136,137,138,139,147,148[卫星通信],150,151,152,157,158,159,172,178,182,183,184,187,188,198
+    var isChinaUnicom = new RegExp(
+      "(^1(3[0-2]|4[56]|5[56]|66|7[156]|8[56])\\d{8}$)"
+    ); // 中国联通
+    // 手机段:130,131,132,145,146[卫星通信],155,156,166,171,175,176,185,186
+    var isChinaTelcom = new RegExp("(^1(33|49|53|7[347]|8[019]|99)\\d{8}$)"); // 中国电信
+    // 手机段:133,149,153,173,174,177,180,181,189,199
+    var isOtherTelphone = new RegExp("(^170\\d{8}$)");
+    // 虚拟运营商170号段
+    if (isChinaMobile.test(account)) {
+      return true;
+    } else if (isChinaUnicom.test(account)) {
+      return true;
+    } else if (isChinaTelcom.test(account)) {
+      return true;
+    } else return isOtherTelphone.test(account);
+  }
+//验证邮箱的正则
+export const patternEmail = /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/

+ 287 - 8
src/views/Login.vue

@@ -3,7 +3,7 @@
 		<div id="login_wrapper">
 			<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
+			<!-- <el-form
 				:model="ruleForm"
 				:rules="rules"
 				ref="ruleForm"
@@ -71,8 +71,70 @@
 						>登录</el-button
 					>
 				</el-form-item>
-			</el-form>
+			</el-form> -->
+			<div class="login-box" id="login-container" v-if="activeModel!=='forgetPassModel'">
+				<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">
+						<OrdinaryModel ref="ordinaryModel"
+							:loginCheck="loginCheck"
+							:accountCheck="accountCheck"
+							@clearnHint="clearnHint"
+							@changeModel="changeModel('forgetPassModel')"
+						/>
+					</el-tab-pane>
+					<el-tab-pane label="手机号登录" name="mobileModel">
+						<MobileModel ref="mobileModel"
+							:areaCode="areaCode"
+						/>
+					</el-tab-pane>
+					<el-tab-pane label="邮箱登录" name="emailModel">
+						<EmailModel ref="emailModel"/>
+					</el-tab-pane>
+				</el-tabs>
+				<el-button
+					type="primary"
+					size="medium"
+					@click.native="handleLogin"
+					:loading="logining"
+					class="submit_btn"
+					>登录</el-button>
+			</div>
+			<div class="login-box" v-else>
+				<ForgetPassModel 
+					ref="forgetPassModel"
+					:autoAccount="$refs.ordinaryModel?$refs.ordinaryModel.form.account:''"
+					@changeModel="changeModel('ordinaryModel')"/>
+			</div>
 		</div>
+		<!-- 验证弹窗 -->
+		<el-dialog
+			class="check-dialog"
+			:visible.sync="isCheckDialogShow"
+			:close-on-click-modal="false"
+			:modal-append-to-body="false"
+			width="30%"
+			@close="isCheckDialogShow = false"
+			>
+			<el-tabs v-model="checkActiveModel" @tab-click="handleClick">
+				<el-tab-pane label="手机号验证" name="checkMobileModel">
+						<MobileModel ref="checkMobileModel"
+							:areaCode="areaCode"
+						/>
+					</el-tab-pane>
+					<el-tab-pane label="邮箱验证" name="checkEmailModel">
+						<EmailModel ref="checkEmailModel"/>
+					</el-tab-pane>
+			</el-tabs>
+			<span slot="footer" class="dialog-footer">
+				<el-button 
+					type="primary" 
+					:loading="checkLogining"
+					@click="submitCheck">提 交</el-button>
+			</span>
+		</el-dialog>
 	</div>
 </template>
 
@@ -80,7 +142,12 @@
 import { userLogin , departInterence } from '@/api/api.js'
 import http from '@/api/http.js'
 import md5 from '@/utils/md5.js'
+import EmailModel from "./login_manage/EmailModel.vue"
+import ForgetPassModel from "./login_manage/ForgetPassModel.vue"
+import MobileModel from "./login_manage/MobileModel.vue"
+import OrdinaryModel from "./login_manage/OrdinaryModel.vue"
 export default {
+	components: { OrdinaryModel, MobileModel, EmailModel, ForgetPassModel },
 	data() {
 		return {
 			b: new http.Base64(),
@@ -107,17 +174,33 @@ export default {
 			},
 			checked: false, //是否保持登录状态
 			visible: true, //密码输入类型
+
+			activeModel: 'ordinaryModel',
+			/* form check 错误提示标识*/
+			loginCheck:false, //账号或密码错误
+			accountCheck:false,//账号异常:多次输错密码、长时间未登录
+			accountForbidden:false,//账号被禁用
+			mobileCheck:false,//手机号未绑定
+			emailCheck:false,//邮箱未绑定
+			areaCode:[],
+
+			isCheckDialogShow:false,
+			checkActiveModel:'checkMobileModel'
 		}
 	},
 	created() {
 		this.keyupSubmit() //回车登录
-		let userAccount = localStorage.getItem('account') || null
+		/* let userAccount = localStorage.getItem('account') || null
 		let userCheckPass = localStorage.getItem('checkPass') || null
 		if (userAccount) {
 			this.ruleForm.account = this.b.decode(userAccount)
 			this.ruleForm.checkPass = this.b.decode(userCheckPass)
 			this.checked = true;
-		}
+		} */
+		this.getPhoneCode();//获取手机号区号
+	},
+	mounted(){
+		this.getRememberedInfo()
 	},
 	methods: {
 		keyupSubmit() {
@@ -125,7 +208,8 @@ export default {
 			document.onkeydown = e => {
 				let keyval = window.event.keyCode
 				if (keyval === 13) {
-					this.handleSubmit2()
+					//this.handleSubmit2()
+					!this.logining&&this.handleLogin()
 				}
 			}
 		},
@@ -221,6 +305,189 @@ export default {
 				}
 				return '/'+pathVal
 			})
+		},
+		getPhoneCode(){
+			departInterence.getPhoneAreaCode().then(res=>{
+				if(res.Ret!==200) return 
+				this.areaCode = res.Data||[]
+			})
+		},
+		handleClick(tab) {
+			//调用对应model的init方法
+			this.$refs[tab.name]&&this.$refs[tab.name].modelInit()
+			this.$refs[tab.name]&&this.$refs[tab.name].$refs.modelForm.clearValidate()
+			if(tab.name==='ordinaryModel'){
+				this.$nextTick(()=>{
+					this.getRememberedInfo()
+				})
+			}
+		},
+		changeModel(model){
+			this.activeModel = model
+			if(model!=='forgetPassModel'){
+				this.$nextTick(()=>{
+					this.getRememberedInfo()
+				})
+			}
+		},
+		handleLogin(){
+			//先进行判空的表单验证
+			this.$refs[this.activeModel].$refs.modelForm.validate((valid)=>{
+				if(valid){
+					this.logining = true
+					//根据activeName 调用不同的登陆接口
+					//账号密码
+						if(this.activeModel==='ordinaryModel'){
+							this.ordinaryModelLogin()
+						}
+					//手机号登录
+						if(this.activeModel==='mobileModel'){
+							this.mobileModelLogin()
+						}
+					//邮箱登录
+						if(this.activeModel==='emailModel'){
+							this.emailModelLogin()
+						}
+				}
+			})
+		},
+		submitCheck(){
+			this.$refs[this.checkActiveModel].$refs.modelForm.validate((valid)=>{
+				if(valid){
+					this.checkLogining = true
+					if(this.checkActiveModel==='checkMobileModel'){
+						this.mobileModelLogin('checkMobileModel')
+					}else{
+						this.emailModelLogin('checkEmailModel')
+					}
+				}
+			})
+		},
+		ordinaryModelLogin(){
+			const {account,checkPass,checked} = this.$refs.ordinaryModel.form
+			departInterence.userLogin({
+				LoginType:1,
+				Username:account,
+				Password:md5.hex_md5(checkPass)
+			}).then(res=>{
+				//this.logining = false
+				//账号异常 将accountCheck置为true
+				if(res.Ret===4011){
+					this.accountCheck = true
+					this.isCheckDialogShow = true
+					this.$nextTick(()=>{
+						this.$refs[this.checkActiveModel].getCodePic()
+					})
+				}
+				//账号密码错误 将loginCheck置为true
+				if(res.Ret===4012){
+					this.loginCheck = true
+				}
+				if(res.Ret!==200){
+					this.logining = false
+					return 
+				}
+				//登录成功,若设置了保存密码,在localStorage内存储一个时间戳
+				if(checked){
+					this.setLoginDate(1)
+					localStorage.setItem("account", this.b.encode(account));
+					localStorage.setItem("checkPass", this.b.encode(checkPass));
+				}else {
+					this.setLoginDate(0)
+					localStorage.removeItem("account");
+					localStorage.removeItem("checkPass");
+				}
+				this.setLoginInfo(res)
+				this.loginSys(res)
+			})
+		},
+		mobileModelLogin(model='mobileModel'){
+			const {mobile,checkCode} = this.$refs[model].form
+			departInterence.userLogin({
+				LoginType:2,
+				Mobile:mobile,
+				VerifyCode:checkCode
+			}).then(res=>{
+				if(res.Ret!==200){
+					//刷新图形验证码
+					this.$refs[model].getCodePic()
+					this.$refs[model].form.picCode = ''
+					model==='mobileModel'&&(this.logining = false)
+					model!=='mobileModel'&&(this.checkLogining = false)
+					return
+				}
+				this.setLoginInfo(res)
+				this.loginSys(res)
+			})
+		},
+		emailModelLogin(model='emailModel'){
+			const {email,checkCode} = this.$refs[model].form
+			departInterence.userLogin({
+				LoginType:3,
+				Email:email,
+				VerifyCode:checkCode
+			}).then(res=>{
+				if(res.Ret!==200){
+					//刷新图形验证码
+					this.$refs[model].getCodePic()
+					this.$refs[model].form.picCode = ''
+					model==='emailModel'&&(this.logining = false)
+					model!=='emailModel'&&(this.checkLogining = false)
+					return
+				}
+				this.setLoginInfo(res)
+				this.loginSys(res)
+			})
+		},
+		clearnHint(){
+			this.loginCheck = false
+			this.accountCheck = false
+		},
+		setLoginDate(type){
+			if(type===0){
+				localStorage.removeItem('timeKey')
+			}else{
+				localStorage.setItem('timeKey',Date.now())
+			}
+
+		},
+		//判断timeKey有没有过期,目前设定的是60天,也就是5184000秒
+		checkTimeKey(timeKey){
+			const nowKey = Date.now()
+			return Math.floor((nowKey-timeKey)/1000)<5184000
+		},
+		//存储登录的信息
+		setLoginInfo(res){
+			localStorage.setItem("auth", res.Data.Authorization);
+			localStorage.setItem("userName", res.Data.RealName);
+			localStorage.setItem("Role", res.Data.RoleTypeCode);
+			localStorage.setItem("RoleIdentity", res.Data.SysRoleTypeCode);
+			localStorage.setItem("RoleType", res.Data.ProductName);
+			localStorage.setItem("ManageType", res.Data.Authority);
+			localStorage.setItem("AdminId", res.Data.AdminId);
+			localStorage.setItem("AdminName", res.Data.AdminName);
+		},
+		//根据角色判断应该进入系统的哪个页面,进入系统
+		async loginSys(res){
+			let path = await this.getOtherRolePath('myCalendar');
+			path&&this.$router.push({ path });
+			this.loading = false
+			this.checkLogining = false
+		},
+		//获取用户记住的账号密码 如果有
+		getRememberedInfo(){
+			const timeKey = localStorage.getItem("timeKey")
+			if(timeKey&&this.checkTimeKey(Number(timeKey))){
+				let userAccount = localStorage.getItem("account") || null;
+				let userCheckPass = localStorage.getItem("checkPass") || null;
+				if (userAccount) {
+					this.$refs.ordinaryModel.form = {
+						account:this.b.decode(userAccount),
+						checkPass:this.b.decode(userCheckPass),
+						checked:true
+					}
+				}
+			}
 		}
 	},
     destroyed(){
@@ -228,7 +495,19 @@ export default {
     }
 }
 </script>
-
+<style lang="scss">
+#login{
+	.el-tabs__nav {
+		width: 100%;
+		display: flex;
+	}
+	.el-tabs__item{
+		font-size: 18px;
+		flex: 1;
+		text-align: center;
+	}
+}
+</style>
 <style lang="scss" scoped>
 #login {
 	width: 100%;
@@ -262,7 +541,7 @@ export default {
 			width: 8%;
 		}
 
-		#login-container {
+		#login-container,.login-box{
 			width: 31%;
 			max-width: 570px;
 			box-sizing: border-box;
@@ -280,7 +559,7 @@ export default {
 			}
 			.submit_btn {
 				width: 100%;
-				height: 40px;
+				height: 50px;
 				background: #007eff;
 				font-size: 16px;
 				border-radius: 5px;

+ 14 - 22
src/views/custom_manage/compontents/ProductReadInfo.vue

@@ -11,13 +11,9 @@
     <div class="dialog-container">
       <div class="table-info-wrap">
         <div class="table-info">
-          <p  v-if="tableName!=='Total'">{{typeName}}</p>
+          <p>{{typeName}}</p>
           <p>共{{clickToal}}个点击量</p>
         </div>
-        <!-- <div class="btn">
-          <el-button size="mini" type="primary" 
-            v-if="tableName!=='Total'"
-            @click="changeTable({type:'Total'})">返回</el-button></div> -->
       </div>
       <el-table
         :data="tableData"
@@ -34,7 +30,7 @@
             :sortable="item.propName==='VisitCount'"
         >
         <template slot-scope="{row}">
-          <span v-if="item.propName==='VisitCount'" :class="tableName==='Total'&&row[item.propName]>0?'editsty':''">{{row[item.propName]||'0'}}</span>
+          <span v-if="item.propName==='VisitCount'" class="editsty">{{row[item.propName]||'0'}}</span>
           <span v-else-if="item.propName==='Source'">{{row[item.propName]===1?'小程序':'PC端'}}</span>
           <span v-else>{{row[item.propName]||'--'}}</span>
         </template>
@@ -61,10 +57,17 @@ const totalColumn = [
   {
     label:'产品名称',
     propName:'ProductName',
+  },{
+    label:'标题',
+    propName:'Title',
   },{
     label:'点击量',
     propName:'VisitCount',
     widthsty:100
+  },{
+    label:'来源',
+    propName:'Source',
+    widthsty:100
   },{
     label:'最近一次点击时间',
     propName:'RecentTime'
@@ -174,7 +177,8 @@ export default {
         const typeMap = {
           1:'VoicePlay',
           2:'Video',
-          3:'Question'
+          3:'Question',
+          99:'Total',
         }
         this.choosedItem = {
           ProductType: Number(subProductArr[0]),
@@ -191,11 +195,7 @@ export default {
       this.tableName = tableName
       this.tableColumn = columnMap[tableName]
       this.pageNo = 1
-      // if(tableName==='Total'){
-      //   this.getTotalReadInfo()
-      // }else{
-        this.getReadInfoDetail()
-      // }
+      this.getReadInfoDetail()
     },
     //关闭弹窗
     cancelHandle(){
@@ -223,11 +223,7 @@ export default {
     //点击页码
     handleCurrentChange(pageNo){
       this.pageNo = pageNo
-      if(this.tableName==='Total'){
-        this.getTotalReadInfo()
-      }else{
-        this.getReadInfoDetail()
-      }
+      this.getReadInfoDetail()
     },
     //获取总的阅读统计
     async getTotalReadInfo(orderType){
@@ -275,11 +271,7 @@ export default {
     sortChangeHandle({ prop,order }){
       const orderType = order==='ascending'?1:order==='descending'?2:0
       this.pageNo = 1
-      if(this.tableName==='Total'){
-        this.getTotalReadInfo(orderType)
-      }else{
-        this.getReadInfoDetail(orderType)
-      }
+      this.getReadInfoDetail(orderType)
     }
   },
   mounted(){}

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

@@ -627,9 +627,9 @@
 		<product-read-info
 		:productReadInfoShow="productReadInfoShow"
 		:productReadId="productReadId"
-				:subProductId="platform_type"
-				:subProductName="subProductName"
-				:clickToal="clickToal"
+		:subProductId="platform_type"
+		:subProductName="subProductName"
+		:clickToal="clickToal"
 		:productReadTitle="productReadTitle"
 		@close="productReadInfoShow=false"
 		></product-read-info>
@@ -1508,7 +1508,7 @@ export default {
 
 		/* 获取分产品的几种类型 */
 		getSubProductList() {
-			customInterence.getSubProduct().then(res => {
+			customInterence.getSubProduct({StatisticFlag:true}).then(res => {
 				if(res.Ret !== 200) return
 				
 				res.Data.forEach(item => {

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

@@ -2080,7 +2080,7 @@ ShareListDialog},
 		// 用于返回按钮名称
 		btnName(btnItem,row){
 			if(btnItem!=='BtnSuspend' && btnItem!=='BtnShare') return this.btnCommandList[btnItem]
-			if(btnItem=='BtnSuspend') return row.isSuspend===1?'启用':'暂停'
+			if(btnItem=='BtnSuspend') return row.IsSuspend===1?'启用':'暂停'
 			if(btnItem=='BtnShare') return row.IsShare===1?'取消共享':'设置共享'
 		},
 		// 设置/取消 共享

+ 139 - 0
src/views/login_manage/EmailModel.vue

@@ -0,0 +1,139 @@
+<template>
+    <div class="email-model-wrap model-wrap">
+        <el-form 
+            ref="modelForm" 
+            label-position="right" 
+            label-width="0px"
+            :model="form"
+            :rules="rules">
+            <el-form-item prop="email">
+                <el-input
+                    type="text"
+                    v-model="form.email"
+                    auto-complete="off"
+                    placeholder="请输入邮箱"
+                >
+                </el-input>
+                <span class="inline-message el-form-item__error" 
+                    v-show="(emailCheck||accountForbidden)&&form.email.length">
+                    {{hintMessage}}
+                </span>
+            </el-form-item>
+            <el-form-item prop="picCode">
+                <el-input
+                    class="input-with-slot"
+                    type="text"
+                    v-model="form.picCode"
+                    auto-complete="off"
+                    placeholder="请输入图形验证码"
+                >
+                    <div class="pic-box" slot="append" @click="getCodePic">
+                        <img :src="picSrc" alt="图形验证码"/>
+                    </div>
+                </el-input>
+            </el-form-item>
+            <el-form-item prop="checkCode" class="code-input">
+                <el-input
+                    type="text"
+                    v-model="form.checkCode"
+                    auto-complete="off"
+                    placeholder="请输入验证码"
+                ></el-input>
+                <el-button type="text" class="code-btn" @click="checkForm" :disabled="codeCountDown<60&&codeCountDown>0">{{codeStr}}</el-button>
+            </el-form-item>
+        </el-form>
+    </div>
+</template>
+
+<script>
+import modelMixins from './modelMixins';
+import {patternEmail} from '@/utils/commonOptions'
+import {departInterence} from "@/api/api.js";
+export default {
+    mixins:[modelMixins],
+    props:{
+        emailCheck:{
+            type:Boolean,
+            default:false
+        },
+        accountForbidden:{
+            type:Boolean,
+            default:false
+        },
+        Source:{//请求验证码来源:1登陆
+            type:Number,
+            default:1
+        }
+    },
+    data() {
+        return {
+            hasPicCode:true,
+            picSrc:'',
+            picId:'',
+            timer:0,
+            codeStr:'获取验证码',
+            codeCountDown:60,
+            form:{
+                email:'',
+                picCode:'',
+                checkCode:''
+            },
+            rules:{
+                email:[
+                    {required:true,message:'请输入邮箱',trigger:'blur'},
+                    {validator:(rule,value,callback)=>{
+                        if(!patternEmail.test(value)){
+                            callback(new Error("请输入正确的邮箱格式"))
+                        }else{
+                            callback()
+                        }
+                    },trigger:'blur'}
+                ],
+                picCode:[{required:true,message:'请输入图形验证码',trigger:'blur'}],
+                checkCode:[{required:true,message:'请输入短信验证码',trigger:'blur'}]
+            },
+            hintMessage:''
+        };
+    },
+    methods: {
+        checkForm(){
+            //首先检查是否是重新获取验证码
+            if(this.codeStr==='重新获取'){
+                //引导用户重新输入图形验证码
+                this.getCodePic()
+                this.form.picCode = ''
+            }
+            //检查邮箱和图形验证码是否正确
+            const {email,picCode} = this.form
+            if(!picCode.length){
+                this.$message.warning('请输入图形验证码')
+                return
+            }
+            if(!patternEmail.test(email)){
+                this.$message.warning('请输入正确的邮箱')
+                return
+            }
+            //通过请求发送验证码
+            departInterence.getCodeVerify({
+                VerifyType:2,
+                CaptchaId:this.picId,
+                CaptchaCode:picCode,
+                Email:email,
+                Source:this.Source
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success('验证码已发送')
+                //60秒倒计时
+                this.countDown()
+                this.timer = setInterval(()=>{
+                    this.countDown()
+                },1000)
+            })
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+@import "./css/formStyle.scss";
+</style>

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

@@ -0,0 +1,339 @@
+<template>
+    <div class="forget-pass-model">
+        <div class="header-nav" @click="changeModel">
+            <span><i class="el-icon-back"></i></span>
+            <span>忘记密码</span>
+        </div>
+        <div class="step-container model-wrap" v-show="currentStep===0">
+            <el-form 
+                ref="modelForm" 
+                label-position="right" 
+                label-width="0px"
+                :model="form"
+                :rules="rules">
+                <el-form-item prop="account">
+                    <el-input
+                        type="text"
+                        v-model="form.account"
+                        auto-complete="off"
+                        placeholder="请输入账号">
+                    </el-input>
+                </el-form-item>
+                <el-form-item prop="picCode">
+                    <el-input
+                        class="input-with-slot"
+                        type="text"
+                        v-model="form.picCode"
+                        auto-complete="off"
+                        placeholder="请输入图形验证码"
+                    >
+                        <div class="pic-box" slot="append" @click="getCodePic">
+                            <img :src="picSrc" alt="图形验证码"/>
+                        </div>
+                    </el-input>
+                </el-form-item>
+            </el-form>
+            <el-button class="submit_btn" @click="getUserInfo">下一步</el-button>
+        </div>
+        <div class="step-container" v-show="currentStep>0">
+            <div class="container-header">
+                <p>您正在找回账号{{form.account}}的密码</p>
+                <ModelSteps :active-step="currentStep"/>
+            </div>
+            <div class="container-inner model-wrap" v-show="currentStep===1">
+                <VerificationBox
+                    verifies-type="mobile"
+                    :info-text="userMobile||'暂未绑定'"
+                    :hideBtn="!userMobile"
+                    @goNext="getCode"
+                />
+                <VerificationBox
+                    verifies-type="email"
+                    :info-text="userEmail||'暂未绑定'"
+                    :hideBtn="!userEmail"
+                    @goNext="getCode"
+                />
+            </div>
+            <div class="container-inner" v-show="currentStep===2">
+                <CaptchaInput 
+                    ref="captInput"
+                />
+                <div class="btn-wrap">
+                    <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 
+                    ref="passForm" 
+                    label-position="right" 
+                    label-width="0px"
+                    :model="passForm"
+                    :rules="passRules">
+                    <el-form-item prop="pass1">
+                        <el-input
+                            type="password" show-password
+                            v-model.trim="passForm.pass1"
+                            auto-complete="off"
+                            @copy.native.capture.prevent="()=>{return false}"
+                            @cut.native.capture.prevent="()=>{return false}"
+                            @paste.native.capture.prevent="()=>{return false}"
+                            placeholder="请输入新密码">
+                        </el-input>
+                    </el-form-item>
+                    <el-form-item prop="pass2">
+                        <el-input
+                            type="password" show-password
+                            v-model.trim="passForm.pass2"
+                            auto-complete="off"
+                            @copy.native.capture.prevent="()=>{return false}"
+                            @cut.native.capture.prevent="()=>{return false}"
+                            @paste.native.capture.prevent="()=>{return false}"
+                            placeholder="请确认新密码">
+                        </el-input>
+                    </el-form-item>
+                </el-form>
+                <el-button class="submit_btn" @click="handleResetPass">{{checkPassStr}}</el-button>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import CaptchaInput from './components/CaptchaInput.vue';
+import ModelSteps from './components/ModelSteps.vue';
+import VerificationBox from './components/VerificationBox.vue';
+import modelMixins from './modelMixins';
+import{checkPassWord} from '@/utils/commonOptions';
+import http from '@/api/http.js';
+import {departInterence } from "@/api/api.js";
+export default {
+    mixins:[modelMixins],
+    props:{
+        autoAccount:{//自动填写的账号,如果有,作为form.accout的初始值
+            type:String,
+            default:''
+        }
+    },
+    components: { VerificationBox, ModelSteps, CaptchaInput },
+    data() {
+        const validatePass = (rule,value,callback)=>{
+            if(value===''){
+                callback(new Error('请输入新密码'))
+            }
+            if(this.passForm.pass2!==''){
+                this.$refs.passForm.validateField('pass2')
+            }
+            if(!checkPassWord(value)){
+                callback(new Error('密码要求8位及以上,包含数字、大写字母、小写字母、特殊字符中的三个类型'))
+            }else{
+                callback()
+            }
+        }
+        const validateCheck = (rule,value,callback)=>{
+            if(value===''){
+                callback(new Error('请输入确认密码'))
+            }else if(value!==this.passForm.pass1){
+                callback(new Error('两次输入的密码不一致,请检查'))
+            }else{
+                callback()
+            }
+        }
+        return {
+            currentStep:0,
+            /* form */
+            form:{//步骤0的表单
+                account:this.autoAccount,
+                picCode:''
+            },
+            picSrc:'',
+            picId:'',
+            passForm:{//设置新密码的表单
+                pass1:'',
+                pass2:''
+            },
+            /* form rule */
+            rules:{},
+            passRules:{
+                pass1:[{validator: validatePass,trigger: 'blur'}],
+                pass2:[{validator: validateCheck,trigger: 'blur'}]
+            },
+            /*user info */
+            userMobile:'',//用户的手机号
+            TelAreaCode:'',//用户手机号的区号
+            userEmail:'',//用户的邮箱
+            /* check way */
+            checkWay:'',//选择的验证方式
+            authCode:'',//手机/邮箱验证码,从CaptchaInput组件中取
+            mobileCountDown:0,//手机获取验证码倒计时
+            emailCountDown:0,//邮箱验证码倒计时
+            checkPassStr:'确定',//重置密码按钮
+            countDownNum:5,
+            resetPassTimer:0,
+        };
+    },
+    created(){
+        this.getCodePic()
+    },
+    methods: {
+        //获取用户账号信息
+        getUserInfo(){
+            //检查form是否填写完整
+            const {account,picCode} = this.form
+            if(!account){
+                this.$message.warning('请输入账号')
+                return
+            }
+            if(!picCode){
+                this.$message.warning('请输入图形验证码')
+                return
+            }
+            //请求接口获取账号数据,赋值userMobile,userEmail
+            departInterence.accountCheck({
+                CaptchaId:this.picId,
+                CaptchaCode:picCode,
+                UserName:account
+            }).then(res=>{
+                if(res.Ret!==200){
+                    //刷新图形验证码
+                    this.getCodePic()
+                    this.form.picCode=''
+                    return
+                }
+                if(res.Data){
+                    this.userMobile = res.Data.Mobile||''
+                    this.userEmail = res.Data.Email||''
+                    this.TelAreaCode = res.Data.TelAreaCode||''
+                    this.goSteps()
+                }
+                
+            })
+        },
+        //获取对应验证方式的验证码
+        getCode(way){
+            this.checkWay = way
+            departInterence.getCodeVerify({
+                VerifyType:way==='mobile'?1:2,
+                CaptchaId:this.picId,
+                CaptchaCode:this.form.picCode,
+                Mobile:way==='mobile'?this.userMobile:'',
+                TelAreaCode:way==='mobile'?this.TelAreaCode:'',
+                Email:way==='email'?this.userEmail:'',
+                Source:3
+            }).then(res=>{
+                if(res.Ret!==200) return
+                /* //60秒倒计时
+                this.countDown()
+                this.timer = setInterval(()=>{
+                    this.countDown()
+                },1000)
+                this.goSteps() */
+                this.goSteps()
+            })
+        },
+        //检查输入的验证码
+        checkInput(){
+            const code = this.$refs.captInput.captchas.map((x) => x.num).join("");
+            if(code.length!==6){
+                this.$message.warning('请输入完整的验证码')
+                return
+            }
+            departInterence.checkCodeVerify({
+                FindType:this.checkWay==='mobile'?1:2,
+                VerifyCode:code,
+                UserName:this.form.account,
+                Mobile:this.checkWay==='mobile'?this.userMobile:'',
+                Email:this.checkWay==='email'?this.userEmail:''
+            }).then(res=>{
+                if(res.Ret!==200) return
+                this.goSteps()
+            })
+
+        },
+        goSteps(){
+            this.currentStep++
+        },
+        changeModel(){
+            if(this.currentStep>0){
+                this.currentStep--
+                if(this.currentStep===0){
+                    this.getCodePic()
+                    this.form.picCode = ''
+                }
+            }else{
+                this.$emit('changeModel')
+            }
+            
+        },
+        handleResetPass(){
+            if(this.checkPassStr.includes('去登陆')){
+                this.$emit('changeModel')
+                return
+            }
+            this.$refs.passForm.validate((valid)=>{
+                if(valid){
+                    //重置密码
+                    departInterence.resetPass({
+                        UserName:this.form.account,
+                        Password:new http.Base64().encode(this.passForm.pass1),
+                        RePassword:new http.Base64().encode(this.passForm.pass2)
+                    }).then(res=>{
+                        if(res.Ret!==200) return
+                        this.$message.success('重置密码成功,请登陆')
+                        this.resetPassCountDown()
+                        this.resetPassTimer = setInterval(()=>{
+                            this.resetPassCountDown()
+                        },1000)
+                    })
+                }
+            })
+        },
+        resetPassCountDown(){
+            this.countDownNum--
+            this.checkPassStr = `去登陆(${this.countDownNum}s)`
+            if(this.countDownNum<=0){
+                clearInterval(this.resetPassTimer)
+                this.$emit('changeModel')
+                return
+            }
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+@import "./css/formStyle.scss";
+</style>
+<style scoped lang="scss">
+.forget-pass-model{
+    .header-nav{
+        font-size: 38px;
+        margin-bottom: 60px;
+        cursor: pointer;
+    }
+    .step-container{
+        .container-header{
+            margin-bottom: 60px;
+            p{
+               font-size: 18px;
+               padding-bottom: 20px;
+               border-bottom: 1px solid #DCDFE6; 
+               margin-bottom: 60px;
+            }
+            .el-steps{
+                margin-top: 60px;
+            }
+        }
+        .container-inner{
+            .btn-wrap{
+                margin-top: 100px;
+                text-align: center;
+                .el-button{
+                    width:200px;
+                }
+            }
+        }
+    }
+}
+</style>

+ 156 - 0
src/views/login_manage/MobileModel.vue

@@ -0,0 +1,156 @@
+<template>
+    <div class="mobile-model-wrap model-wrap">
+        <el-form 
+            ref="modelForm" 
+            label-position="right" 
+            label-width="0px"
+            :model="form"
+            :rules="rules">
+            <el-form-item prop="mobile">
+                <el-input
+                    class="input-with-slot"
+                    type="text"
+                    v-model="form.mobile"
+                    auto-complete="off"
+                    placeholder="请输入手机号"
+                >
+                    <el-select v-model="areaCodeSelect" slot="prepend" placeholder="请选择">
+                        <el-option v-for="item in areaCode" :key="item.Value"
+                            :label="item.Name" :value="item.Value" />
+                    </el-select>
+                </el-input>
+                <span class="inline-message el-form-item__error" 
+                    v-show="(mobileCheck||accountForbidden)&&form.mobile.length">
+                    {{hintMessage}}
+                </span>
+            </el-form-item>
+            <el-form-item prop="picCode">
+                <el-input
+                    class="input-with-slot"
+                    type="text"
+                    v-model="form.picCode"
+                    auto-complete="off"
+                    placeholder="请输入图形验证码"
+                >
+                    <div class="pic-box" slot="append" @click="getCodePic">
+                        <img :src="picSrc" alt="图形验证码"/>
+                    </div>
+                </el-input>
+            </el-form-item>
+            <el-form-item prop="checkCode" class="code-input">
+                <el-input
+                    type="text"
+                    v-model="form.checkCode"
+                    auto-complete="off"
+                    placeholder="请输入验证码">
+                </el-input>
+                <el-button type="text" class="code-btn" @click="checkForm" :disabled="codeCountDown<60&&codeCountDown>0">{{codeStr}}</el-button>
+            </el-form-item>
+        </el-form>
+    </div>
+</template>
+
+<script>
+import modelMixins from './modelMixins';
+import {isMobileNo} from '@/utils/commonOptions'
+import {departInterence } from "@/api/api.js";
+export default {
+    mixins:[modelMixins],
+    props:{
+        mobileCheck:{
+            type:Boolean,
+            default:false
+        },
+        accountForbidden:{
+            type:Boolean,
+            default:false
+        },
+        areaCode:{
+            type:Array,
+            default:()=>{return []}
+        },
+        Source:{//请求验证码来源:1登陆
+            type:Number,
+            default:1
+        }
+    },
+    data() {
+        return {
+            hasPicCode:true,//是否需要图形验证码
+            areaCodeSelect:'86',
+            picSrc:'',//图形验证码地址
+            picId:'',//图形验证码id
+            timer:0,
+            codeStr:'获取验证码',
+            codeCountDown:60,
+            form:{
+                mobile:'',
+                picCode:'',
+                checkCode:''
+            },
+            rules:{
+                mobile:[
+                    {required: true,message: "请输入手机号",trigger: "blur"},
+                    {validator:(rule,value,callback)=>{
+                        if(this.areaCodeSelect==='86'&&!isMobileNo(value)){
+                            callback(new Error('请输入正确的手机号格式'));
+                        }else if(this.areaCodeSelect!=='86'&&isNaN(value.trim())){
+                            callback(new Error('请输入正确的手机号格式'));
+                        }else{
+                            callback()
+                        }
+                    },trigger:'blur'}
+                ],
+                picCode:[{required:true,message:'请输入图形验证码',trigger:'blur'}],
+                checkCode:[{required:true,message:'请输入短信验证码',trigger:'blur'}]
+            }
+        };
+    },
+    methods: {
+        checkForm(){
+            //首先检查是否是重新获取验证码
+            if(this.codeStr==='重新获取'){
+                //引导用户重新输入图形验证码
+                this.getCodePic()
+                this.form.picCode = ''
+            }
+            //检查手机号和图形验证码是否正确
+            const {picCode,mobile} = this.form
+            if(!picCode.length){
+                this.$message.warning('请输入图形验证码')
+                return
+            }
+            if(this.areaCodeSelect==='86'&&!isMobileNo(mobile)){
+                this.$message.warning('请输入正确的手机号')
+                return
+            }
+            /* this.countDown()
+                this.timer = setInterval(()=>{
+                    this.countDown()
+                },1000) */
+            //通过请求发送验证码
+            departInterence.getCodeVerify({
+                VerifyType:1,
+                CaptchaId:this.picId,
+                CaptchaCode:picCode,
+                Mobile:mobile,
+                TelAreaCode:this.areaCodeSelect,
+                Source:this.Source
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success('验证码已发送')
+                //60秒倒计时
+                this.countDown()
+                this.timer = setInterval(()=>{
+                    this.countDown()
+                },1000)
+            })
+
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+@import "./css/formStyle.scss";
+</style>

+ 117 - 0
src/views/login_manage/OrdinaryModel.vue

@@ -0,0 +1,117 @@
+<template>
+    <div class="ordinary-model-wrap model-wrap">
+        <el-form 
+            ref="modelForm" 
+            label-position="right" 
+            label-width="0px"
+            :model="form"
+            :rules="rules">
+            <el-form-item prop="account">
+                <el-input
+                    type="text"
+                    v-model="form.account"
+                    auto-complete="off"
+                    placeholder="请输入用户名"
+                />
+                <span class="inline-message el-form-item__error" 
+                    v-show="(loginCheck||accountCheck)&&form.account.length">
+                    {{hintMessage}}
+                </span>
+            </el-form-item>
+            <el-form-item prop="checkPass">
+                <el-input
+                    type="password" show-password
+                    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 class="inline-message el-form-item__error" 
+                    v-show="(loginCheck||accountCheck)&&form.checkPass.length">
+                    {{hintMessage}}</span>
+            </el-form-item>
+            <el-form-item class="remember-cont" prop="checked">
+                <el-checkbox v-model="form.checked" class="remember">
+                    记住账号密码
+                    <el-tooltip effect="dark" content="有效期60天" placement="top">
+                        <span class="hint-text">
+                            <i class="el-icon-question"></i>
+                        </span>
+                    </el-tooltip>
+                </el-checkbox>
+                <el-button type="text" style="font-size: 16px;" @click="changeModel">忘记密码</el-button>
+            </el-form-item>
+        </el-form>
+    </div>
+</template>
+
+<script>
+import modelMixins from './modelMixins';
+export default {
+    mixins:[modelMixins],
+    props:{
+        loginCheck:{
+            type:Boolean,
+            default:false
+        },
+        accountCheck:{
+            type:Boolean,
+            default:false
+        }
+    },
+    data() {
+        const validateClearn = (rule,value,callBack)=>{
+            if(this.loginCheck||this.accountCheck){
+                this.$emit('clearnHint')
+            }
+            callBack()
+        }
+        return {
+            form:{
+                account:'',
+                checkPass:'',
+                checked:false
+            },
+            rules:{
+                account:[
+                    {required: true,message: "请输入账号",trigger: "blur"},
+                    {validator:validateClearn,trigger:['change']}
+                ],
+                checkPass:[
+                    {required: true,message: "请输入密码",trigger: "blur"},
+                    {validator:validateClearn,trigger:['change']}
+                ]
+            },
+            hintMessage:''
+        };
+    },
+    watch:{
+        loginCheck(newVal){
+            //显示/隐藏inline-message
+            if(newVal){
+                this.hintMessage="账号或密码错误"
+            }else{
+                this.hintMessage=''
+            }
+        },
+        accountCheck(newVal){
+            if(newVal){
+                this.hintMessage="账号异常,请通过验证登录"
+            }else{
+                this.hintMessage=''
+            }
+        }
+    },
+    methods: {
+        changeModel(){
+            this.$emit('changeModel')
+        }
+    },
+};
+</script>
+
+<style scoped lang="scss">
+@import "./css/formStyle.scss";
+</style>

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

@@ -0,0 +1,108 @@
+<template>
+    <!-- 格子验证码输入组件 -->
+    <div class="row-center captcha_input_wrap">
+        <input
+            v-for="(item, index) in captchas"
+            :key="index"
+            v-model="item.num"
+            :id="'captcha' + index"
+            @input="inputFinash(index)"
+            @focus="adjust(index)"
+            @keydown="(e)=>{inputDirection(index,e)}"
+            class="captcha_input_box row-center"
+            :class="[index <= activeInput ? 'active' : '']"
+            type="tel"
+            maxlength="1"
+        />
+  </div>
+</template>
+  
+  <script>
+export default {
+  data() {
+    return {
+      // 当前输入框
+      activeInput: 0,
+      captchas: [
+        { num: "" },
+        { num: "" },
+        { num: "" },
+        { num: "" },
+        { num: "" },
+        { num: "" },
+      ],
+    };
+  },
+  //   页面加载后聚焦第一个
+  mounted() {
+    let dom = document.getElementById("captcha" + this.activeInput);
+    dom.focus();
+  },
+ 
+  methods: {
+    // 自动校准输入顺序
+    adjust(index) {
+      let dom = document.getElementById("captcha" + this.activeInput);
+      if (index !== this.activeInput && dom) {
+        dom.focus();
+      }
+    },
+    // 控制前后方向
+    inputDirection(index,e) {
+      let val = this.captchas[index].num;
+      // 回退键处理
+      if (e.key==='Backspace' && val === "") {
+        // 重新校准
+        let dom = document.getElementById("captcha" + (index - 1));
+        this.activeInput = index - 1;
+        if (dom) dom.focus();
+      }
+      if (e.key!=='Backspace' && val !== "") {
+        let dom = document.getElementById("captcha" + (index + 1));
+        this.activeInput = index + 1;
+        if (dom) dom.focus();
+      }
+    },
+    // 输入框相互联动
+    inputFinash(index) {
+      let val = this.captchas[index].num;
+      this.activeInput = val ? index + 1 : index - 1;
+      let dom = document.getElementById("captcha" + this.activeInput);
+      if (dom) dom.focus();
+      if (index == this.captchas.length - 1) {
+        let code = this.captchas.map((x) => x.num).join("");
+        if (code.length == 6) {
+          this.$emit("finish", code);
+        }
+      }
+    },
+  },
+};
+</script>
+  
+<style scoped lang='scss'>
+.row-center {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    align-items: center;
+    gap:40px;
+}
+.captcha_input_wrap {
+    width: 100%;
+}
+.captcha_input_box {
+    width: 40px;
+    height: 40px;
+    background: rgba(255, 255, 255, 1);
+    border-radius: 6px;
+    border: 1px solid #dddddd;
+    font-size: 16px;
+    text-align: center;
+    color: #1e243a;
+    outline: none;
+}
+.active {
+    border: 1px solid #3654C1 !important;
+}
+</style>

+ 99 - 0
src/views/login_manage/components/ModelSteps.vue

@@ -0,0 +1,99 @@
+<template>
+    <ul class="model-step-wrap">
+        <li v-for="(step,index) in stepList" :key="step.text"
+            class="step-item"
+            :class="{'active':index+1===activeStep,'success':index+1<activeStep}"
+        >   
+            <div class="step-line"></div>
+            <div class="step-num" v-if="index+1>=activeStep">{{index+1}}</div>
+            <div class="step-num" v-else><i class="el-icon-check"></i></div>
+            <div class="step-text">{{step.text}}</div>
+            
+        </li>
+    </ul>
+</template>
+
+<script>
+export default {
+    props:{
+        stepList:{
+            type:Array,
+            default:()=>{
+                return [
+                    {text:'选择验证方式'},
+                    {text:'进行安全验证'},
+                    {text:'设置密码'}
+                ]
+            }
+        },
+        activeStep:{
+            type:Number,
+            default:1
+        }
+    },
+    data() {
+        return {
+
+        };
+    },
+    methods: {
+
+    },
+};
+</script>
+
+<style scoped lang="scss">
+.model-step-wrap{
+    display: flex;
+    justify-content: center;
+    width: 100%;
+    .step-item{
+        display: flex;
+        align-items: center;
+        gap: 12px;
+        color: #DCDCDC;
+        font-size: 20px;
+        &:first-child{
+            .step-line{
+                display: none;
+            }
+        }
+        &:last-child{
+            .step-text{
+                margin-right: 0;
+            }
+        }
+        &.active,&.success{
+            color:#3654C1;
+            .step-num{
+                border-color: #3654C1;
+                color: #3654C1;
+            }
+            .step-line{
+                background-color: #3654C1;
+            }
+        }
+        &.success{
+            color: #000;
+        }
+        .step-num{
+            width:24px;
+            height:24px;
+            font-size: 16px;
+            border:1px solid #DCDCDC;
+            border-radius: 50%;
+            text-align: center;
+            line-height: 25px;
+        }
+        .step-line{
+           flex: 1;
+           height:2px;
+           background-color:#DCDCDC ;
+           min-width: 40px;
+        }
+        .step-text{
+            margin-right: 16px;
+        }
+    }
+}
+</style>

+ 79 - 0
src/views/login_manage/components/VerificationBox.vue

@@ -0,0 +1,79 @@
+<template>
+    <div class="verification-box-wrap">
+        <div class="icon">
+            <img :src="verifiesType==='mobile'?mobile_src:email_src" />
+        </div>
+        <div class="text">{{infoText}}</div>
+        <el-button  type="primary" @click="goNext" v-if="!hideBtn" :disabled="countDown">{{countDown?`重发(${countDown}秒)`:btnText}}</el-button>
+    </div>
+</template>
+
+<script>
+export default {
+    props:{
+        verifiesType:{//安全验证 mobile or email
+            type:String,
+            default:'mobile'
+        },
+        infoText:{//手机号或邮箱
+            type:String,
+            default:'123456'
+        },
+        hideBtn:{
+            type:Boolean,
+            default:false
+        },
+        countDown:{
+            type:Number,
+            default:0
+        },
+        btnText:{
+            type:String,
+            default:'开始验证'
+        }
+    },
+    data() {
+        return {
+            mobile_src:require('@/assets/img/home/phone_icon.png'),
+            email_src:require('@/assets/img/home/email_icon.png'),
+        };
+    },
+    methods: {
+        goNext(){
+            this.$emit('goNext',this.verifiesType)
+        }
+    },
+};
+</script>
+
+<style scoped lang="scss">
+.verification-box-wrap{
+    display: flex;
+    align-items: center;
+    margin-bottom: 60px;
+    cursor: pointer;
+    .icon{
+        width:40px;
+        height:40px;
+        box-sizing: border-box;
+        padding:8px;
+        border-radius: 50%;
+        box-shadow: 0px 2px 12px 0px #0000001A;
+        text-align: center;
+        img{
+            width: 24px;
+            height: 24px;
+        }
+    }
+    .text{
+        margin-left: 20px;
+        font-size: 18px;
+    }
+    .el-button{
+        /* background-color: #3654C1;
+        color: #fff; */
+        margin-left: auto;
+    }
+}
+
+</style>

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

@@ -0,0 +1,111 @@
+.model-wrap{
+    margin-top: 25px;
+    .remember-cont{
+        margin-top: -10px;
+        margin-bottom: 60px !important;
+        width: 100%;
+        .hint-text{
+            color: #606266 !important;
+            font-size: 16px;
+        }
+        .el-form-item__content{
+            display: flex;
+            width: 100%;
+            justify-content: space-between;
+            .remember{
+                flex: 1;
+                .el-checkbox__label{
+                    font-size: 16px;
+                }
+            }
+        }
+    }
+    .el-form-item{
+        margin-bottom: 40px;
+        .el-input__inner{
+            height: 50px;
+            border-radius: 8px;
+            font-size: 16px;
+        }
+    }
+    .el-form-item.is-error{
+        .inline-message{
+            display: none;
+        }
+    }
+    .input-with-slot{
+        display: flex;
+        &.el-input-group--prepend{
+            .el-input__inner{
+                border-top-left-radius: 0;
+                border-bottom-left-radius: 0;
+            }
+        }
+        &.el-input-group--append{
+            .el-input__inner{
+                border-top-right-radius: 0;
+                border-bottom-right-radius: 0;
+            }
+        }
+        .el-input__inner{
+            flex: 1;
+            height: 50px !important;
+        }
+        .el-input-group__prepend,.el-input-group__append{
+            padding:0 !important;
+            background-color: #fff;
+            width:110px;
+            height: 50px;
+            box-sizing: border-box;
+            overflow: hidden;
+            .el-input__inner{
+                padding:0;
+            }
+            .el-select{
+                margin:0;
+                width:110px;
+                .el-input__inner{
+                    width:100%;
+                    text-align: center;
+                }
+            }
+        }    
+        .pic-box{
+            cursor: pointer;
+            width:110px;
+            height:50px;
+            overflow: hidden;
+            padding:5px;
+            box-sizing: border-box;
+            background-color: #D7F1F6;
+            img{
+                width: 100%;
+                height: 100%;
+            }
+        }
+        .code{
+            display: inline-block;
+            width:100%;
+            text-align: center;
+            line-height: 40px;
+            cursor: pointer;
+        }
+    }
+    .submit_btn {
+        width: 100%;
+        height: 50px;
+        background: #007eff;
+        font-size: 20px;
+        border-radius: 5px;
+        color: #fff;
+    }
+    .code-input{
+        position:relative;
+        .code-btn{
+            position:absolute;
+            top:5px;
+            right: 20px;
+            font-size: 16px;
+        }
+    }
+}

+ 34 - 0
src/views/login_manage/modelMixins.js

@@ -0,0 +1,34 @@
+import {departInterence } from "@/api/api.js";
+export default {
+    methods:{
+        modelInit(){
+            //重置表单
+            this.form = this.$options.data().form
+            //如果有图形验证码,重新请求
+            this.hasPicCode && this.getCodePic()
+        },
+        //获取图片验证码
+        getCodePic(){
+            //存base64和id
+            departInterence.getCodePic().then(res=>{
+                if(res.Ret!==200) return 
+                if(res.Data){
+                    this.picSrc = res.Data.Base64Blob,
+                    this.picId = res.Data.Id
+                }
+                
+            })
+        },
+        countDown(){
+            /* if(!this.timer) return */
+            console.log('click down')
+            this.codeCountDown--
+            this.codeStr=`重新获取(${this.codeCountDown})秒`
+            if(this.codeCountDown<=0){
+                clearInterval(this.timer)
+                this.codeStr = '重新获取'
+                return
+            }
+        }
+    }
+}

+ 201 - 112
src/views/resetpassword.vue

@@ -1,118 +1,207 @@
 <template>
-	<div>
-		<el-card class="box-card">
-			<div slot="header" class="clearfix">
-				<b>修改密码</b>
-			</div>
-			<el-form :model="addForm" :rules="rules" label-width="120px" ref="addForm" style="width:500px;">
-				<el-form-item label="原密码" prop="OldPwd">
-		          	<el-input type="text" v-model="addForm.OldPwd" placeholder="请输入不超过20个字符" clearable autocomplete="new-password"></el-input>
-		        </el-form-item>
-		        <el-form-item label="新密码" prop="NewPwd" v-if="visible">
-					<el-input type="password" v-model="addForm.NewPwd" placeholder="请输入长度不超过20个字符" maxlength="20" autocomplete="new-password">
-		            	<i slot="suffix" class="el-icon-view el-input__icon" title="显示密码" @click="changePass('show')" style="cursor:pointer;"></i>
-		          	</el-input>
-				</el-form-item>
-				<el-form-item label="新密码" prop="NewPwd" v-else>
-		          	<el-input type="text" v-model="addForm.NewPwd" placeholder="请输入长度不超过20个字符" maxlength="20" autocomplete="new-password">
-		            	<i slot="suffix" class="el-icon-more el-input__icon" title="隐藏密码" @click="changePass('hide')" style="cursor:pointer;"></i>
-		          	</el-input>
-		        </el-form-item>
-				<el-form-item label="确认新密码" prop="twoNewPwd" v-if="twovisible">
-					<el-input type="password" v-model="addForm.twoNewPwd" placeholder="请输入长度不超过20个字符" maxlength="20">
-				    	<i slot="suffix" class="el-icon-view el-input__icon" title="显示密码" @click="changetwoPass('show')" style="cursor:pointer;"></i>
-				  	</el-input>
-				</el-form-item>
-				<el-form-item label="确认新密码" prop="twoNewPwd" v-else>
-				  	<el-input type="text" v-model="addForm.twoNewPwd" placeholder="请输入长度不超过20个字符" maxlength="20">
-				    	<i slot="suffix" class="el-icon-more el-input__icon" title="隐藏密码" @click="changetwoPass('hide')" style="cursor:pointer;"></i>
-				  	</el-input>
-				</el-form-item>
-				<el-form-item style="text-align:center; padding-top:20px;">
-					<el-button type="primary" size="medium" @click.native="addSubmit">确定</el-button>
-					<el-button type="primary" size="medium" plain @click.native="historyBack">返回</el-button>
-				</el-form-item>
-			</el-form>
-		</el-card>
-	</div>
+  <div>
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <b>修改密码</b>
+      </div>
+      <el-form
+        :model="addForm"
+        :rules="rules"
+        label-width="120px"
+        ref="addForm"
+        style="width: 500px"
+      >
+        <el-form-item label="原密码" prop="OldPwd">
+          <el-input
+            type="text"
+            v-model="addForm.OldPwd"
+            placeholder="请输入不超过20个字符"
+            clearable
+            autocomplete="new-password"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="新密码" prop="NewPwd" v-if="visible">
+          <el-input
+            type="password"
+            v-model="addForm.NewPwd"
+            placeholder="请输入长度不超过20个字符"
+            maxlength="20"
+            autocomplete="new-password"
+          >
+            <i
+              slot="suffix"
+              class="el-icon-view el-input__icon"
+              title="显示密码"
+              @click="changePass('show')"
+              style="cursor: pointer"
+            ></i>
+          </el-input>
+        </el-form-item>
+        <el-form-item label="新密码" prop="NewPwd" v-else>
+          <el-input
+            type="text"
+            v-model="addForm.NewPwd"
+            placeholder="请输入长度不超过20个字符"
+            maxlength="20"
+            autocomplete="new-password"
+          >
+            <i
+              slot="suffix"
+              class="el-icon-more el-input__icon"
+              title="隐藏密码"
+              @click="changePass('hide')"
+              style="cursor: pointer"
+            ></i>
+          </el-input>
+        </el-form-item>
+        <el-form-item label="确认新密码" prop="twoNewPwd" v-if="twovisible">
+          <el-input
+            type="password"
+            v-model="addForm.twoNewPwd"
+            placeholder="请输入长度不超过20个字符"
+            maxlength="20"
+          >
+            <i
+              slot="suffix"
+              class="el-icon-view el-input__icon"
+              title="显示密码"
+              @click="changetwoPass('show')"
+              style="cursor: pointer"
+            ></i>
+          </el-input>
+        </el-form-item>
+        <el-form-item label="确认新密码" prop="twoNewPwd" v-else>
+          <el-input
+            type="text"
+            v-model="addForm.twoNewPwd"
+            placeholder="请输入长度不超过20个字符"
+            maxlength="20"
+          >
+            <i
+              slot="suffix"
+              class="el-icon-more el-input__icon"
+              title="隐藏密码"
+              @click="changetwoPass('hide')"
+              style="cursor: pointer"
+            ></i>
+          </el-input>
+        </el-form-item>
+        <el-form-item style="text-align: center;">
+          <el-button type="primary" size="medium" @click.native="addSubmit"
+            >确定</el-button
+          >
+          <el-button
+            type="primary"
+            size="medium"
+            plain
+            @click.native="historyBack"
+            >返回</el-button
+          >
+        </el-form-item>
+      </el-form>
+    </el-card>
+  </div>
 </template>
 
 <script>
-	import { modifyPwd } from '@/api/api.js';
-	import http from "@/api/http.js";
-	import md5 from "@/utils/md5.js";
-	export default {
-		data() {
-			return {
-				visible:true,
-				twovisible:true,
-				addForm:{
-					OldPwd:'',
-					NewPwd:'',
-					twoNewPwd:''
-				},
-				rules: {
-					OldPwd: [{
-						required:true,
-						message:'请输入原密码',
-						trigger:'blur'
-					}],
-					NewPwd: [{
-						required:true,
-						message:'请输入确认密码',
-						trigger:'blur'
-					}],
-					twoNewPwd: [{
-						required:true,
-						message:'请输入确认密码',
-						trigger:'blur'
-					}]
-				}
-			}
-		},
-		mounted() {
-			
-		},
-		methods: {
-			changePass(value){
-	        	this.visible = !(value === 'show');
-	     	},
-			changetwoPass(value){
-				this.twovisible = !(value === 'show');
-			},
-	     	addSubmit(){
-	     		this.$refs.addForm.validate((valid) => {
-					if( valid ){
-						let that=this;
-						if( that.addForm.NewPwd!=that.addForm.twoNewPwd ){
-							that.$message.warning("新密码两次输入不一致,请核对!");
-							return false;
-						}
-						modifyPwd({OldPwd:md5.hex_md5(that.addForm.OldPwd),NewPwd:md5.hex_md5(that.addForm.NewPwd)}).then((res) => {
-							if( res.Ret == 200 ){
-								that.$message.success("修改密码成功,请重新登录!");
-								setTimeout(function(){
-									// http.setCookie({rddp_admin_access_token:'',rddp_user_name:''},function(){},0);
-									localStorage.setItem('auth','');
-									localStorage.setItem('userName','');
-									localStorage.setItem('Role','');
-									localStorage.setItem('RoleType','');
-									localStorage.setItem('AdminId','');
-                  localStorage.setItem('AdminName','')
-									localStorage.setItem('RoleIdentity','')
-									localStorage.setItem('ManageType','');
-									that.$router.push({path:'/login'});
-								},1000);
-							}
-						});
-					}
-				});
-	     	},
-	     	historyBack(){  //返回上一页
-		    	history.back();
-		    }
-		}
-	}
+import { modifyPwd } from "@/api/api.js";
+import http from "@/api/http.js";
+import md5 from "@/utils/md5.js";
+import{checkPassWord} from '@/utils/commonOptions';
+export default {
+  data() {
+    return {
+      visible: true,
+      twovisible: true,
+      addForm: {
+        OldPwd: "",
+        NewPwd: "",
+        twoNewPwd: "",
+      },
+      rules: {
+        OldPwd: [
+          {
+            required: true,
+            message: "请输入原密码",
+            trigger: "blur",
+          },
+        ],
+        NewPwd: [
+            {
+                validator:(rule,value,callback)=>{
+                    if(!checkPassWord(value)){
+                        callback(new Error('密码要求8位及以上,包含数字、大写字母、小写字母、特殊字符中的三个类型'))
+                    }else{
+                        callback()
+                    }
+                }
+            },
+          {
+            required: true,
+            message: "请输入确认密码",
+            trigger: "blur",
+          },
+        ],
+        twoNewPwd: [
+          {
+            required: true,
+            message: "请输入确认密码",
+            trigger: "blur",
+          },
+        ],
+      },
+    };
+  },
+  mounted() {},
+  methods: {
+    changePass(value) {
+      this.visible = !(value === "show");
+    },
+    changetwoPass(value) {
+      this.twovisible = !(value === "show");
+    },
+    addSubmit() {
+      this.$refs.addForm.validate((valid) => {
+        if (valid) {
+          let that = this;
+          if (that.addForm.NewPwd != that.addForm.twoNewPwd) {
+            that.$message.warning("新密码两次输入不一致,请核对!");
+            return false;
+          }
+          modifyPwd({
+            OldPwd: md5.hex_md5(that.addForm.OldPwd),
+            NewPwd: md5.hex_md5(that.addForm.NewPwd),
+          }).then((res) => {
+            if (res.Ret == 200) {
+              that.$message.success("修改密码成功,请重新登录!");
+              setTimeout(function () {
+                localStorage.setItem("auth", "");
+                localStorage.setItem("userName", "");
+                localStorage.setItem("Role", "");
+                localStorage.setItem("RoleType", "");
+                localStorage.setItem("AdminId", "");
+                localStorage.setItem("AdminName", "");
+                localStorage.setItem("RoleIdentity", "");
+                localStorage.setItem("ManageType", "");
+                that.$router.push({ path: "/login" });
+              }, 1000);
+            }
+          });
+        }
+      });
+    },
+    historyBack() {
+      //返回上一页
+      history.back();
+    },
+  },
+};
 </script>
 
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.box-card{
+    .el-form-item{
+        margin-bottom: 40px;
+    }
+}
+</style>

+ 53 - 7
src/views/system_manage/components/addUserDialog.vue

@@ -13,22 +13,29 @@
                 </el-input>
             </el-form-item>
             <el-form-item label="登录密码" prop="pwd" v-if="userForm.title == '添加用户'">
-                <el-input v-model="userForm.pwd" placeholder="6-12位数字与字母的组合" 
+                <el-input v-model.trim="userForm.pwd" placeholder="6-12位数字与字母的组合" 
                     :type="userForm.title == '添加用户' ? 'text' : 'password' " clearable></el-input>
             </el-form-item>
             <el-form-item label="姓名" prop="name">
                 <el-input v-model="userForm.name" placeholder="请输入用户名称"  clearable>
                 </el-input>
             </el-form-item>
-            <el-form-item label="手机号码" prop="mobile">
-                <el-input v-model="userForm.mobile" placeholder="请输入手机号码" clearable>
+            <el-form-item label="手机号码" prop="mobile" class="mobile-input-item">
+                <el-input v-model.trim="userForm.mobile" placeholder="请输入手机号码" clearable class="mobile-input">
                 </el-input>
+                <el-select v-model="userForm.areacode" class="mobile-select" placeholder="请选择">
+                    <el-option v-for="item in areaCode" :key="item.Value"
+                        :label="item.Name" :value="item.Value" />
+                </el-select>
             </el-form-item>
             <el-form-item label="所属部门" prop="depart" v-if="userForm.title == '添加用户'">
                 <el-cascader :options="departArr" v-model="userForm.depart" :props="form_departProp"
                     placeholder="请选择部门分组" clearable>
                 </el-cascader>
             </el-form-item>
+            <el-form-item label="邮箱" prop="email">
+                <el-input v-model="userForm.email" placeholder="请输入邮箱"></el-input>
+            </el-form-item>
             <el-form-item label="工号" prop="employeeNumber">
                 <el-input :disabled="hasEmployeeNo" v-model="userForm.employeeNumber" placeholder="请输入工号"></el-input>
             </el-form-item>
@@ -69,6 +76,7 @@
 
 <script>
 import searchDistPicker from '@/components/searchDistPicker.vue'
+import {patternEmail,isMobileNo,checkPassWord} from '@/utils/commonOptions'
     export default {
         props: {
             isAddUserDialogShow: {
@@ -96,6 +104,10 @@ import searchDistPicker from '@/components/searchDistPicker.vue'
             researchGroup:{
                 type:Array,
                 default:()=>{return []}
+            },
+            areaCode:{
+                type:Array,
+                default:()=>{return []}
             }
         },
         components:{searchDistPicker},
@@ -103,13 +115,33 @@ import searchDistPicker from '@/components/searchDistPicker.vue'
             return {
                 userRule: {
                     account:[{required: true, message: '登录账号不能为空', trigger: 'blur'}],
-                    pwd:[{ required: true, message: '登录密码不能为空', trigger: 'blur' }],
+                    pwd:[{validator:(rule,value,callback)=>{
+                        if(value===''){
+                            callback(new Error('请输入新密码'))
+                        }
+                        if(!checkPassWord(value)){
+                            callback(new Error('密码要求8位及以上,包含数字、大写字母、小写字母、特殊字符中的三个类型'))
+                        }else{
+                            callback()
+                        }
+                    }}],
                     name:[{ required: true, message: '姓名不能为空', trigger: 'blur' }],
                     mobile:[{ validator: (rule, value, callback) => {
-                        if (value === '') {
-                            callback(new Error('手机号码不能为空'));
-                        }else if(isNaN(value.trim())) {
+                        if (value === ''&&!this.userForm.email) {
+                            callback(new Error('手机号码和邮箱至少填一个'));
+                        }else if(value&&this.userForm.areacode==='86'&&!isMobileNo(value)) {
                             callback(new Error('请输入正确的手机号格式'));
+                        } else if(this.userForm.areacode!=='86'&&isNaN(value.trim())){
+                            callback(new Error('请输入正确的手机号格式'));
+                        }else {
+                            callback();
+                        }
+                    }, trigger: 'blur'}],
+                    email:[{ validator: (rule, value, callback) => {
+                        if (value === ''&&!this.userForm.mobile) {
+                            callback(new Error('手机号码和邮箱至少填一个'));
+                        }else if(value&&!patternEmail.test(value)) {
+                            callback(new Error('请输入正确的邮箱格式'));
                         } else {
                             callback();
                         }
@@ -163,6 +195,20 @@ import searchDistPicker from '@/components/searchDistPicker.vue'
             width:145px;
         }
     }
+    .mobile-input-item{
+        position:relative;
+        .mobile-select{
+            position:absolute;
+            top:0;
+            left:0;
+            width:115px !important;
+        }
+        .mobile-input{
+            .el-input__inner{
+                padding-left: 125px !important;
+            }
+        }
+    }
 }
 </style>
 <style scoped lang="scss">

+ 39 - 132
src/views/system_manage/departManage.vue

@@ -3,7 +3,7 @@
 		<div class="left_cont">
 			<div class="company_top" @click="initDepart">
 				<img src="~@/assets/img/set_m/home_ico.png" alt="" style="width:30px;height:30px;">
-				<span :class="!defaultGroup&&!defaultDepart?'act':''">弘则研究</span>
+				<span :class="!defaultGroup&&!defaultDepart?'act':''">部门信息</span>
 			</div>
 			<el-tree
 				ref="departTree"
@@ -12,7 +12,6 @@
 				:data="departArr"
 				node-key="unicodeKey"
 				:props="defaultProp"
-				default-expand-all
 				draggable 
 				:allow-drag="checkAllowDrag"
 				:allow-drop="checkAllowDrop"
@@ -80,6 +79,11 @@
 							<span style="position: relative;">{{scope.row.RealName}}</span>
 						</template>
 					</el-table-column>
+					<el-table-column 
+						prop="AdminName"
+						label="账号"
+						align="center"
+					/>
 					<el-table-column
 					prop="Mobile"
 					label="手机号"
@@ -275,128 +279,6 @@
 				<el-button  style="width:80px;" @click="cancelHandle(2)">取消</el-button>
 			</div>
 		</el-dialog>
-		<!-- 添加用户
-			研报后台5.9后拆成组件重写了,这块没实际用到,留着参考
-		 -->
-		<!-- <el-dialog
-		:title="userForm.title"
-		:visible.sync="isAddUser"
-		:close-on-click-modal="false"
-		:modal-append-to-body='false'
-		@close="cancelHandle(3)"
-		center
-		width="700px"
-		top="5vh"
-		v-dialogDrag>
-			<div slot="title" style="display:flex;alignItems:center;">
-				<img :src="userForm.title=='添加用户'?$icons.add:$icons.edit" style="color:#fff;width:16px;height:16px;marginRight:5px;">
-				<span style="fontSize:16px;">{{userForm.title}}</span>
-			</div>
-			<el-form @submit.native.prevent :model="userForm" :rules="userRule" ref="userForm" label-width="100px" class="demo-ruleForm" style="marginTop:15px;">
-				<el-form-item label="登录账号" prop="account">
-					<el-input
-					v-model="userForm.account"
-					placeholder="建议使用邮箱前缀或者手机号码"
-					style="width:90%"
-					clearable>
-					</el-input>
-				</el-form-item>
-				<el-form-item label="登录密码" prop="pwd">
-					<el-input 
-					v-model="userForm.pwd"
-					placeholder="6-12位数字与字母的组合"
-					style="width:90%"
-					:type="userForm.title == '添加用户' ? 'text' : 'password' "
-					clearable></el-input>
-				</el-form-item>
-				<el-form-item label="工号" prop="employeeNumber">
-					<el-input :disabled="hasEmployeeNo"
-					v-model="userForm.employeeNumber"
-					placeholder="请输入工号"
-					style="width:90%"></el-input>
-				</el-form-item>
-				<el-form-item label="姓名" prop="name">
-					<el-input
-					v-model="userForm.name"
-					placeholder="请输入用户名称"
-					style="width:90%"
-					clearable>
-					</el-input>
-				</el-form-item>
-				<el-form-item label="所属部门" prop="depart">
-					<el-cascader
-						:options="departArr"
-						v-model="userForm.depart"
-						:props="form_departProp"
-						placeholder="请选择部门分组"
-						:key="cascaderIdx"
-						style="width:90%"
-						clearable
-						></el-cascader>
-				</el-form-item>
-				<el-form-item label="分配角色" prop="role">
-					<el-select v-model="userForm.role" placeholder="分配角色" @change="roleChange" style="width:90%">
-						<el-option
-							v-for="item in roleArr"
-							:key="item.RoleId"
-							:label="item.RoleName"
-							:value="item.RoleId">
-						</el-option>
-					</el-select>
-				</el-form-item>
-					<el-form-item label="研究方向" prop="direct">
-						<el-cascader
-						collapse-tags
-						:show-all-levels="false"
-						:options="researchGroup"
-						v-model="userForm.direct"
-						:props="form_directProp"
-						placeholder="请选择研究方向"
-						style="width:90%"
-						clearable
-						></el-cascader>
-					</el-form-item>
-					<el-form-item label="工作地点" prop="city"
-					:rules="[2,6,18].includes(userForm.role)?{ required: true, message: '工作地点不能为空', trigger: 'change' }:{}">
-						<v-distpicker 
-              :province-source="province_sorce"
-              :city-source="city_sorce"
-							:province="userForm.province"
-							:city="userForm.city"
-							hide-area 
-							@selected="selectRegion"
-							@province="provinceChange"
-						></v-distpicker>
-					</el-form-item>
-				<el-form-item label="职务" prop="post">
-					<el-input
-					v-model="userForm.post"
-					placeholder="请输入职务"
-					style="width:90%"
-					clearable>
-					</el-input>
-				</el-form-item>
-				<el-form-item label="手机号码" prop="mobile">
-					<el-input
-					v-model="userForm.mobile"
-					placeholder="请输入手机号码"
-					style="width:90%"
-					clearable>
-					</el-input>
-				</el-form-item>
-				<el-form-item label="状态" prop="status">
-					<el-radio-group v-model="userForm.status">
-						<el-radio :label="1">启用</el-radio>
-						<el-radio :label="0">禁用</el-radio>
-					</el-radio-group>
-				</el-form-item>
-			</el-form>	
-			<div style="display:flex;justify-content:center;margin:75px 0 26px;">
-				<el-button type="primary" style="width:80px;marginRight:24px;" @click="saveUser">保存</el-button>
-				<el-button  style="width:80px;" @click="cancelHandle(3)">取消</el-button>
-			</div>
-		</el-dialog> -->
-		<!-- 编辑分组 -->
 		<el-dialog
 		title="编辑分组"
 		:visible.sync="isEditGroup"
@@ -438,6 +320,7 @@
 			:roleArr="roleArr"
 			:hasEmployeeNo="hasEmployeeNo"
 			:researchGroup="researchGroup"
+			:areaCode="areaCode"
 			@close="cancelHandle(3)"
 			@save="saveUser"
 			@selectRegion="selectRegion"
@@ -453,6 +336,9 @@
 		>
 			<div class="dialog-container">
 				<el-form ref="resetForm" :model="resetForm" :rules="resetRules" label-width="100px">
+					<el-form-item label="账号">
+						<span>{{modifyAdminName}}</span>
+					</el-form-item>
 					<el-form-item label="新密码" prop="password">
 						<el-input v-model="resetForm.password" style="width:100%" :show-password="true"></el-input>
 					</el-form-item>
@@ -475,6 +361,10 @@
 			@close="isMoveDepartShow=false" center width="460px" v-dialogDrag
 		>
 			<div class="dialog-cotainer">
+				<div class="form-item" style="display: flex;align-items: center;margin-bottom:20px">
+					<p style="width:90px">账号</p>
+					<span>{{modifyAdminName}}</span>
+				</div>
 				<div class="form-item" style="display: flex;align-items: center;">
 					<p style="width:90px">选择分组</p>
 					<el-cascader :options="departArr" v-model="resetDepart" :props="form_departProp" style="width:100%"
@@ -586,6 +476,8 @@ export default {
 				mobile:'',
 				auth:0,
 				status:1,//状态 1启用 0禁用
+				email:'',
+				areacode:'86',
 			},//用户弹框表单
 			// 是否有工号
 			hasEmployeeNo:false,
@@ -692,6 +584,7 @@ export default {
 		}else if(process.env.NODE_ENV == 'production'){
 			this.shareCustomDepartmentId = 37
 		}
+		this.getAreaCode()
 	},
 	mounted() {
 		this.getDepartArr();
@@ -1035,7 +928,7 @@ export default {
 			this.userForm = {
 				title:'添加用户',
 				account:'',
-				pwd:'123456a',
+				pwd:'',
 				employeeNumber:'',
 				name:'',
 				depart:'',
@@ -1046,7 +939,9 @@ export default {
 				post:'',
 				mobile:'',
 				auth:0,
-				status:1
+				status:1,
+				email:'',
+				areacode:'86',
 			}
 		},
 		// 同步每刻
@@ -1100,6 +995,8 @@ export default {
 							ResearchGroupIds:ResearchGroupIds.join(','),
 							Province:this.userForm.province,
 							City:this.userForm.city,
+							Email:this.userForm.email,
+							TelAreaCode:this.userForm.areacode,
 						}
 						//console.log('testAdd',params)
 						departInterence.addUser(params).then(res => {
@@ -1120,7 +1017,9 @@ export default {
 									post:'',
 									mobile:'',
 									auth:0,
-									status:1
+									status:1,
+									email:'',
+									areacode:'86'
 								}
 								this.getTableUser();
 							}
@@ -1147,7 +1046,9 @@ export default {
 							Enabled:Number(this.userForm.status),
 							ResearchGroupIds:ResearchGroupIds.join(','),
 							Province:this.userForm.province,
-							City:this.userForm.city
+							City:this.userForm.city,
+							Email:this.userForm.email,
+							TelAreaCode:this.userForm.areacode||'86',
 						}
 						//console.log('testEdit',params)
 						departInterence.editUser(params).then(res => {
@@ -1168,7 +1069,9 @@ export default {
 									post:'',
 									mobile:'',
 									auth:0,
-									status:1
+									status:1,
+									email:'',
+									areacode:'86',
 								}
 								this.getTableUser();
 							}
@@ -1208,7 +1111,9 @@ export default {
 					post:'',
 					mobile:'',
 					auth:'无',
-					status:1
+					status:1,
+					email:'',
+					areacode:'86',
 				},
 				this.$refs.addUserDialog.$refs.userForm.resetFields();//重置校验
 				this.isAddUser = false;
@@ -1300,14 +1205,16 @@ export default {
 				mobile:item.Mobile,
 				auth:item.Authority,
 				status:item.Enabled,
-				direct:direct
+				direct:direct,
+				email:item.Email,
+				areacode:item.TelAreaCode||'86'
 			}
 			this.hasEmployeeNo=!!item.EmployeeId
 			this.isAddUser = true;
 		},
 		/* 删除用户 */
 		delUser(item) {
-			this.$confirm('是否确认删除该用户?','提示',{
+			this.$confirm(`是否确认删除用户【${item.AdminName}】`,'提示',{
 				type:'warning'
 			}).then(() => {
 				departInterence.delUser({

+ 22 - 6
src/views/system_manage/mixin/departManageMixin.js

@@ -5,7 +5,8 @@
  */
 import { departInterence } from '@/api/api.js';
 import http from '@/api/http.js';
-import AddUserDialog from '../components/addUserDialog.vue'
+import AddUserDialog from '../components/addUserDialog.vue';
+import{checkPassWord} from '@/utils/commonOptions';
 
 export default {
     components:{AddUserDialog},
@@ -13,10 +14,13 @@ export default {
         const validatePass = (rule,value,callback)=>{
             if(value===''){
                 callback(new Error('请输入新密码'))
+            }
+            if(this.resetForm.check!==''){
+                this.$refs.resetForm.validateField('check')
+            }
+            if(!checkPassWord(value)){
+                callback(new Error('密码要求8位及以上,包含数字、大写字母、小写字母、特殊字符中的三个类型'))
             }else{
-                if(this.resetForm.check!==''){
-                    this.$refs.resetForm.validateField('check')
-                }
                 callback()
             }
         }
@@ -25,8 +29,9 @@ export default {
                 callback(new Error('请输入确认密码'))
             }else if(value!==this.resetForm.password){
                 callback(new Error('两次输入的密码不一致'))
+            }else{
+                callback()
             }
-            callback()
         }
         return {
             isExtraUserFormItemShow: false, //是否显示额外的用户表单项
@@ -53,7 +58,10 @@ export default {
                 check:''
             },
             resetDepart:'',
-            modifyAdminId:0
+            modifyAdminId:0,
+            areaCode:[],
+            modifyAdminName:'',
+
 
         }
     },
@@ -175,6 +183,7 @@ export default {
             if(type==='show'){
                 this.$refs.resetForm&&this.$refs.resetForm.clearValidate()
                 this.modifyAdminId = data.AdminId
+                this.modifyAdminName=data.AdminName
                 this.isResetPasswordShow = true
             }else{
                 this.$refs.resetForm.validate((valid)=>{
@@ -208,6 +217,7 @@ export default {
                 data.TeamId ?departArr.push(data.TeamId):''
                 this.resetDepart = departArr
                 this.modifyAdminId = data.AdminId
+                this.modifyAdminName=data.AdminName
                 this.isMoveDepartShow = true
             }else{
                 //选择分组接口
@@ -223,6 +233,12 @@ export default {
                     this.getTableUser();
                 })
             }
+        },
+        getAreaCode(){
+            departInterence.getPhoneAreaCode().then(res=>{
+                if(res.Ret!==200) return 
+                this.areaCode = res.Data||[]
+            })
         }
     }