eamilPassWord.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. <template>
  2. <view>
  3. <view class="password-type-2">
  4. <!--顶部返回按钮-->
  5. <text class="back-btn iconfont iconzuo" @tap="navBack"></text>
  6. <view class="login-top" :class="'bg-' + themeColor.name">
  7. <view class="desc">
  8. <view class="title">Hi~</view>
  9. <text>{{ this.$i18n.locale == 'zh' ? '找回密码' : 'RetrievePassword' }}!</text>
  10. </view>
  11. <image class="login-pic" :src="loginPic"></image>
  12. </view>
  13. <view class="login-type-content">
  14. <image class="login-bg" :src="loginBg"></image>
  15. <view class="main">
  16. <view class="login-type-form">
  17. <view class="input-item" style="display: flex;">
  18. <!-- <text class="iconfont iconxiangxiajiantou" :class="'text-' + themeColor.name"></text> -->
  19. <u-icon name="email" color="#4BC0E2" size="50"></u-icon>
  20. <input class="login-type-input" v-model="resetPasswordParams.email"
  21. :placeholder="i18n('EnterEmail')" maxlength="20" style="padding-left: 32upx;" />
  22. </view>
  23. <view class="input-item input-item-sms-code">
  24. <text class="iconfont iconyanzhengma" :class="'text-' + themeColor.name"></text>
  25. <view class="input-wrapper">
  26. <view class="rf-input-wrapper">
  27. <input type="number" class="login-type-input" v-model="resetPasswordParams.code"
  28. :placeholder="i18n('EnterVerification')" maxlength="6" />
  29. </view>
  30. <button class="sms-code-btn" :disabled="smsCodeBtnDisabled" @click="getSmsCode">
  31. <text v-if="!smsCodeBtnDisabled">{{i18n('GetVerification')}}</text>
  32. <text v-else class="sms-code-resend">{{codeSeconds}}s{{i18n('resend')}}</text>
  33. <!-- {{`重新发送 (${codeSeconds})`}}</text> -->
  34. </button>
  35. </view>
  36. </view>
  37. <view class="input-item">
  38. <text class="iconfont iconmimaffffffpx" :class="'text-' + themeColor.name"></text>
  39. <input class="login-type-input" type="password" v-model="resetPasswordParams.password"
  40. :placeholder="this.$i18n.locale == 'zh' ? '请输入密码':'Please input a password'"
  41. maxlength="20" />
  42. </view>
  43. <view class="input-item">
  44. <text class="iconfont iconmimaffffffpx" :class="'text-' + themeColor.name"></text>
  45. <input class="login-type-input" type="password"
  46. v-model="resetPasswordParams.password_repetition"
  47. :placeholder="this.$i18n.locale == 'zh' ? '请输入确认密码':'Please input a password'"
  48. maxlength="20" />
  49. </view>
  50. </view>
  51. <view class="login-type-tips">
  52. <view @tap="navTo('/pages/public/login')" class="forget-section">
  53. {{this.$i18n.locale == 'zh' ? '马上登陆' :'login'}}
  54. </view>
  55. <text @tap="toHome">{{this.$i18n.locale == 'zh' ? '返回主页' :'Home'}}</text>
  56. </view>
  57. <button class="confirm-btn" :class="'bg-' + themeColor.name" :disabled="btnLoading"
  58. :loading="btnLoading" @tap="restPassword">
  59. {{this.$i18n.locale == 'zh' ? '找回密码' : 'RetrievePassword'}}
  60. </button>
  61. </view>
  62. </view>
  63. <view class="login-type-bottom" :class="'text-' + themeColor.name">
  64. {{ appName }}{{this.$i18n.locale == 'zh' ? '版权所有' : 'Copyright'}}
  65. </view>
  66. <u-toast ref="uToast" />
  67. </view>
  68. </view>
  69. </template>
  70. <script>
  71. import {
  72. smsCode,
  73. updatePassword
  74. } from '@/api/login';
  75. import moment from '@/common/moment';
  76. export default {
  77. data() {
  78. return {
  79. resetPasswordParams: {
  80. email: '',
  81. password: '',
  82. password_repetition: '',
  83. code: ''
  84. },
  85. btnLoading: false,
  86. type: null,
  87. smsCodeBtnDisabled: true,
  88. loginBg: this.$mAssetsPath.loginBg,
  89. loginPic: this.$mAssetsPath.loginPic,
  90. appName: this.$mSettingConfig.appName,
  91. reqBody: {},
  92. codeSeconds: 0, // 验证码发送时间间隔
  93. second: 60,
  94. service: '',
  95. name: '',
  96. userInfo: [],
  97. };
  98. },
  99. onLoad(options) {
  100. const time =
  101. moment().valueOf() / 1000 - uni.getStorageSync('pwdSmsCodeTime');
  102. if (time < 60) {
  103. this.codeSeconds =
  104. this.$mConstDataConfig.sendCodeTime - parseInt(time, 10);
  105. this.handleSmsCodeTime(this.codeSeconds);
  106. } else {
  107. this.codeSeconds = this.$mConstDataConfig.sendCodeTime;
  108. this.smsCodeBtnDisabled = false;
  109. uni.removeStorageSync('pwdSmsCodeTime');
  110. }
  111. this.type = options.type;
  112. },
  113. methods: {
  114. async getSmsCode() {
  115. //获取当前邮箱的用户信息
  116. this.getUserInfo();
  117. },
  118. // 获取邮箱验证码
  119. async userInfoBack(e) {
  120. // 邮件:service:YJ
  121. this.service = "YJ";
  122. //发送验证码 判断当前是手机号还是邮箱号 短信:service:“TX" 邮件:service:“YJ
  123. let language = this.$i18n.locale;
  124. let userName = e
  125. console.log(userName);
  126. const res = await this.$myRequest({
  127. url: '/ums/umsUsers/Code',
  128. data: {
  129. account: userName,
  130. service: this.service,
  131. language
  132. },
  133. });
  134. if (res.status == '200') {
  135. this.handleSmsCodeTime(this.second);
  136. return this.$refs.uToast.show({
  137. title: res.msg,
  138. type: 'success',
  139. });
  140. } else {
  141. return this.$refs.uToast.show({
  142. title: res.msg,
  143. type: 'error',
  144. });
  145. }
  146. },
  147. //验证邮箱号合法性
  148. verificationTel(name) {
  149. if (!name) {
  150. return this.$refs.uToast.show({
  151. title: this.i18n('Themailboxcannotbeempty') + "!",
  152. type: 'warning',
  153. }); //邮箱号不能为空
  154. }
  155. const regEmail = /^[a-zA-Z0-9]+([-_.][a-zA-Z0-9]+)*@[a-zA-Z0-9]+([-_.][a-zA-Z0-9]+)*\.[a-z]{2,}$/;
  156. if (regEmail.test(name)) {
  157. return true;
  158. } else {
  159. this.$refs.uToast.show({
  160. title: this.i18n('Pleaseenterlegalemail') + "!",
  161. type: 'warning',
  162. }); //请输入合法的手机号
  163. return false;
  164. }
  165. },
  166. async getUserInfo() {
  167. var bool = this.verificationTel(this.resetPasswordParams.email);
  168. if (!bool) {
  169. return;
  170. }
  171. //校验邮箱/验证码格式
  172. let userName = this.resetPasswordParams.email
  173. // console.log('userName==', userName)
  174. this.userInfoBack(userName);
  175. //获取当前登录邮箱号的用户信息
  176. // const result = await this.$myRequest({
  177. // url: '/ums/umsUsers/getByUserName',
  178. // data: {
  179. // userName: userName
  180. // }
  181. // });
  182. // if (result.status == 200 && result.data != null && result.data != "") {
  183. // this.userInfo = result.data;
  184. // } else {
  185. // this.$refs.uToast.show({
  186. // title: this.$i18n.locale == 'zh' ? '用户不存在' : 'user does not exist',
  187. // type: 'error',
  188. // })
  189. // };
  190. },
  191. handleSmsCodeTime(time) {
  192. let timer = setInterval(() => {
  193. if (time === 0) {
  194. clearInterval(timer);
  195. this.smsCodeBtnDisabled = false;
  196. } else {
  197. this.codeSeconds = time;
  198. this.smsCodeBtnDisabled = true;
  199. time--;
  200. }
  201. }, 1000);
  202. },
  203. //后台自动登录,获取token值
  204. async codeLogin() {
  205. const that = this;
  206. this.service = "YJ";
  207. const res = await this.$myRequest({
  208. url: '/sys/token',
  209. data: {},
  210. });
  211. let token = res.data;
  212. let VCode = this.resetPasswordParams.code;
  213. this.name = this.resetPasswordParams.email
  214. let page = {
  215. email: this.name,
  216. code: VCode,
  217. grant_type: 'password',
  218. client_id: 'client_2',
  219. client_secret: '1xapp',
  220. };
  221. const login = await this.$myRequest({
  222. url: '/ums/email/login',
  223. data: page,
  224. method: 'post',
  225. type: 'formData'
  226. });
  227. if (login.msg == 'ok') {
  228. try {
  229. //存储登录账号
  230. uni.setStorageSync('user', login.data.userInfo);
  231. uni.setStorageSync('Auth-Token', login.data.access_token);
  232. uni.setStorageSync('loginAccount', that.resetPasswordParams.email);
  233. } catch (e) {
  234. }
  235. this.toUpdatePassword();
  236. } else {
  237. return this.$refs.uToast.show({
  238. title: this.$i18n.locale == 'zh' ? '修改失败请重新再试' :
  239. 'Modification failed. Please try again',
  240. type: 'error',
  241. });
  242. }
  243. },
  244. // 更新密码
  245. async toUpdatePassword() {
  246. let Storage_data;
  247. let token;
  248. try {
  249. Storage_data = JSON.parse(uni.getStorageSync('user'));
  250. token = uni.getStorageSync('Auth-Token');
  251. } catch (e) {
  252. }
  253. let userId = Storage_data.umsUser.id
  254. if (userId == "" || userId == null) {
  255. return this.$refs.uToast.show({
  256. title: this.$i18n.locale == 'zh' ? '系统繁忙,请稍后再试' :
  257. 'The system is busy. Please try again later',
  258. type: 'warning',
  259. });
  260. }
  261. if (this.resetPasswordParams.password == "" || this.resetPasswordParams.password == null) {
  262. return this.$refs.uToast.show({
  263. title: this.$i18n.locale == 'zh' ? '新密码不能为空' : 'New password cannot be empty',
  264. type: 'warning',
  265. });
  266. }
  267. if (this.resetPasswordParams.password_repetition == "" || this.resetPasswordParams
  268. .password_repetition == null) {
  269. return this.$refs.uToast.show({
  270. title: this.$i18n.locale == 'zh' ? '确认密码不能为空' : 'Confirm password cannot be empty',
  271. type: 'warning',
  272. });
  273. }
  274. //判断两次密码是否一致
  275. if (this.resetPasswordParams.password != this.resetPasswordParams.password_repetition) {
  276. return this.$refs.uToast.show({
  277. title: this.$i18n.locale == 'zh' ? '两次输入密码不一致' : 'The two passwords are inconsistent',
  278. type: 'warning',
  279. });
  280. }
  281. //校验密码格式
  282. var msg = /((?=.*\d)(?=.*\D)(?=.*[a-z])(?=.*[A-Z]))(?!^.*[\u4E00-\u9FA5].*$)^\S{8,20}$/.test(
  283. this.resetPasswordParams.password_repetition) ? "" : this.$i18n.locale == 'zh' ? '请输入8~20为密码' :
  284. 'Your password strength is too low, please enter your password';
  285. if (msg != "") {
  286. return this.$refs.uToast.show({
  287. title: msg,
  288. type: 'warning',
  289. });
  290. }
  291. let param = JSON.stringify({
  292. id: userId,
  293. password: this.resetPasswordParams.password_repetition,
  294. Authorization: token
  295. });
  296. const result = await this.$myRequest({
  297. url: '/ums/umsUsers/changePassword',
  298. data: {
  299. param: param
  300. },
  301. method: 'post'
  302. });
  303. if (result.status == '200') {
  304. this.$refs.uToast.show({
  305. title: this.$i18n.locale == 'zh' ? '密码修改成功,请使用新密码重新登录!' :
  306. 'Password modified successfully, please use the new password to login again!',
  307. type: 'success',
  308. });
  309. uni.removeStorageSync('user');
  310. uni.removeStorageSync('Auth-Token');
  311. setTimeout(() => {
  312. uni.navigateTo({
  313. url: `/pages/public/login`
  314. });
  315. }, 2000);
  316. } else {
  317. this.$refs.uToast.show({
  318. title: result.msg,
  319. type: 'error',
  320. });
  321. try {
  322. uni.removeStorageSync('user');
  323. uni.removeStorageSync('Auth-Token');
  324. } catch (e) {
  325. }
  326. }
  327. },
  328. //重置密码
  329. async restPassword() {
  330. if (!this.resetPasswordParams.code) {
  331. this.$refs.uToast.show({
  332. title: this.$i18n.locale == 'zh' ? '验证码不能为空' : 'verificationCode cannot be empty',
  333. type: 'warning',
  334. });
  335. return;
  336. }
  337. this.codeLogin();
  338. },
  339. i18n(data) {
  340. return this.$t('common.' + data);
  341. },
  342. navBack() {
  343. this.$mRouter.back();
  344. },
  345. navTo(route) {
  346. this.$mRouter.push({
  347. route
  348. });
  349. },
  350. toHome() {
  351. this.$mRouter.reLaunch({
  352. route: '/pages/index/index'
  353. });
  354. },
  355. }
  356. };
  357. </script>
  358. <style lang="scss">
  359. page {
  360. background: $color-white;
  361. }
  362. .password-type-2 {
  363. width: 100%;
  364. position: relative;
  365. .back-btn {
  366. position: absolute;
  367. left: 40upx;
  368. z-index: 9999;
  369. padding-top: var(--status-bar-height);
  370. top: 40upx;
  371. font-size: 48upx;
  372. color: $color-white;
  373. }
  374. .login-top {
  375. height: 460upx;
  376. position: relative;
  377. .desc {
  378. position: absolute;
  379. top: 200upx;
  380. left: 40upx;
  381. font-size: 48upx;
  382. z-index: 2;
  383. .title {
  384. font-size: 48upx;
  385. }
  386. }
  387. .login-pic {
  388. position: absolute;
  389. width: 750upx;
  390. height: 270upx;
  391. right: 30upx;
  392. top: 100upx;
  393. z-index: 1;
  394. }
  395. }
  396. .login-type-content {
  397. position: relative;
  398. top: -72upx;
  399. .login-bg {
  400. width: 94vw;
  401. height: 114vw;
  402. margin: 0 3vw;
  403. }
  404. .main {
  405. width: 94vw;
  406. position: absolute;
  407. top: 0;
  408. left: 3vw;
  409. .nav-bar {
  410. display: flex;
  411. height: 100upx;
  412. justify-content: center;
  413. align-items: center;
  414. position: relative;
  415. z-index: 10;
  416. .nav-bar-item {
  417. flex: 1;
  418. display: flex;
  419. height: 100%;
  420. line-height: 96upx;
  421. font-size: $font-lg;
  422. display: flex;
  423. margin: 0 120upx;
  424. justify-content: center;
  425. }
  426. .nav-bar-item-active {
  427. border-bottom: 5upx solid;
  428. }
  429. }
  430. .login-type-form {
  431. width: 80%;
  432. margin: 50upx auto;
  433. .input-item {
  434. position: relative;
  435. height: 90upx;
  436. line-height: 90upx;
  437. margin-bottom: $spacing-lg;
  438. .iconfont {
  439. font-size: 50upx;
  440. position: absolute;
  441. left: 0;
  442. }
  443. .login-type-input {
  444. height: 90upx;
  445. padding-left: 80upx;
  446. border-bottom: 1upx solid rgba(0, 0, 0, .1);
  447. }
  448. .sms-code-btn,
  449. sms-code-resend {
  450. width: 240upx;
  451. font-size: $font-base - 2upx;
  452. }
  453. }
  454. }
  455. .login-type-tips {
  456. padding: 0 50upx;
  457. display: flex;
  458. justify-content: space-between;
  459. }
  460. .confirm-btn {
  461. height: 80upx;
  462. line-height: 80upx;
  463. }
  464. }
  465. }
  466. .login-type-bottom {
  467. width: 100%;
  468. padding-bottom: 30upx;
  469. text-align: center;
  470. font-size: $font-lg;
  471. }
  472. }
  473. </style>