forked from integrated_whb/integrated_whb_vue
				
			feat(security): 修改默认密码并增加密码强度验证
- 将默认密码从 "Aa@123456" 修改为 "Jtys@123456" - 在用户信息页面添加修改密码对话框,增加密码强度验证 - 更新登录逻辑,传递密码类型和令牌到首页 - 修改密码后自动登出并重定向到登录页面dev
							parent
							
								
									c28fec0270
								
							
						
					
					
						commit
						4f0a07f2fc
					
				|  | @ -23,9 +23,6 @@ | ||||||
|           autocomplete="off" |           autocomplete="off" | ||||||
|         /> |         /> | ||||||
|       </el-form-item> |       </el-form-item> | ||||||
|       <el-form-item label="姓名" prop="NAME"> |  | ||||||
|         <el-input v-model="form.NAME" placeholder="这里输入姓名..." /> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="邮箱" prop="EMAIL"> |       <el-form-item label="邮箱" prop="EMAIL"> | ||||||
|         <el-input v-model="form.EMAIL" placeholder="这里输入邮箱..." /> |         <el-input v-model="form.EMAIL" placeholder="这里输入邮箱..." /> | ||||||
|       </el-form-item> |       </el-form-item> | ||||||
|  | @ -46,13 +43,14 @@ | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script setup> | <script setup> | ||||||
| import { getVerifyDuplicateEmail, setUserInfo } from "@/request/api.js"; | import {getVerifyDuplicateEmail, logout, setUserInfo} from "@/request/api.js"; | ||||||
| import { useVModels } from "@vueuse/core"; | import { useVModels } from "@vueuse/core"; | ||||||
| import { debounce } from "throttle-debounce"; | import { debounce } from "throttle-debounce"; | ||||||
| import useFormValidate from "@/assets/js/useFormValidate.js"; | import useFormValidate from "@/assets/js/useFormValidate.js"; | ||||||
| import { ElMessage } from "element-plus"; | import { ElMessage } from "element-plus"; | ||||||
| import { useUserStore } from "@/pinia/user.js"; | import { useUserStore } from "@/pinia/user.js"; | ||||||
| import { ref } from "vue"; | import { ref } from "vue"; | ||||||
|  | import {useRouter} from "vue-router"; | ||||||
| 
 | 
 | ||||||
| const userStore = useUserStore(); | const userStore = useUserStore(); | ||||||
| const props = defineProps({ | const props = defineProps({ | ||||||
|  | @ -69,6 +67,7 @@ const props = defineProps({ | ||||||
| }); | }); | ||||||
| const emits = defineEmits(["update:visible", "update:form", "get-data"]); | const emits = defineEmits(["update:visible", "update:form", "get-data"]); | ||||||
| const { visible, form } = useVModels(props, emits); | const { visible, form } = useVModels(props, emits); | ||||||
|  | const router = useRouter(); | ||||||
| const formRef = ref(null); | const formRef = ref(null); | ||||||
| const validatePass = (rule, value, callback) => { | const validatePass = (rule, value, callback) => { | ||||||
|   if (value) { |   if (value) { | ||||||
|  | @ -106,7 +105,6 @@ const validateEmail = async (rule, value, callback) => { | ||||||
|   } else callback(); |   } else callback(); | ||||||
| }; | }; | ||||||
| const rules = { | const rules = { | ||||||
|   NAME: [{ required: true, message: "姓名不能为空", trigger: "blur" }], |  | ||||||
|   EMAIL: [ |   EMAIL: [ | ||||||
|     { required: false, message: "请输入邮箱", trigger: "blur" }, |     { required: false, message: "请输入邮箱", trigger: "blur" }, | ||||||
|     { |     { | ||||||
|  | @ -133,12 +131,17 @@ const fnSubmit = debounce( | ||||||
|       ...form.value, |       ...form.value, | ||||||
|       PASSWORD: form.value.newpwd, |       PASSWORD: form.value.newpwd, | ||||||
|     }); |     }); | ||||||
|     fnClose(); |  | ||||||
|     ElMessage.success("修改成功"); |     ElMessage.success("修改成功"); | ||||||
|  |     await fnSignOut(); | ||||||
|     emits("get-data"); |     emits("get-data"); | ||||||
|   }, |   }, | ||||||
|   { atBegin: true } |   { atBegin: true } | ||||||
| ); | ); | ||||||
|  | const fnSignOut = async () => { | ||||||
|  |   await logout(); | ||||||
|  |   userStore.$reset(); | ||||||
|  |   await router.replace("/login"); | ||||||
|  | }; | ||||||
| const fnClose = () => { | const fnClose = () => { | ||||||
|   formRef.value.resetFields(); |   formRef.value.resetFields(); | ||||||
|   visible.value = false; |   visible.value = false; | ||||||
|  |  | ||||||
|  | @ -615,7 +615,7 @@ const fnGetData = async () => { | ||||||
|   if (!USER_ID) return; |   if (!USER_ID) return; | ||||||
|   const resData = await getUserView({ USER_ID }); |   const resData = await getUserView({ USER_ID }); | ||||||
|   const form = resData.pd; |   const form = resData.pd; | ||||||
|   form.PASSWORD = "Aa@123456"; |   form.PASSWORD = "Jtys@123456"; | ||||||
|   form.periodStr = resData.periodStr; |   form.periodStr = resData.periodStr; | ||||||
|   form.ISSTUDENT = resData.pd.ISSTUDENT.toString(); |   form.ISSTUDENT = resData.pd.ISSTUDENT.toString(); | ||||||
|   if (form.USERAVATARURL_CONVERT) |   if (form.USERAVATARURL_CONVERT) | ||||||
|  |  | ||||||
|  | @ -261,7 +261,7 @@ onBeforeRouteUpdate((to) => { | ||||||
| const fnResetPassword = debounce( | const fnResetPassword = debounce( | ||||||
|   1000, |   1000, | ||||||
|   async (USER_ID, NAME) => { |   async (USER_ID, NAME) => { | ||||||
|     await ElMessageBox.confirm(`是否将【${NAME}】重置密码为Aa@123456?`, { |     await ElMessageBox.confirm(`是否将【${NAME}】重置密码为Jtys@123456?`, { | ||||||
|       type: "warning", |       type: "warning", | ||||||
|     }); |     }); | ||||||
|     await setUserResetPassword({ USER_ID }); |     await setUserResetPassword({ USER_ID }); | ||||||
|  |  | ||||||
|  | @ -1078,7 +1078,7 @@ const fnGetData = async () => { | ||||||
|   if (!USER_ID) return; |   if (!USER_ID) return; | ||||||
|   const resData = await getUserView({ USER_ID }); |   const resData = await getUserView({ USER_ID }); | ||||||
|   const form = resData.pd; |   const form = resData.pd; | ||||||
|   form.PASSWORD = "Aa@123456"; |   form.PASSWORD = "Jtys@123456"; | ||||||
|   form.periodStr = resData.periodStr; |   form.periodStr = resData.periodStr; | ||||||
|   form.ISSTUDENT = resData.pd.ISSTUDENT.toString(); |   form.ISSTUDENT = resData.pd.ISSTUDENT.toString(); | ||||||
|   if (form.USERAVATARURL_CONVERT) |   if (form.USERAVATARURL_CONVERT) | ||||||
|  |  | ||||||
|  | @ -980,7 +980,7 @@ const fnGetData = async (USER_ID) => { | ||||||
|   if (!USER_ID) return; |   if (!USER_ID) return; | ||||||
|   const resData = await getPractitionerForEdit({ USER_ID }); |   const resData = await getPractitionerForEdit({ USER_ID }); | ||||||
|   const form = resData.pd; |   const form = resData.pd; | ||||||
|   form.PASSWORD = "Aa@123456"; |   form.PASSWORD = "Jtys@123456"; | ||||||
|   form.periodStr = resData.periodStr; |   form.periodStr = resData.periodStr; | ||||||
|   form.ISSTUDENT = resData.pd.ISSTUDENT.toString(); |   form.ISSTUDENT = resData.pd.ISSTUDENT.toString(); | ||||||
|   if (form.USERAVATARURL_CONVERT) |   if (form.USERAVATARURL_CONVERT) | ||||||
|  |  | ||||||
|  | @ -952,7 +952,7 @@ const fnGetData = async () => { | ||||||
|   if (!USER_ID) return; |   if (!USER_ID) return; | ||||||
|   const resData = await getPractitionerForEdit({ USER_ID }); |   const resData = await getPractitionerForEdit({ USER_ID }); | ||||||
|   const form = resData.pd; |   const form = resData.pd; | ||||||
|   form.PASSWORD = "Aa@123456"; |   form.PASSWORD = "Jtys@123456"; | ||||||
|   form.periodStr = resData.periodStr; |   form.periodStr = resData.periodStr; | ||||||
|   form.ISSTUDENT = resData.pd.ISSTUDENT.toString(); |   form.ISSTUDENT = resData.pd.ISSTUDENT.toString(); | ||||||
|   if (form.USERAVATARURL_CONVERT) { |   if (form.USERAVATARURL_CONVERT) { | ||||||
|  |  | ||||||
|  | @ -28,6 +28,48 @@ | ||||||
|         <waybill /> |         <waybill /> | ||||||
|       </el-col> |       </el-col> | ||||||
|     </el-row> |     </el-row> | ||||||
|  |     <el-dialog | ||||||
|  |       v-model="dialogFormEdit" | ||||||
|  |       :before-close="handleClose" | ||||||
|  |       :append-to-body="true" | ||||||
|  |       title="登录的密码强度为弱,请修改密码!" | ||||||
|  |       width="600px" | ||||||
|  |     > | ||||||
|  |       <div style="padding: 0 40px"> | ||||||
|  |         <el-form | ||||||
|  |           ref="formRef" | ||||||
|  |           :model="form" | ||||||
|  |           :rules="rules" | ||||||
|  |           status-icon | ||||||
|  |           label-width="100px" | ||||||
|  |         > | ||||||
|  |           <el-form-item label="用户名"> | ||||||
|  |             <el-input | ||||||
|  |               v-model="form.USERNAME" | ||||||
|  |               disabled | ||||||
|  |               placeholder="默认用户手机号码..." | ||||||
|  |             /> | ||||||
|  |           </el-form-item> | ||||||
|  |           <el-form-item label="新密码:" prop="newpwd"> | ||||||
|  |             <el-input | ||||||
|  |               v-model="form.newpwd" | ||||||
|  |               type="password" | ||||||
|  |               auto-complete="off" | ||||||
|  |             /> | ||||||
|  |           </el-form-item> | ||||||
|  |           <el-form-item label="确认密码:" prop="newpassword1"> | ||||||
|  |             <el-input | ||||||
|  |               v-model="form.newpassword1" | ||||||
|  |               type="password" | ||||||
|  |               auto-complete="off" | ||||||
|  |             /> | ||||||
|  |           </el-form-item> | ||||||
|  |         </el-form> | ||||||
|  |         <div style="text-align: center; margin-top: 30px"> | ||||||
|  |           <el-button type="primary" @click="editUser">确认修改</el-button> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </el-dialog> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
|  | @ -41,6 +83,92 @@ import doublePrevention from "./components/doublePrevention.vue"; | ||||||
| import info from "./components/info.vue"; | import info from "./components/info.vue"; | ||||||
| import statistics from "./components/statistics.vue"; | import statistics from "./components/statistics.vue"; | ||||||
| import waybill from "./components/waybill.vue"; | import waybill from "./components/waybill.vue"; | ||||||
|  | import { debounce } from "throttle-debounce"; | ||||||
|  | import { logout, setUserInfo } from "@/request/api.js"; | ||||||
|  | import { ElMessage } from "element-plus"; | ||||||
|  | import { useUserStore } from "@/pinia/user.js"; | ||||||
|  | import { useRoute, useRouter } from "vue-router"; | ||||||
|  | import { ref, onMounted } from "vue"; | ||||||
|  | import useFormValidate from "@/assets/js/useFormValidate.js"; | ||||||
|  | const userStore = useUserStore(); | ||||||
|  | 
 | ||||||
|  | const form = ref({ | ||||||
|  |   USERNAME: userStore.getUserInfo.USERNAME, | ||||||
|  |   newpwd: "", | ||||||
|  |   newpassword1: "", | ||||||
|  | }); | ||||||
|  | const formRef = ref(null); | ||||||
|  | const router = useRouter(); | ||||||
|  | const route = useRoute(); | ||||||
|  | const passwordType = route.query.passwordType; | ||||||
|  | const dialogFormEdit = ref(false); | ||||||
|  | 
 | ||||||
|  | onMounted(() => { | ||||||
|  |   // 检查 passwordType 是否为 '0'(路由参数是字符串类型) | ||||||
|  |   if (passwordType === "0") { | ||||||
|  |     dialogFormEdit.value = true; | ||||||
|  |     console.log(dialogFormEdit.value); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const validatePass = (rule, value, callback) => { | ||||||
|  |   if (value) { | ||||||
|  |     const reg1 = | ||||||
|  |       /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[~!@#$%^&*.])[\da-zA-Z~!@#$%^&*.]{8,}$/; | ||||||
|  |     if (!reg1.test(value)) { | ||||||
|  |       callback( | ||||||
|  |         new Error("密码必须是8位以上、必须包含大小写字母、数字、特殊符号") | ||||||
|  |       ); | ||||||
|  |     } else { | ||||||
|  |       callback(); | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     callback(); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | const validatePass2 = (rule, value, callback) => { | ||||||
|  |   if (form.value.newpwd && !value) { | ||||||
|  |     callback(new Error("请再次输入新密码")); | ||||||
|  |   } else if (form.value.newpwd && value && value !== form.value.newpwd) { | ||||||
|  |     callback(new Error("两次输入密码不一致!")); | ||||||
|  |   } else callback(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const rules = { | ||||||
|  |   newpwd: [ | ||||||
|  |     { required: false, message: "请输入新密码", trigger: "blur" }, | ||||||
|  |     { required: true, validator: validatePass, trigger: "blur" }, | ||||||
|  |   ], | ||||||
|  |   newpassword1: [ | ||||||
|  |     { required: false, validator: validatePass2, trigger: "blur" }, | ||||||
|  |   ], | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const editUser = debounce( | ||||||
|  |   1000, | ||||||
|  |   async () => { | ||||||
|  |     await useFormValidate(formRef); | ||||||
|  |     await setUserInfo({ | ||||||
|  |       USER_ID: userStore.getUserInfo.USER_ID, | ||||||
|  |       OPERATIONTYPE: "1", | ||||||
|  |       ...form.value, | ||||||
|  |       PASSWORD: form.value.newpwd, | ||||||
|  |     }); | ||||||
|  |     ElMessage.success("修改成功"); | ||||||
|  |     await fnSignOut(); | ||||||
|  |   }, | ||||||
|  |   { atBegin: true } | ||||||
|  | ); | ||||||
|  | const fnSignOut = async () => { | ||||||
|  |   await logout(); | ||||||
|  |   userStore.$reset(); | ||||||
|  |   await router.replace("/login"); | ||||||
|  | }; | ||||||
|  | const handleClose = (done) => { | ||||||
|  |   if (!dialogFormEdit.value) { | ||||||
|  |     done(); | ||||||
|  |   } | ||||||
|  | }; | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
|  |  | ||||||
|  | @ -143,11 +143,18 @@ const fnSubmitLogin = async () => { | ||||||
|     KEYDATA, |     KEYDATA, | ||||||
|     SOURCE: 1, |     SOURCE: 1, | ||||||
|   }); |   }); | ||||||
|  |   console.log(resData,'123') | ||||||
|   await userStore.setUserInfo({ |   await userStore.setUserInfo({ | ||||||
|     ...userStore.getUserInfo, |     ...userStore.getUserInfo, | ||||||
|     ...resData, |     ...resData, | ||||||
|   }); |   }); | ||||||
|   await router.replace("/index"); |   await router.replace({ | ||||||
|  |     path: "/index", | ||||||
|  |     query: { | ||||||
|  |       passwordType: resData.passwordType, | ||||||
|  |       token: resData.token, // 传递令牌 | ||||||
|  |     }, | ||||||
|  |   }); | ||||||
| }; | }; | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue