forgotPassword.tsx 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. import { defineComponent, reactive, ref } from 'vue';
  2. import styles from '../index.module.less';
  3. import pwdIcon from '../images/lock-icon.png';
  4. import lockIcon from '../images/pwdIcon.png';
  5. import useIcon from '../images/phoneIcon.png';
  6. import openEye from '../images/openEye.png';
  7. import closeEye from '../images/closeEye.png';
  8. import {
  9. useMessage,
  10. NForm,
  11. NFormItem,
  12. NInput,
  13. NButton,
  14. NInputGroup
  15. } from 'naive-ui';
  16. import { useRoute, useRouter } from 'vue-router';
  17. import { PageEnum } from '/src/enums/pageEnum';
  18. import { storage } from '@/utils/storage';
  19. import { useUserStore } from '/src/store/modules/users';
  20. import { sendSms, updatePassword } from '../api';
  21. interface FormState {
  22. mobile: string;
  23. password: string;
  24. grant_type: string;
  25. loginType: string;
  26. client_id: string;
  27. client_secret: string;
  28. }
  29. export default defineComponent({
  30. name: 'forgotPassword',
  31. emits: ['changType'],
  32. setup(props, { emit }) {
  33. const router = useRouter();
  34. const route = useRoute();
  35. const formRef = ref();
  36. const message = useMessage();
  37. const loading = ref(false);
  38. const autoLogin = ref(true);
  39. const LOGIN_NAME = PageEnum.BASE_LOGIN_NAME;
  40. const showPwd = ref(false);
  41. const showPwd2 = ref(false);
  42. const userStore = useUserStore();
  43. const formInline = reactive({
  44. mobile: '',
  45. password: '',
  46. password1: '',
  47. code: '',
  48. isCaptcha: true
  49. });
  50. const isDisabledCode = ref(false);
  51. const starTimer = ref(60);
  52. const codeName = '发送短信';
  53. const validatePass2 = (rule: any, value: any, callback: any) => {
  54. const reg = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/;
  55. if (value === '') {
  56. callback(new Error('请再次输入密码'));
  57. } else if (value !== formInline.password) {
  58. callback(new Error('两次输入密码不一致!'));
  59. } else if (!reg.test(value)) {
  60. callback(new Error('密码为6-20位数字和字母组合'));
  61. } else {
  62. callback();
  63. }
  64. };
  65. const handleSubmit = async () => {
  66. formRef.value.validate(async (errors: any) => {
  67. if (!errors) {
  68. message.loading('修改中...');
  69. loading.value = true;
  70. try {
  71. await updatePassword({
  72. ...formInline,
  73. clientType: 'TEACHER'
  74. });
  75. message.success('修改成功');
  76. loading.value = false;
  77. emit('changType');
  78. return false;
  79. } catch (e: any) {
  80. loading.value = false;
  81. message.error(e.msg);
  82. return false;
  83. console.log(e);
  84. }
  85. }
  86. });
  87. return false;
  88. };
  89. const sendMessage = async () => {
  90. if (!formInline.mobile) {
  91. message.error('请输入手机号');
  92. return;
  93. }
  94. try {
  95. const res = await sendSms({
  96. clientId: 'cooleshow-teacher',
  97. mobile: formInline.mobile,
  98. type: 'PASSWORD'
  99. });
  100. checkTimeOut();
  101. } catch (e) {
  102. console.log(e);
  103. }
  104. };
  105. const checkTimeOut = () => {
  106. if (isDisabledCode.value) {
  107. return;
  108. }
  109. isDisabledCode.value = true;
  110. const tiemr = setInterval(() => {
  111. starTimer.value--;
  112. console.log(starTimer.value);
  113. if (starTimer.value <= 0) {
  114. isDisabledCode.value = false;
  115. clearInterval(tiemr);
  116. }
  117. }, 1000);
  118. };
  119. return () => (
  120. <div class={styles['view-account-form-wrap']}>
  121. {/* <div class={styles.formTitle}>
  122. <div class={styles.dot}></div>
  123. 酷乐秀课堂乐器
  124. </div> */}
  125. <NForm
  126. ref={formRef}
  127. label-placement="left"
  128. size="large"
  129. model={formInline}>
  130. <NFormItem
  131. path="mobile"
  132. rule={[
  133. { required: true, message: '请输入手机号', trigger: 'blur' }
  134. ]}>
  135. <NInput
  136. maxlength={11}
  137. v-model:value={formInline.mobile}
  138. placeholder="请输入手机号">
  139. {{
  140. prefix: () => (
  141. <img src={useIcon} class={styles.prefixIcon} alt="" />
  142. )
  143. }}
  144. </NInput>
  145. </NFormItem>
  146. <NFormItem
  147. path="password"
  148. rule={[
  149. {
  150. pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/,
  151. message: '密码为6-20位数字和字母组合',
  152. trigger: 'blur'
  153. }
  154. ]}>
  155. <NInput
  156. v-model:value={formInline.password}
  157. type="text"
  158. showPasswordOn="click"
  159. placeholder="请输入密码"
  160. inputProps={{ autocomplete: 'off' }}
  161. class={[showPwd.value ? '' : styles['no-pwd']]}>
  162. {{
  163. prefix: () => (
  164. <img src={pwdIcon} class={styles.prefixIcon} alt="" />
  165. ),
  166. suffix: () => (
  167. <img
  168. src={showPwd.value ? openEye : closeEye}
  169. class={styles.pwdIcon}
  170. alt=""
  171. onClick={() => {
  172. showPwd.value = !showPwd.value;
  173. }}
  174. />
  175. )
  176. }}
  177. </NInput>
  178. </NFormItem>
  179. <NFormItem
  180. path="password1"
  181. rule={[
  182. {
  183. validator: validatePass2 as any,
  184. trigger: 'blur',
  185. required: true
  186. }
  187. ]}>
  188. <NInput
  189. v-model:value={formInline.password1}
  190. type="text"
  191. showPasswordOn="click"
  192. placeholder="请确认密码"
  193. inputProps={{ autocomplete: 'off' }}
  194. class={[showPwd2.value ? '' : styles['no-pwd']]}>
  195. {{
  196. prefix: () => (
  197. <img src={pwdIcon} class={styles.prefixIcon} alt="" />
  198. ),
  199. suffix: () => (
  200. <img
  201. src={showPwd2.value ? openEye : closeEye}
  202. class={styles.pwdIcon}
  203. alt=""
  204. onClick={() => {
  205. showPwd2.value = !showPwd2.value;
  206. }}
  207. />
  208. )
  209. }}
  210. </NInput>
  211. </NFormItem>
  212. <NFormItem
  213. path="code"
  214. rule={[
  215. { required: true, message: '请输入验证码', trigger: 'blur' }
  216. ]}>
  217. <NInputGroup>
  218. <NInput
  219. v-model:value={formInline.code}
  220. type="text"
  221. showPasswordOn="click"
  222. placeholder="请输入验证码"
  223. inputProps={{ autocomplete: 'off' }}
  224. class={styles.sendInput}
  225. onKeydown={(e: KeyboardEvent) => {
  226. if (e.code === 'Enter') {
  227. handleSubmit();
  228. }
  229. }}>
  230. {{
  231. prefix: () => (
  232. <img src={lockIcon} class={styles.prefixIcon} alt="" />
  233. ),
  234. suffix: () => (
  235. <NButton
  236. class={styles.sendMsg}
  237. disabled={isDisabledCode.value}
  238. onClick={() => sendMessage()}>
  239. {isDisabledCode.value ? starTimer.value : codeName}
  240. </NButton>
  241. )
  242. }}
  243. </NInput>
  244. </NInputGroup>
  245. </NFormItem>
  246. <NFormItem>
  247. <NButton
  248. class={[styles.submitBtm, styles.submitForgoBtm]}
  249. type="primary"
  250. onClick={handleSubmit}
  251. size="large"
  252. disabled={loading.value}
  253. block>
  254. 确认
  255. </NButton>
  256. </NFormItem>
  257. <NFormItem>
  258. <NButton
  259. text
  260. class={styles.forgetBtm}
  261. onClick={() => {
  262. emit('changType');
  263. }}
  264. size="large"
  265. block>
  266. 返回登录
  267. </NButton>
  268. </NFormItem>
  269. </NForm>
  270. </div>
  271. );
  272. }
  273. });