forgotPassword.tsx 8.9 KB

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