Browse Source

代码合并冲突解决

hbchen 1 year ago
parent
commit
c91b83d38c

+ 12 - 1
index.html

@@ -25,7 +25,18 @@
 	
 	<!-- dataTables -->
 	<link rel="stylesheet" type="text/css" href="./static/css/jquery.dataTables.css"/>
-
+    <!-- 隐藏Edge在密码输入框的icon -->
+    <style>
+        input[type="password"]::-ms-reveal{
+            display: none;
+        }
+        input[type="password"]::-ms-clear{
+            display: none;
+        }
+        input[type="password"]::-o-reveal{
+            display: none;
+        }
+    </style>
 	<script>
 		var _hmt = _hmt || [];
 		(function() {

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

@@ -260,7 +260,81 @@ const departInterence = {
 	//获取用户所有的按钮权限
 	getRoleBtnAuth:params=>{
 		return http.get('/system/role/menu/buttons',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-登录;3-忘记密码
+	 * @returns 
+	 */
+	getCodeVerify:params=>{
+		return http.post('/user_login/verify_code',params)
+	},
+	/**
+	 * ETA1.4后,用户登录
+	 * @param {Number} LoginType 登录方式: 1-账号; 2-手机号; 3-邮箱
+	 * @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 图形验证码ID
+	 * @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


+ 1 - 1
src/main.js

@@ -157,7 +157,7 @@ router.beforeEach(async(to, from, next) => {
   } */
 
   let auth = localStorage.getItem("auth") || false;
-  if (to.path != "/login" && to.path!='/temppage' && !auth) {
+  if (to.path != "/login" && to.path!='/temppage' &&to.path!='/fogetpassword' && !auth) {
     window.location.href =  window.location.origin + '/login';
     return false;
   }

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

+ 416 - 127
src/views/Login.vue

@@ -1,10 +1,10 @@
 <template>
-  <div id="login">
+	<div id="login">
 		<div id="login_wrapper">
       
 			<img class="login-bg" :src="isTrail?global.login_bg:$setting.login_bg" alt />
-      <img class="login-icon" :src="isTrail?global.login_logo:$setting.login_logo" v-if="isTrail?global.login_logo:$setting.login_logo">
-			<el-form
+			<img class="login-icon" :src="isTrail?global.login_logo:$setting.login_logo" v-if="isTrail?global.login_logo:$setting.login_logo">
+			<!-- <el-form
 				:model="ruleForm"
 				:rules="rules"
 				ref="ruleForm"
@@ -63,8 +63,68 @@
 						>登录</el-button
 					>
 				</el-form-item>
-			</el-form>
+			</el-form>  -->
+			<div class="login-box" id="login-container" v-if="activeModel!=='forgetPassModel'">
+				<span class="login-title">ETA — 让投研领先市场半步</span>
+				<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>
 
@@ -72,9 +132,14 @@
 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";
 import global from '@/config/setting'
 import {openLoginTimer} from "@/utils/TimeOnPage.js"
 export default {
+    components: { OrdinaryModel, MobileModel, EmailModel, ForgetPassModel },
   data() {
     return {
 			global,
@@ -102,6 +167,18 @@ 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'
     };
   },
 	computed: {
@@ -110,135 +187,347 @@ export default {
 			return this.$store.state.businessCode == this.$store.state.TRIAL_CODE
 		}
   },
-  created() {
-    this.keyupSubmit(); //回车登录
-    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;
-    }
-  },
-  methods: {
-    keyupSubmit() {
-      //回车登录
-      document.onkeydown = (e) => {
-        let keyval = window.event.keyCode;
-        if (keyval === 13) {
-          this.handleSubmit2();
-        }
-      };
+    created() {
+        this.keyupSubmit(); //回车登录
+        this.getPhoneCode();//获取手机号区号
+    },
+    mounted(){
+        this.getRememberedInfo()
     },
-    handleSubmit2() {
-      //登录
-      let that = this;
-      this.$refs.ruleForm.validate((valid) => {
-        if (valid) {
-          that.logining = true;
-          var loginParams = {
-            Username: that.ruleForm.account,
-            Password: md5.hex_md5(that.ruleForm.checkPass),
-            IsRemember: this.checked,
-          };
-          userLogin(loginParams).then(async (res) => {
-            if (res.Ret === 200) {
-              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);
-							// 打开登录计时
-							if(this.isTrail){
-								openLoginTimer()
-							}
-							
-              if (this.checked) {
-                localStorage.setItem(
-                  "account",
-                  this.b.encode(this.ruleForm.account)
-                );
-                localStorage.setItem(
-                  "checkPass",
-                  this.b.encode(this.ruleForm.checkPass)
-                );
-              } else {
-                localStorage.removeItem("account");
-                localStorage.removeItem("checkPass");
-              }
+    methods: {
+        keyupSubmit() {
+            //回车登录
+            document.onkeydown = (e) => {
+                let keyval = window.event.keyCode;
+                if (keyval === 13) {
+                    //this.handleSubmit2();
+                    !this.logining&&this.handleLogin()
+                }
+            };
+        },
+        handleSubmit2() {
+            //登录
+            let that = this;
+            this.$refs.ruleForm.validate((valid) => {
+                if (valid) {
+                    that.logining = true;
+                    var loginParams = {
+                        Username: that.ruleForm.account,
+                        Password: md5.hex_md5(that.ruleForm.checkPass),
+                        IsRemember: this.checked,
+                    };
+                    userLogin(loginParams).then(async (res) => {
+                        if (res.Ret === 200) {
+                            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);
+                            if (this.checked) {
+                                localStorage.setItem("account", this.b.encode(this.ruleForm.account));
+                                localStorage.setItem("checkPass", this.b.encode(this.ruleForm.checkPass));
+                            }
+                            else {
+                                localStorage.removeItem("account");
+                                localStorage.removeItem("checkPass");
+                            }
+                            let path = "";
+                            switch (res.Data.RoleTypeCode) {
+                                case "rai_researcher":
+                                case "ficc_researcher":
+                                case "researcher":
+                                    path = "/reportlist";
+                                    break;
+                                case "compliance": //合规
+                                    path = "/contractapprovallist";
+                                    break;
+                                case "special_researcher": //特邀研究员
+                                    path = "/dataList";
+                                    break;
+                                case "special_ficc_seller":
+                                    path = "/meetingCalendar";
+                                    break;
+                                default:
+                                    path = await this.getOtherRolePath("myCalendar");
+                            }
+                            this.$router.push({ path });
+                        }
+                        that.logining = false;
+                    });
+                }
+            });
+        },
+        changePass(value) {
+            //密码输入格式切换
+            this.visible = !(value === "show");
+        },
+        getOtherRolePath(pathVal) {
+            return departInterence.getMenu().then((res) => {
+                let resolvePath = "";
+                if (res.Ret === 200) {
+                    let menuList = res.Data.List || [];
+                    if (!menuList.length) {
+                        this.$message.error('该账号没有任何菜单权限,请联系管理员');
+                        return;
+                    }
+                    // 是否已经拿到菜单信息
+                    sessionStorage.setItem("hasGetMenu", "true");
+                    sessionStorage.setItem("MenuList", JSON.stringify(menuList));
+                    /* 是否有数据报表权限 */
+                    this.$store.commit("SET_DATA_AUTH", menuList.some((item) => item.name === "数据报表"));
+                    for (let i = 0; i < menuList.length; i++) {
+                        const arr = menuList[i].children || [];
+                        if (arr.some(it => it.path == pathVal)) {
+                            resolvePath = "/" + pathVal;
+                            break;
+                        }
+                    }
+                    return resolvePath || "/" + menuList[0].children[0].path;
+                }
+                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())
+            }
 
-              let path = "";
-              switch (res.Data.RoleTypeCode) {
+        },
+        //判断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 = ''
+            switch (res.Data.RoleTypeCode) {
                 case "rai_researcher":
                 case "ficc_researcher":
                 case "researcher":
-                  path = "/reportlist";
-                  break;
+                    path = "/reportlist";
+                    break;
                 case "compliance": //合规
-                  path = "/contractapprovallist";
-                  break;
+                    path = "/contractapprovallist";
+                    break;
                 case "special_researcher": //特邀研究员
-                  path = "/dataList";
-                  break;
+                    path = "/dataList";
+                    break;
                 case "special_ficc_seller":
-                  path = "/meetingCalendar";
-                  break;
+                    path = "/meetingCalendar";
+                    break;
                 default:
-                  path = await this.getOtherRolePath("myCalendar");
-              }
-              this.$router.push({ path });
+                    path = await this.getOtherRolePath("myCalendar");
             }
-            that.logining = false;
-          });
-        }
-      });
-    },
-    changePass(value) {
-      //密码输入格式切换
-      this.visible = !(value === "show");
-    },
-    getOtherRolePath(pathVal) {
-      return departInterence.getMenu().then((res) => {
-        let resolvePath = "";
-        if (res.Ret === 200) {
-          let menuList = res.Data.List || [];
-          if(!menuList.length){
-						this.$message.error('该账号没有任何菜单权限,请联系管理员')
-						return
-					}
-
-          // 是否已经拿到菜单信息
-          sessionStorage.setItem("hasGetMenu", "true");
-          sessionStorage.setItem("MenuList", JSON.stringify(menuList));
-          /* 是否有数据报表权限 */
-          this.$store.commit(
-            "SET_DATA_AUTH",
-            menuList.some((item) => item.name === "数据报表")
-          );
-
-          for (let i = 0; i < menuList.length; i++) {
-            const arr=menuList[i].children||[]
-						
-						if(arr.some(it => it.path == pathVal)){
-              resolvePath = "/" + pathVal;
-              break;
+            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
+                    }
+                }
             }
-          }
-          return resolvePath || "/" + menuList[0].children[0].path;
         }
-        return "/" + pathVal;
-      });
     },
-  },
-  destroyed() {
-    document.onkeydown = null;
-  },
+    destroyed() {
+        document.onkeydown = null;
+    }
 };
 </script>
 
+<style lang="scss">
+#login{
+	.el-tabs__nav {
+		width: 100%;
+		display: flex;
+	}
+	.el-tabs__item{
+		font-size: 18px;
+		flex: 1;
+		text-align: center;
+	}
+	.check-dialog{
+		.el-dialog{
+			border-radius: 8px;
+			.el-dialog__header{
+				background-color: transparent;
+				.el-dialog__headerbtn>i{
+					color: #C0C4CC;
+				}
+			}
+			.el-input{
+				width:100%;
+			}
+			.el-dialog__footer{
+				text-align: center;
+			}
+		}
+	}
+}
+</style>
 <style lang="scss" scoped>
 #login {
 	width: 100%;
@@ -264,22 +553,22 @@ export default {
 
 		.login-icon {
 			position: absolute;
-      top: 40px;
+			top: 40px;
 			right: 40px;
 		}
 		.login-title {
 			color: #333;
-			font-size: 30px;
+			font-size: 38px;
 			display: block;
-      text-align: center;
-			margin-bottom: 30px;
+			text-align: center;
+			margin-bottom: 60px;
 		}
 
-		#login-container {
+		#login-container ,.login-box{
 			box-sizing: border-box;
 			border-radius: 10px;
 			position: absolute;
-			top: 31%;
+			top: 27%;
 			right: 12%;
 			z-index: 100;
 			input::-webkit-input-placeholder {
@@ -290,7 +579,7 @@ export default {
 			}
 			.submit_btn {
 				width: 100%;
-				height: 60px;
+				height: 50px;
 				background: #3654C1;
 				font-size: 20px;
 				border-radius: 5px;
@@ -343,15 +632,15 @@ export default {
 			.login-bg{ 
 				display: block;
 			}
-			#login-container {
-				width: 31%;
+			#login-container ,.login-box{
+				width: 33%;
 			}
 		}
 		@media screen and (max-width: 1200px){
 			.login-bg{ 
 				display: none; 
 			}
-			#login-container {
+			#login-container ,.login-box{
 				width: 70%;
 			}
 		}

+ 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: #3654C1;
+        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
+            }
+        }
+    }
+}

+ 18 - 2
src/views/resetpassword.vue

@@ -86,7 +86,7 @@
             ></i>
           </el-input>
         </el-form-item>
-        <el-form-item style="text-align: center; padding-top: 20px">
+        <el-form-item style="text-align: center;">
           <el-button type="primary" size="medium" @click.native="addSubmit"
             >确定</el-button
           >
@@ -107,6 +107,7 @@
 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 {
@@ -126,6 +127,15 @@ export default {
           },
         ],
         NewPwd: [
+            {
+                validator:(rule,value,callback)=>{
+                    if(!checkPassWord(value)){
+                        callback(new Error('密码要求8位及以上,包含数字、大写字母、小写字母、特殊字符中的三个类型'))
+                    }else{
+                        callback()
+                    }
+                }
+            },
           {
             required: true,
             message: "请输入确认密码",
@@ -188,4 +198,10 @@ export default {
 };
 </script>
 
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.box-card{
+    .el-form-item{
+        margin-bottom: 40px;
+    }
+}
+</style>

+ 54 - 8
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="请输入手机号码" :disabled="userForm.disabledForm" 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="请选择部门分组" :disabled="userForm.disabledForm" 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>
@@ -68,7 +75,8 @@
 </template>
 
 <script>
-import searchDistPicker from '@/components/searchDistPicker.vue'
+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">

+ 24 - 126
src/views/system_manage/departManage.vue

@@ -285,127 +285,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="编辑分组"
@@ -448,6 +327,7 @@
 			:roleArr="roleArr"
 			:hasEmployeeNo="hasEmployeeNo"
 			:researchGroup="researchGroup"
+			:areaCode="areaCode"
 			@close="cancelHandle(3)"
 			@save="saveUser"
 			@selectRegion="selectRegion"
@@ -463,10 +343,10 @@
 		>
 			<div class="dialog-container">
 				<el-form ref="resetForm" :model="resetForm" :rules="resetRules" label-width="100px">
-					<el-form-item label="新密码" prop="password">
+					<el-form-item label="新密码" prop="password" style="margin-bottom: 40px;">
 						<el-input v-model="resetForm.password" style="width:100%" :show-password="true"></el-input>
 					</el-form-item>
-					<el-form-item label="确认新密码" prop="check">
+					<el-form-item label="确认新密码" prop="check" style="margin-bottom: 40px;">
 						<el-input v-model="resetForm.check" style="width:100%" :show-password="true"></el-input>
 					</el-form-item>
 				</el-form>
@@ -596,6 +476,8 @@ export default {
 				post:'',
 				employeeNumber:'',
 				mobile:'',
+				email:'',
+				areacode:'86',
 				auth:0,
 				status:1,//状态 1启用 0禁用
 				disabledForm:false,//是否禁用表单的某些选项
@@ -682,6 +564,7 @@ export default {
 				direct:'',
 				province:'',
 				city:'',
+				email:'',
 			},//用户详情信息
 			authList:[],//权限列表
 			click_roleId:'',//角色id
@@ -725,6 +608,7 @@ export default {
 		}else if(process.env.NODE_ENV == 'production'){
 			this.shareCustomDepartmentId = 37
 		}
+		this.getAreaCode()
 	},
 	mounted() {
 		this.getDepartArr();
@@ -1080,7 +964,7 @@ export default {
 			this.userForm = {
 				title:'添加用户',
 				account:'',
-				pwd:'123456a',
+				pwd:'',
 				employeeNumber:'',
 				name:'',
 				depart:'',
@@ -1090,6 +974,8 @@ export default {
 				city:'',
 				post:'',
 				mobile:'',
+				email:'',
+				areacode:'86',
 				auth:0,
 				status:1
 			}
@@ -1145,6 +1031,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 => {
@@ -1164,6 +1052,8 @@ export default {
 									city:'',
 									post:'',
 									mobile:'',
+									email:'',
+									areacode:'86',
 									auth:0,
 									status:1
 								}
@@ -1192,7 +1082,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
 						}
 						//console.log('testEdit',params)
 						departInterence.editUser(params).then(res => {
@@ -1212,6 +1104,8 @@ export default {
 									city:'',
 									post:'',
 									mobile:'',
+									email:'',
+									areacode:'86',
 									auth:0,
 									status:1
 								}
@@ -1252,6 +1146,8 @@ export default {
 					city:'',
 					post:'',
 					mobile:'',
+					email:'',
+					areacode:'86',
 					auth:'无',
 					status:1
 				},
@@ -1348,7 +1244,9 @@ export default {
 				direct:direct,
 				departmentName:item.DepartmentGroup,
         disabledForm:false,
-				disabledStatus:false
+				disabledStatus:false,
+				email:item.Email,
+				areacode:item.TelAreaCode
 			}
 			this.hasEmployeeNo=!!item.EmployeeId
 			this.isAddUser = true;

+ 18 - 7
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,8 +58,8 @@ export default {
                 check:''
             },
             resetDepart:'',
-            modifyAdminId:0
-
+            modifyAdminId:0,
+            areaCode:[]
         }
     },
     methods: {
@@ -223,6 +228,12 @@ export default {
                     this.getTableUser();
                 })
             }
+        },
+        getAreaCode(){
+            departInterence.getPhoneAreaCode().then(res=>{
+                if(res.Ret!==200) return 
+                this.areaCode = res.Data||[]
+            })
         }
     }