From 01d423865ae5eddf91f35c8526f5683c3b430870 Mon Sep 17 00:00:00 2001 From: Crunchy <3114200645@qq.com> Date: 星期一, 13 一月 2025 09:30:06 +0800 Subject: [PATCH] 密码强校验添加 --- src/views/admin/user/info.vue | 503 ++++++++++++++++++++++++++++++------------------------- 1 files changed, 274 insertions(+), 229 deletions(-) diff --git a/src/views/admin/user/info.vue b/src/views/admin/user/info.vue index b7fb0b1..f220390 100644 --- a/src/views/admin/user/info.vue +++ b/src/views/admin/user/info.vue @@ -16,269 +16,314 @@ --> <template> - <div class="app-container calendar-list-container"> - <basic-container> - <template> - <el-tabs v-model="switchStatus" @tab-click="switchTab" style="padding-left:20px"> - <el-tab-pane label="淇℃伅绠$悊" name="userManager"/> - <el-tab-pane label="瀵嗙爜绠$悊" name="passwordManager"/> - </el-tabs> - </template> - <el-row> - <el-col :span="12"> - <div class="grid-content bg-purple"> - <el-form - v-if="switchStatus==='userManager'" - ref="ruleForm2" - :model="ruleForm2" - :rules="rules2" - label-width="100px" - class="demo-ruleForm"> - <el-form-item - label="鐢ㄦ埛鍚�" - prop="username"> - <el-input - v-model="ruleForm2.username" - type="text" - disabled/> - </el-form-item> - <el-form-item label="鎵嬫満鍙�" prop="phone"> - <el-input v-model="ruleForm2.phone" placeholder="楠岃瘉鐮佺櫥褰曚娇鐢�"/> - </el-form-item> - <el-form-item label="澶村儚"> - <el-upload - :headers="headers" - :show-file-list="false" - :on-success="handleAvatarSuccess" - class="avatar-uploader" - action="/admin/sys-file/upload"> - <img v-if="ruleForm2.avatar" id="avatar" :src="avatarUrl" class="avatar"> - <i v-else class="el-icon-plus avatar-uploader-icon"/> - </el-upload> - </el-form-item> - <!-- <el-form-item - label="绀句氦鐧诲綍" - prop="social"> - <a - href="#" - style="color: blue" - @click="handleClick('wechat')">缁戝畾寰俊</a>锝� - <a - href="#" - style="color: blue" - @click="handleClick('gitee')">缁戝畾鐮佷簯</a> | - <a - href="#" - style="color: blue" - @click="handleClick('osc')">寮�婧愪腑鍥�</a> - </el-form-item> --> - <el-form-item> - <el-button - type="primary" - @click="submitForm('ruleForm2')">鎻愪氦 - </el-button> - <el-button @click="resetForm('ruleForm2')">閲嶇疆</el-button> - </el-form-item> - </el-form> - <el-form - v-if="switchStatus==='passwordManager'" - ref="ruleForm2" - :model="ruleForm2" - :rules="rules2" - label-width="100px" - class="demo-ruleForm"> - <el-form-item - label="鍘熷瘑鐮�" - prop="password"> - <el-input - v-model="ruleForm2.password" - type="password" - auto-complete="off"/> - </el-form-item> - <el-form-item - label="瀵嗙爜" - prop="newpassword1"> - <el-input - v-model="ruleForm2.newpassword1" - type="password" - auto-complete="off"/> - </el-form-item> - <el-form-item - label="纭瀵嗙爜" - prop="newpassword2"> - <el-input - v-model="ruleForm2.newpassword2" - type="password" - auto-complete="off"/> - </el-form-item> - <el-form-item> - <el-button - type="primary" - @click="submitForm('ruleForm2')">鎻愪氦 - </el-button> - <el-button @click="resetForm('ruleForm2')">閲嶇疆</el-button> - </el-form-item> - </el-form> - </div> - </el-col> - </el-row> - </basic-container> - </div> + <div class="app-container calendar-list-container"> + <basic-container> + <template> + <el-tabs @tab-click="switchTab"> + <el-tab-pane label="淇℃伅绠$悊" name="userManager" /> + <el-tab-pane label="瀵嗙爜绠$悊" name="passwordManager" /> + </el-tabs> + </template> + <el-row> + <el-col :span="12"> + <div class="grid-content bg-purple"> + <el-form v-if="switchStatus === 'userManager'" ref="ruleForm2" :model="ruleForm2" :rules="rules2" label-width="100px" class="demo-ruleForm"> + <el-form-item label="鐢ㄦ埛鍚�" prop="username"> + <el-input v-model="ruleForm2.username" type="text" disabled /> + </el-form-item> + <el-form-item label="鎵嬫満鍙�" prop="phone"> + <el-input v-model="ruleForm2.phone" placeholder="楠岃瘉鐮佺櫥褰曚娇鐢�" /> + </el-form-item> + <el-form-item label="澶村儚"> + <el-upload :headers="headers" :show-file-list="false" :on-success="handleAvatarSuccess" class="avatar-uploader" action="/admin/sys-file/upload"> + <img v-if="ruleForm2.avatar" id="avatar" :src="avatarUrl" class="avatar" /> + <i v-else class="el-icon-plus avatar-uploader-icon" /> + </el-upload> + </el-form-item> + <el-form-item label="绀句氦鐧诲綍" prop="social"> + <a href="#" style="color: blue" @click="handleClick('wechat')">缁戝畾寰俊</a>锝� <a href="#" style="color: blue" @click="handleClick('gitee')">缁戝畾鐮佷簯</a> | + <a href="#" style="color: blue" @click="handleClick('osc')">寮�婧愪腑鍥�</a> + </el-form-item> + <el-form-item> + <el-button type="primary" @click="submitForm('ruleForm2')">鎻愪氦 </el-button> + <el-button @click="resetForm('ruleForm2')">閲嶇疆</el-button> + </el-form-item> + </el-form> + <el-form v-if="switchStatus === 'passwordManager'" ref="ruleForm2" :model="ruleForm2" :rules="rules2" label-width="100px" class="demo-ruleForm"> + <el-form-item label="鍘熷瘑鐮�" prop="password"> + <el-input v-model="ruleForm2.password" type="password" auto-complete="off" /> + </el-form-item> + <el-form-item label="瀵嗙爜" prop="newpassword1"> + <div class="password-input-container"> + <el-input v-model="ruleForm2.newpassword1" type="password" @input="checkPasswordStrength" show-password auto-complete="off" /> + <div v-if="ruleForm2.newpassword1" class="password-strength-indicator"> + 瀵嗙爜寮哄害: <span :class="passwordLevelClass">{{ passwordLevel }}</span> + </div> + </div> + </el-form-item> + <el-form-item label="纭瀵嗙爜" prop="newpassword2"> + <el-input v-model="ruleForm2.newpassword2" type="password" auto-complete="off" /> + </el-form-item> + <el-form-item> + <el-button type="primary" @click="submitForm('ruleForm2')">鎻愪氦 </el-button> + <el-button @click="resetForm('ruleForm2')">閲嶇疆</el-button> + </el-form-item> + </el-form> + </div> + </el-col> + </el-row> + </basic-container> + </div> </template> <script> - import {handleImg, openWindow} from '@/util/util' - import {mapState} from 'vuex' - import store from '@/store' - import {getStore, setStore} from '@/util/store' - import {editInfo} from '@/api/admin/user' +import { handleImg, openWindow } from '@/util/util' +import { mapState } from 'vuex' +import store from '@/store' +import { getStore, setStore } from '@/util/store' +import { editInfo } from '@/api/admin/user' - - export default { +export default { data() { - var validatePass = (rule, value, callback) => { - if (this.ruleForm2.password !== '') { - if (value !== this.ruleForm2.newpassword1) { - callback(new Error('涓ゆ杈撳叆瀵嗙爜涓嶄竴鑷�!')) - } else { - callback() - } - } else { - callback() + // 瀵嗙爜寮哄害鏍¢獙 + const validatePasswordStrength = (rule, value, callback) => { + let strength = 0 + + if (value.length >= 8) strength++ + if (/\d/.test(value)) strength++ + if (/[a-z]/.test(value)) strength++ + if (/[A-Z]/.test(value)) strength++ + if (/[!@#$%^&*]/.test(value)) strength++ + + if (strength < 4) { + callback(new Error('瀵嗙爜寮哄害涓嶅锛岃纭繚瀵嗙爜鍖呭惈锛氬ぇ灏忓啓瀛楁瘝銆佹暟瀛楀拰鐗规畩瀛楃锛屼笖闀垮害涓嶅皯浜�8浣�')) + } else { + callback() + } } - } - return { - switchStatus: 'userManager', - avatarUrl: '', - show: false, - headers: { - 'Authorization': 'Bearer ' + store.getters.access_token, - }, - ruleForm2: { - username: '', - password: '', - newpassword1: '', - newpassword2: '', - avatar: '', - phone: '' - }, - rules2: { - password: [{required: true, min: 6, message: '鍘熷瘑鐮佷笉鑳戒负绌轰笖涓嶅皯浜�6浣�', trigger: 'change'}], - newpassword1: [{required: false, min: 6, message: '涓嶅皯浜�6浣�', trigger: 'change'}], - newpassword2: [{required: false, validator: validatePass, trigger: 'blur'}] + + // 纭瀵嗙爜鏍¢獙 + var validatePass = (rule, value, callback) => { + if (this.ruleForm2.password !== '') { + if (value !== this.ruleForm2.newpassword1) { + callback(new Error('涓ゆ杈撳叆瀵嗙爜涓嶄竴鑷�!')) + } else { + callback() + } + } else { + callback() + } } - } + + return { + switchStatus: 'userManager', + avatarUrl: '', + show: false, + headers: { + Authorization: 'Bearer ' + store.getters.access_token + }, + ruleForm2: { + username: '', + password: '', + newpassword1: '', + newpassword2: '', + avatar: '', + phone: '' + }, + passwordLevel: '', // 瀵嗙爜寮哄害绾у埆 + passwordLevelClass: '', // 瀵嗙爜寮哄害鏍峰紡绫� + rules2: { + password: [ + { + required: true, + min: 8, + message: '鍘熷瘑鐮佷笉鑳戒负绌轰笖涓嶅皯浜�8浣�', + trigger: 'change' + } + ], + newpassword1: [{ required: true, message: '璇疯緭鍏ユ柊瀵嗙爜', trigger: 'blur' }, { validator: validatePasswordStrength, trigger: 'blur' }], + newpassword2: [ + { + required: true, + validator: validatePass, + trigger: 'blur' + } + ] + } + } }, created() { - this.resetForm() + this.resetForm() }, computed: { - ...mapState({ - userInfo: state => state.user.userInfo - }) + ...mapState({ + userInfo: (state) => state.user.userInfo + }) }, methods: { - switchTab(tab) { - if (tab.name === 'userManager') { - handleImg(this.ruleForm2.avatar, 'avatar') - } - this.switchStatus = tab.name - }, - submitForm(formName) { - this.$refs[formName].validate(valid => { - if (!valid) { - return false - } - editInfo(this.ruleForm2).then(response => { - this.handleLocalData(this.ruleForm2) - this.$notify.success('淇敼鎴愬姛') - // 淇敼瀵嗙爜涔嬪悗寮哄埗閲嶆柊鐧诲綍 - if (this.switchStatus === 'passwordManager') { - this.$store.dispatch('LogOut').then(() => { - location.reload() // 涓轰簡閲嶆柊瀹炰緥鍖杤ue-router瀵硅薄 閬垮厤bug - }) + switchTab(tab) { + if (tab.name === 'userManager') { + handleImg(this.ruleForm2.avatar, 'avatar') } - }) - }) - }, - resetForm() { - this.ruleForm2.password = undefined - this.ruleForm2.newpassword1 = undefined - this.ruleForm2.newpassword2 = undefined - this.ruleForm2.username = this.userInfo.username - this.ruleForm2.phone = this.userInfo.phone - this.ruleForm2.avatar = this.userInfo.avatar - handleImg(this.userInfo.avatar, 'avatar') - //鍒ゆ柇鏄惁閫夋嫨浜嗙鎴稩D - const TENANT_ID = getStore({name: 'tenantId'}) - if (TENANT_ID) { - this.headers['TENANT-ID'] = TENANT_ID // 绉熸埛ID - } - }, - handleClick(thirdpart) { - let appid, client_id, redirect_uri, url - redirect_uri = encodeURIComponent(window.location.origin + '/#/authredirect') - if (thirdpart === 'wechat') { - appid = 'wxd1678d3f83b1d83a' - url = 'https://open.weixin.qq.com/connect/qrconnect?appid=' + appid + '&redirect_uri=' + redirect_uri + '&state=WX-BIND&response_type=code&scope=snsapi_login#wechat_redirect' - } else if (thirdpart === 'tencent') { - client_id = '101322838' - url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&state=QQ-BIND&client_id=' + client_id + '&redirect_uri=' + redirect_uri - } else if (thirdpart === 'gitee') { - client_id = '235ce26bbc59565b82c989aa3a407ce844cf59a7c5e0f9caa9bb3bf32cee5952' - url = 'https://gitee.com/oauth/authorize?response_type=code&state=GITEE-BIND&client_id=' + client_id + '&redirect_uri=' + redirect_uri - } else if (thirdpart === 'osc') { - client_id = 'neIIqlwGsjsfsA6uxNqD' - url = 'https://www.oschina.net/action/oauth2/authorize?response_type=code&client_id=' + client_id + '&state=OSC-BIND&redirect_uri=' + redirect_uri - } - openWindow(url, thirdpart, 540, 540) - }, - handleAvatarSuccess(res, file) { - this.avatarUrl = URL.createObjectURL(file.raw) - this.ruleForm2.avatar = res.data.url - }, - // 澶勭悊鏈湴鏁版嵁锛岄伩鍏嶅埛鏂颁笉鍚屾 - handleLocalData(form) { - let userInfo = getStore({name: 'userInfo'}) + this.switchStatus = tab.name + }, + submitForm(formName) { + this.$refs[formName].validate((valid) => { + if (!valid) { + return false + } + editInfo(this.ruleForm2).then((response) => { + this.handleLocalData(this.ruleForm2) + this.$notify.success('淇敼鎴愬姛') + // 淇敼瀵嗙爜涔嬪悗寮哄埗閲嶆柊鐧诲綍 + if (this.switchStatus === 'passwordManager') { + this.$store.dispatch('LogOut').then(() => { + location.reload() // 涓轰簡閲嶆柊瀹炰緥鍖杤ue-router瀵硅薄 閬垮厤bug + }) + } + }) + }) + }, + resetForm() { + this.ruleForm2.password = undefined + this.ruleForm2.newpassword1 = undefined + this.ruleForm2.newpassword2 = undefined + this.ruleForm2.username = this.userInfo.username + this.ruleForm2.phone = this.userInfo.phone + this.ruleForm2.avatar = this.userInfo.avatar + handleImg(this.userInfo.avatar, 'avatar') + //鍒ゆ柇鏄惁閫夋嫨浜嗙鎴稩D + const TENANT_ID = getStore({ name: 'tenantId' }) + if (TENANT_ID) { + this.headers['TENANT-ID'] = TENANT_ID // 绉熸埛ID + } + }, + handleClick(thirdpart) { + let appid, client_id, redirect_uri, url + redirect_uri = encodeURIComponent(window.location.origin + '/#/authredirect') + if (thirdpart === 'wechat') { + appid = 'wxd1678d3f83b1d83a' + url = 'https://open.weixin.qq.com/connect/qrconnect?appid=' + appid + '&redirect_uri=' + redirect_uri + '&state=WX-BIND&response_type=code&scope=snsapi_login#wechat_redirect' + } else if (thirdpart === 'tencent') { + client_id = '101322838' + url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&state=QQ-BIND&client_id=' + client_id + '&redirect_uri=' + redirect_uri + } else if (thirdpart === 'gitee') { + client_id = '235ce26bbc59565b82c989aa3a407ce844cf59a7c5e0f9caa9bb3bf32cee5952' + url = 'https://gitee.com/oauth/authorize?response_type=code&state=GITEE-BIND&client_id=' + client_id + '&redirect_uri=' + redirect_uri + } else if (thirdpart === 'osc') { + client_id = 'neIIqlwGsjsfsA6uxNqD' + url = 'https://www.oschina.net/action/oauth2/authorize?response_type=code&client_id=' + client_id + '&state=OSC-BIND&redirect_uri=' + redirect_uri + } + openWindow(url, thirdpart, 540, 540) + }, + handleAvatarSuccess(res, file) { + this.avatarUrl = URL.createObjectURL(file.raw) + this.ruleForm2.avatar = res.data.url + }, + // 澶勭悊鏈湴鏁版嵁锛岄伩鍏嶅埛鏂颁笉鍚屾 + handleLocalData(form) { + let userInfo = getStore({ name: 'userInfo' }) - if (userInfo) { - userInfo.avatar = form.avatar - userInfo.phone = form.phone - setStore({ - name: 'userInfo', - content: userInfo, - type: 'session' - }) + if (userInfo) { + userInfo.avatar = form.avatar + userInfo.phone = form.phone + setStore({ + name: 'userInfo', + content: userInfo, + type: 'session' + }) + } + }, + // 妫�鏌ュ瘑鐮佸己搴� + checkPasswordStrength(password) { + let strength = 0 + + // 妫�鏌ラ暱搴� + if (password.length >= 8) strength++ + + // 妫�鏌ユ槸鍚﹀寘鍚暟瀛� + if (/\d/.test(password)) strength++ + + // 妫�鏌ユ槸鍚﹀寘鍚皬鍐欏瓧姣� + if (/[a-z]/.test(password)) strength++ + + // 妫�鏌ユ槸鍚﹀寘鍚ぇ鍐欏瓧姣� + if (/[A-Z]/.test(password)) strength++ + + // 妫�鏌ユ槸鍚﹀寘鍚壒娈婂瓧绗� + if (/[!@#$%^&*]/.test(password)) strength++ + + switch (strength) { + case 0: + case 1: + this.passwordLevel = '寮�' + this.passwordLevelClass = 'password-weak' + break + case 2: + case 3: + this.passwordLevel = '涓�' + this.passwordLevelClass = 'password-medium' + break + case 4: + case 5: + this.passwordLevel = '寮�' + this.passwordLevelClass = 'password-strong' + break + } } - } } - } +} </script> <style> - .avatar-uploader .el-upload { +.avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; - } +} - .avatar-uploader .el-upload:hover { - border-color: #409EFF; - } +.avatar-uploader .el-upload:hover { + border-color: #409eff; +} - .avatar-uploader-icon { +.avatar-uploader-icon { font-size: 28px !important; color: #8c939d !important; width: 178px !important; height: 178px !important; line-height: 178px !important; text-align: center !important; - } +} - .avatar { +.avatar { width: 178px; height: 178px; display: block; - } +} + +.password-input-container { + width: 100%; + .el-input { + width: 100%; + } +} + +.password-strength-indicator { + margin-top: 5px; + font-size: 12px; + color: #606266; +} + +.password-weak { + color: #f56c6c; +} + +.password-medium { + color: #e6a23c; +} + +.password-strong { + color: #67c23a; +} </style> -- Gitblit v1.9.3