MiniForgotpad.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. <template>
  2. <div class="aui-content">
  3. <div class="aui-container">
  4. <div class="aui-form">
  5. <div class="aui-image">
  6. <div class="aui-image-text">
  7. <img :src="adTextImg" alt="" />
  8. </div>
  9. </div>
  10. <div class="aui-formBox">
  11. <div class="aui-formWell">
  12. <div class="aui-step-box">
  13. <div class="aui-step-item" :class="activeKey === 1 ? 'activeStep' : ''">
  14. <div class="aui-step-tags">
  15. <em>1</em>
  16. <p>{{t('sys.login.authentication')}}</p>
  17. </div>
  18. </div>
  19. <div class="aui-step-item" :class="activeKey === 2 ? 'activeStep' : ''">
  20. <div class="aui-step-tags">
  21. <em>2</em>
  22. <p>{{t('sys.login.resetLoginPassword')}}</p>
  23. </div>
  24. </div>
  25. <div class="aui-step-item" :class="activeKey === 3 ? 'activeStep' : ''">
  26. <div class="aui-step-tags">
  27. <em>3</em>
  28. <p>{{t('sys.login.resetSuccess')}}</p>
  29. </div>
  30. </div>
  31. </div>
  32. <div class="" style="height: 230px; position: relative">
  33. <a-form ref="formRef" :model="formData" v-if="activeKey === 1">
  34. <!-- 身份验证 begin -->
  35. <div class="aui-account aui-account-line aui-forgot">
  36. <a-form-item>
  37. <div class="aui-input-line">
  38. <a-input type="text" :placeholder="t('sys.login.mobile')" v-model:value="formData.mobile" />
  39. </div>
  40. </a-form-item>
  41. <div class="aui-input-line">
  42. <a-form-item>
  43. <a-input type="text" :placeholder="t('sys.login.smsCode')" v-model:value="formData.smscode" />
  44. </a-form-item>
  45. <div v-if="showInterval" class="aui-code-line" @click="getLoginCode">{{t('component.countdown.normalText')}}</div>
  46. <div v-else class="aui-code-line">{{t('component.countdown.sendText',[unref(timeRuning)])}}</div>
  47. </div>
  48. </div>
  49. <!-- 身份验证 end -->
  50. </a-form>
  51. <a-form ref="pwdFormRef" :model="pwdFormData" v-else-if="activeKey === 2">
  52. <!-- 重置密码 begin -->
  53. <div class="aui-account aui-account-line aui-forgot">
  54. <a-form-item>
  55. <div class="aui-input-line">
  56. <a-input type="password" :placeholder="t('sys.login.passwordPlaceholder')" v-model:value="pwdFormData.password" />
  57. </div>
  58. </a-form-item>
  59. <a-form-item>
  60. <div class="aui-input-line">
  61. <a-input type="password" :placeholder="t('sys.login.confirmPassword')" v-model:value="pwdFormData.confirmPassword" />
  62. </div>
  63. </a-form-item>
  64. </div>
  65. <!-- 重置密码 end -->
  66. </a-form>
  67. <!-- 重置成功 begin -->
  68. <div class="aui-success" v-else>
  69. <div class="aui-success-icon">
  70. <img :src="successImg"/>
  71. </div>
  72. <h3>恭喜您,重置密码成功!</h3>
  73. </div>
  74. <!-- 重置成功 end -->
  75. </div>
  76. <div class="aui-formButton" style="padding-bottom: 40px">
  77. <div class="aui-flex" v-if="activeKey === 1 || activeKey === 2">
  78. <a class="aui-link-login aui-flex-box" @click="nextStepClick">{{t('sys.login.nextStep')}}</a>
  79. </div>
  80. <div class="aui-flex" v-else>
  81. <a class="aui-linek-code aui-flex-box" @click="toLogin">{{t('sys.login.goToLogin')}}</a>
  82. </div>
  83. <div class="aui-flex">
  84. <a class="aui-linek-code aui-flex-box" @click="goBack"> {{ t('sys.login.backSignIn') }}</a>
  85. </div>
  86. </div>
  87. </div>
  88. </div>
  89. </div>
  90. </div>
  91. </div>
  92. </template>
  93. <script lang="ts" name="mini-forgotpad" setup>
  94. import { reactive, ref, toRaw, unref } from 'vue';
  95. import { useI18n } from '/@/hooks/web/useI18n';
  96. import { SmsEnum, useFormRules, useFormValid, useLoginState } from '/@/views/sys/login/useLogin';
  97. import { useMessage } from '/@/hooks/web/useMessage';
  98. import { getCaptcha, passwordChange, phoneVerify } from '/@/api/sys/user';
  99. import logoImg from '/@/assets/loginmini/icon/jeecg_logo.png'
  100. import adTextImg from '/@/assets/loginmini/icon/jeecg_ad_text.png'
  101. import successImg from '/@/assets/loginmini/icon/icon-success.png'
  102. //下一步控制
  103. const activeKey = ref<number>(1);
  104. const { t } = useI18n();
  105. const { handleBackLogin } = useLoginState();
  106. const { notification, createMessage, createErrorModal } = useMessage();
  107. //是否显示获取验证码
  108. const showInterval = ref<boolean>(true);
  109. //60s
  110. const timeRuning = ref<number>(60);
  111. //定时器
  112. const timer = ref<any>(null);
  113. const formRef = ref();
  114. const pwdFormRef = ref();
  115. //账号数据
  116. const accountInfo = reactive<any>({});
  117. //手机号表单
  118. const formData = reactive({
  119. mobile: '',
  120. smscode: '',
  121. });
  122. //密码表单
  123. const pwdFormData = reactive<any>({
  124. password: '',
  125. confirmPassword: '',
  126. });
  127. const emit = defineEmits(['go-back', 'success', 'register']);
  128. /**
  129. * 下一步
  130. */
  131. async function handleNext() {
  132. if (!formData.mobile) {
  133. createMessage.warn(t('sys.login.mobilePlaceholder'));
  134. return;
  135. }
  136. if (!formData.smscode) {
  137. createMessage.warn(t('sys.login.smsPlaceholder'));
  138. return;
  139. }
  140. const resultInfo = await phoneVerify(
  141. toRaw({
  142. phone: formData.mobile,
  143. smscode: formData.smscode,
  144. })
  145. );
  146. if (resultInfo.success) {
  147. Object.assign(accountInfo, {
  148. username: resultInfo.result.username,
  149. phone: formData.mobile,
  150. smscode: formData.smscode,
  151. });
  152. activeKey.value = 2;
  153. setTimeout(()=>{
  154. pwdFormRef.value.resetFields();
  155. },300)
  156. } else {
  157. notification.error({
  158. message: '错误提示',
  159. description: resultInfo.message || t('sys.api.networkExceptionMsg'),
  160. duration: 3,
  161. });
  162. }
  163. }
  164. /**
  165. * 完成修改密码
  166. */
  167. async function finishedPwd() {
  168. if (!pwdFormData.password) {
  169. createMessage.warn(t('sys.login.passwordPlaceholder'));
  170. return;
  171. }
  172. if (!pwdFormData.confirmPassword) {
  173. createMessage.warn(t('sys.login.confirmPassword'));
  174. return;
  175. }
  176. if (pwdFormData.password !== pwdFormData.confirmPassword) {
  177. createMessage.warn(t('sys.login.diffPwd'));
  178. return;
  179. }
  180. const resultInfo = await passwordChange(
  181. toRaw({
  182. username: accountInfo.username,
  183. password: pwdFormData.password,
  184. smscode: accountInfo.smscode,
  185. phone: accountInfo.phone,
  186. })
  187. );
  188. if (resultInfo.success) {
  189. accountInfo.password = pwdFormData.password;
  190. //修改密码
  191. activeKey.value = 3;
  192. } else {
  193. //错误提示
  194. createErrorModal({
  195. title: t('sys.api.errorTip'),
  196. content: resultInfo.message || t('sys.api.networkExceptionMsg'),
  197. });
  198. }
  199. }
  200. /**
  201. * 下一步
  202. */
  203. function nextStepClick() {
  204. if (unref(activeKey) == 1) {
  205. handleNext();
  206. } else if (unref(activeKey) == 2) {
  207. finishedPwd();
  208. }
  209. }
  210. /**
  211. * 去登录
  212. */
  213. function toLogin() {
  214. emit('success', { username: accountInfo.username, password: accountInfo.password });
  215. initForm();
  216. }
  217. /**
  218. * 返回
  219. */
  220. function goBack() {
  221. emit('go-back');
  222. initForm();
  223. }
  224. /**
  225. * 获取手机验证码
  226. */
  227. async function getLoginCode() {
  228. if (!formData.mobile) {
  229. createMessage.warn(t('sys.login.mobilePlaceholder'));
  230. return;
  231. }
  232. const result = await getCaptcha({ mobile: formData.mobile, smsmode: SmsEnum.FORGET_PASSWORD });
  233. if (result) {
  234. const TIME_COUNT = 60;
  235. if (!unref(timer)) {
  236. timeRuning.value = TIME_COUNT;
  237. showInterval.value = false;
  238. timer.value = setInterval(() => {
  239. if (unref(timeRuning) > 0 && unref(timeRuning) <= TIME_COUNT) {
  240. timeRuning.value = timeRuning.value - 1;
  241. } else {
  242. showInterval.value = true;
  243. clearInterval(unref(timer));
  244. timer.value = null;
  245. }
  246. }, 1000);
  247. }
  248. }
  249. }
  250. /**
  251. * 初始化表单
  252. */
  253. function initForm() {
  254. activeKey.value = 1;
  255. Object.assign(formData, { phone: '', smscode: '' });
  256. Object.assign(pwdFormData, { password: '', confirmPassword: '' });
  257. Object.assign(accountInfo, {});
  258. if(unref(timer)){
  259. clearInterval(unref(timer));
  260. timer.value = null;
  261. showInterval.value = true;
  262. }
  263. setTimeout(()=>{
  264. formRef.value.resetFields();
  265. },300)
  266. }
  267. defineExpose({
  268. initForm,
  269. });
  270. </script>
  271. <style lang="less" scoped>
  272. @import '/@/assets/loginmini/style/home.less';
  273. @import '/@/assets/loginmini/style/base.less';
  274. </style>