ForgetPassModel.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. <template>
  2. <div class="forget-pass-model">
  3. <div class="header-nav" @click="changeModel">
  4. <span><i class="el-icon-back"></i></span>
  5. <span><!-- 忘记密码 -->{{ $t('LoginPage.label_forget') }}</span>
  6. </div>
  7. <div class="step-container model-wrap" v-show="currentStep===0">
  8. <el-form
  9. ref="modelForm"
  10. label-position="right"
  11. label-width="0px"
  12. :model="form"
  13. :rules="rules">
  14. <el-form-item prop="account">
  15. <el-input
  16. type="text"
  17. v-model="form.account"
  18. auto-complete="off"
  19. :placeholder="$t('LoginPage.ph_account')">
  20. </el-input>
  21. </el-form-item>
  22. <el-form-item prop="picCode">
  23. <el-input
  24. class="input-with-slot"
  25. type="text"
  26. v-model="form.picCode"
  27. auto-complete="off"
  28. :placeholder="$t('LoginPage.ph_img_code')"
  29. >
  30. <div class="pic-box" slot="append" @click="getCodePic">
  31. <img :src="picSrc" alt="图形验证码"/>
  32. </div>
  33. </el-input>
  34. </el-form-item>
  35. </el-form>
  36. <el-button class="submit_btn" @click="getUserInfo"><!-- 下一步 -->{{ $t('Dialog.next_step') }}</el-button>
  37. </div>
  38. <div class="step-container" v-show="currentStep>0">
  39. <div class="container-header">
  40. <p> {{ $t('LoginPage.label_find_pwd',{name: form.account}) }}</p>
  41. <ModelSteps :active-step="currentStep"/>
  42. </div>
  43. <div class="container-inner model-wrap" v-show="currentStep===1">
  44. <VerificationBox
  45. verifies-type="mobile"
  46. :info-text="userMobile||$t('LoginPage.label_not_bind')"
  47. :hideBtn="!userMobile"
  48. @goNext="getCode"
  49. />
  50. <VerificationBox
  51. verifies-type="email"
  52. :info-text="userEmail||$t('LoginPage.label_not_bind')"
  53. :hideBtn="!userEmail"
  54. @goNext="getCode"
  55. />
  56. </div>
  57. <div class="container-inner" v-show="currentStep===2">
  58. <CaptchaInput
  59. ref="captInput"
  60. />
  61. <div class="btn-wrap">
  62. <el-button type="primary" plain @click="changeModel"><!-- 上一步 -->{{ $t('Dialog.prev_step') }}</el-button>
  63. <el-button type="primary" @click="checkInput"><!-- 下一步 -->{{ $t('Dialog.next_step') }}</el-button>
  64. </div>
  65. </div>
  66. <div class="container-inner model-wrap" v-show="currentStep===3">
  67. <el-form
  68. ref="passForm"
  69. label-position="right"
  70. label-width="0px"
  71. :model="passForm"
  72. :rules="passRules">
  73. <el-form-item prop="pass1">
  74. <el-input
  75. type="password" show-password
  76. v-model.trim="passForm.pass1"
  77. auto-complete="off"
  78. @copy.native.capture.prevent="()=>{return false}"
  79. @cut.native.capture.prevent="()=>{return false}"
  80. @paste.native.capture.prevent="()=>{return false}"
  81. :placeholder="$t('LoginPage.ph_new_pwd')">
  82. </el-input>
  83. </el-form-item>
  84. <el-form-item prop="pass2">
  85. <el-input
  86. type="password" show-password
  87. v-model.trim="passForm.pass2"
  88. auto-complete="off"
  89. @copy.native.capture.prevent="()=>{return false}"
  90. @cut.native.capture.prevent="()=>{return false}"
  91. @paste.native.capture.prevent="()=>{return false}"
  92. :placeholder="$t('ResetPwdPage.vaild_new')">
  93. </el-input>
  94. </el-form-item>
  95. </el-form>
  96. <el-button class="submit_btn" @click="handleResetPass">{{checkPassStr}}</el-button>
  97. </div>
  98. </div>
  99. </div>
  100. </template>
  101. <script>
  102. import CaptchaInput from './components/CaptchaInput.vue';
  103. import ModelSteps from './components/ModelSteps.vue';
  104. import VerificationBox from './components/VerificationBox.vue';
  105. import modelMixins from './modelMixins';
  106. import{checkPassWord} from '@/utils/commonOptions';
  107. import http from '@/api/http.js';
  108. import {departInterence } from "@/api/api.js";
  109. export default {
  110. mixins:[modelMixins],
  111. props:{
  112. autoAccount:{//自动填写的账号,如果有,作为form.accout的初始值
  113. type:String,
  114. default:''
  115. }
  116. },
  117. components: { VerificationBox, ModelSteps, CaptchaInput },
  118. data() {
  119. const validatePass = (rule,value,callback)=>{
  120. if(value===''){
  121. callback(new Error(/* '请输入新密码' */this.$t('LoginPage.ph_new_pwd')))
  122. }
  123. if(this.passForm.pass2!==''){
  124. this.$refs.passForm.validateField('pass2')
  125. }
  126. if(!checkPassWord(value)){
  127. callback(new Error(/* '密码要求8位及以上,包含数字、大写字母、小写字母、特殊字符中的三个类型' */this.$t('ResetPwdPage.vaild_rule')))
  128. }else{
  129. callback()
  130. }
  131. }
  132. const validateCheck = (rule,value,callback)=>{
  133. if(value===''){
  134. callback(new Error(/* '请输入确认密码' */this.$t('ResetPwdPage.vaild_new')))
  135. }else if(value!==this.passForm.pass1){
  136. callback(new Error(/* '两次输入的密码不一致,请检查' */this.$t('ResetPwdPage.vaild_same')))
  137. }else{
  138. callback()
  139. }
  140. }
  141. return {
  142. currentStep:0,
  143. /* form */
  144. form:{//步骤0的表单
  145. account:this.autoAccount,
  146. picCode:''
  147. },
  148. picSrc:'',
  149. picId:'',
  150. passForm:{//设置新密码的表单
  151. pass1:'',
  152. pass2:''
  153. },
  154. /* form rule */
  155. rules:{},
  156. passRules:{
  157. pass1:[{validator: validatePass,trigger: 'blur'}],
  158. pass2:[{validator: validateCheck,trigger: 'blur'}]
  159. },
  160. /*user info */
  161. userMobile:'',//用户的手机号
  162. TelAreaCode:'',//用户手机号的区号
  163. userEmail:'',//用户的邮箱
  164. /* check way */
  165. checkWay:'',//选择的验证方式
  166. authCode:'',//手机/邮箱验证码,从CaptchaInput组件中取
  167. mobileCountDown:0,//手机获取验证码倒计时
  168. emailCountDown:0,//邮箱验证码倒计时
  169. checkPassStr:'确定',//重置密码按钮
  170. countDownNum:5,
  171. resetPassTimer:0,
  172. };
  173. },
  174. created(){
  175. this.getCodePic()
  176. },
  177. methods: {
  178. //获取用户账号信息
  179. getUserInfo(){
  180. //检查form是否填写完整
  181. const {account,picCode} = this.form
  182. if(!account){
  183. this.$message.warning(/* '请输入账号' */this.$t('LoginPage.ph_account'))
  184. return
  185. }
  186. if(!picCode){
  187. this.$message.warning(/* '请输入图形验证码' */this.$t('LoginPage.ph_img_code'))
  188. return
  189. }
  190. //请求接口获取账号数据,赋值userMobile,userEmail
  191. departInterence.accountCheck({
  192. CaptchaId:this.picId,
  193. CaptchaCode:picCode,
  194. UserName:account
  195. }).then(res=>{
  196. if(res.Ret!==200){
  197. //刷新图形验证码
  198. this.getCodePic()
  199. this.form.picCode=''
  200. return
  201. }
  202. if(res.Data){
  203. this.userMobile = res.Data.Mobile||''
  204. this.userEmail = res.Data.Email||''
  205. this.TelAreaCode = res.Data.TelAreaCode||''
  206. this.goSteps()
  207. }
  208. })
  209. },
  210. //获取对应验证方式的验证码
  211. getCode(way){
  212. this.checkWay = way
  213. departInterence.getCodeVerify({
  214. VerifyType:way==='mobile'?1:2,
  215. CaptchaId:this.picId,
  216. CaptchaCode:this.form.picCode,
  217. Mobile:way==='mobile'?this.userMobile:'',
  218. TelAreaCode:way==='mobile'?this.TelAreaCode:'',
  219. Email:way==='email'?this.userEmail:'',
  220. Source:3
  221. }).then(res=>{
  222. if(res.Ret!==200) return
  223. this.goSteps()
  224. })
  225. },
  226. //检查输入的验证码
  227. checkInput(){
  228. const code = this.$refs.captInput.captchas.map((x) => x.num).join("");
  229. if(code.length!==6){
  230. this.$message.warning('请输入完整的验证码')
  231. return
  232. }
  233. departInterence.checkCodeVerify({
  234. FindType:this.checkWay==='mobile'?1:2,
  235. VerifyCode:code,
  236. UserName:this.form.account,
  237. Mobile:this.checkWay==='mobile'?this.userMobile:'',
  238. Email:this.checkWay==='email'?this.userEmail:'',
  239. TelAreaCode:this.checkWay==='mobile'?this.TelAreaCode:''
  240. }).then(res=>{
  241. if(res.Ret!==200) return
  242. this.goSteps()
  243. })
  244. },
  245. goSteps(){
  246. this.currentStep++
  247. },
  248. changeModel(){
  249. if(this.currentStep>0){
  250. this.currentStep--
  251. if(this.currentStep===0){
  252. this.getCodePic()
  253. this.form.picCode = ''
  254. }
  255. }else{
  256. this.$emit('changeModel')
  257. }
  258. },
  259. handleResetPass(){
  260. if(this.checkPassStr.includes('去登陆')){
  261. this.$emit('changeModel')
  262. return
  263. }
  264. this.$refs.passForm.validate((valid)=>{
  265. if(valid){
  266. //重置密码
  267. departInterence.resetPass({
  268. UserName:this.form.account,
  269. Password:new http.Base64().encode(this.passForm.pass1),
  270. RePassword:new http.Base64().encode(this.passForm.pass2)
  271. }).then(res=>{
  272. if(res.Ret!==200) return
  273. this.$message.success(/* '重置密码成功,请登陆' */this.$t('LoginPage.reset_pwd_success_msg'))
  274. localStorage.setItem('timeKey',Date.now())
  275. localStorage.setItem("account", new http.Base64().encode(this.form.account));
  276. localStorage.setItem("checkPass", new http.Base64().encode(this.passForm.pass1));
  277. this.resetPassCountDown()
  278. this.resetPassTimer = setInterval(()=>{
  279. this.resetPassCountDown()
  280. },1000)
  281. })
  282. }
  283. })
  284. },
  285. resetPassCountDown(){
  286. this.countDownNum--
  287. this.checkPassStr = `去登陆(${this.countDownNum}s)`
  288. if(this.countDownNum<=0){
  289. clearInterval(this.resetPassTimer)
  290. this.$emit('changeModel')
  291. return
  292. }
  293. }
  294. },
  295. };
  296. </script>
  297. <style lang="scss">
  298. @import "./css/formStyle.scss";
  299. </style>
  300. <style scoped lang="scss">
  301. .forget-pass-model{
  302. .header-nav{
  303. font-size: 38px;
  304. margin-bottom: 60px;
  305. cursor: pointer;
  306. }
  307. .step-container{
  308. .container-header{
  309. margin-bottom: 60px;
  310. p{
  311. font-size: 18px;
  312. padding-bottom: 20px;
  313. border-bottom: 1px solid #DCDFE6;
  314. margin-bottom: 60px;
  315. }
  316. .el-steps{
  317. margin-top: 60px;
  318. }
  319. }
  320. .container-inner{
  321. .btn-wrap{
  322. margin-top: 100px;
  323. text-align: center;
  324. .el-button{
  325. width:200px;
  326. }
  327. }
  328. }
  329. }
  330. }
  331. </style>