password.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <template>
  2. <div class="app-container">
  3. <van-form ref="formRef" @submit="onSubmit" class="mt10" required="auto">
  4. <van-cell-group>
  5. <van-field
  6. v-model="state.form.oldPassword"
  7. :type="state.showOldPassword ? 'text' : 'password'"
  8. label="旧密码"
  9. placeholder="旧密码"
  10. :right-icon="state.showOldPassword ? 'eye-o' : 'closed-eye'"
  11. @click-right-icon="state.showOldPassword = !state.showOldPassword"
  12. :rules="[{ required: true, message: '请输入旧密码' }]"
  13. />
  14. <van-field
  15. v-model="state.form.newPassword"
  16. :type="state.showNewPassword ? 'text' : 'password'"
  17. label="新密码"
  18. placeholder="新密码"
  19. :right-icon="state.showNewPassword ? 'eye-o' : 'closed-eye'"
  20. @click-right-icon="state.showNewPassword = !state.showNewPassword"
  21. :rules="[{ required: true, message: '请输入新密码' }, {validator: checkPassword, message: '密码不合法'}]"
  22. />
  23. <van-field
  24. v-model="state.form.newPassword2"
  25. :type="state.showNewPassword2 ? 'text' : 'password'"
  26. label="确认密码"
  27. placeholder="确认密码"
  28. :right-icon="state.showNewPassword2 ? 'eye-o' : 'closed-eye'"
  29. @click-right-icon="state.showNewPassword2 = !state.showNewPassword2"
  30. :rules="[{ required: true, message: '请输入确认密码', validator: checkConfirmPassword }]"
  31. />
  32. </van-cell-group>
  33. <div style="margin: 16px">
  34. <van-button round block type="primary" native-type="submit">保存</van-button>
  35. </div>
  36. </van-form>
  37. </div>
  38. </template>
  39. <script lang="ts" setup>
  40. import { storeToRefs } from 'pinia'
  41. import { useUserInfo } from '/@/stores/userInfo'
  42. import { Local, Session } from '/@/utils/storage'
  43. import { showConfirmDialog, showDialog, showNotify } from 'vant'
  44. import { useRouter } from 'vue-router'
  45. import { nextTick, onMounted, reactive, ref } from 'vue'
  46. import { useUserApi } from '/@/api/system/user'
  47. import to from 'await-to-js'
  48. import { useDictApi } from '/@/api/system/dict'
  49. import Cropper from 'cropperjs'
  50. import 'cropperjs/dist/cropper.css'
  51. import axios from 'axios'
  52. import crypto from 'sm-crypto';
  53. import { useLoginApi } from '/@/api/login'
  54. import { enhancedEncrypt, decryptLoginData, encryptWithBackendConfig } from '/@/utils/aesCrypto';
  55. const sm3 = crypto.sm3;
  56. const router = useRouter()
  57. const storesUseUserInfo = useUserInfo()
  58. const { userInfos } = storeToRefs(storesUseUserInfo)
  59. const userApi = useUserApi()
  60. const formRef = ref()
  61. const dictApi = useDictApi()
  62. const userSexList = ref(<RowDicDataType[]>[])
  63. const loginApi = useLoginApi()
  64. const state = reactive({
  65. showOldPassword: false,
  66. showNewPassword: false,
  67. showNewPassword2: false,
  68. form: {
  69. oldPassword: '',
  70. newPassword: '',
  71. newPassword2: '',
  72. saltValue: '',
  73. token: ''
  74. },
  75. dialog: {
  76. isShowDialog: false,
  77. type: '',
  78. title: '',
  79. submitTxt: ''
  80. }
  81. })
  82. const checkPassword = (value: string) => {
  83. // if (/^[\w\S]{6,18}$/.test(value) && /[a-z]+/.test(value) && /[A-Z]+/.test(value) && /\d+/.test(value) && /[^a-zA-Z0-9]+/.test(value)) {
  84. // return true
  85. // } else {
  86. // return '密码必须包含大小写字母、数字和特殊字符,长度在6~18之间'
  87. // }
  88. if (!value) {
  89. return "请输入新密码"
  90. }
  91. return loginApi.validatePassword({ password: value })
  92. .then(res => {
  93. return true
  94. })
  95. .catch((err) => {
  96. return err.message || "密码不合法"
  97. })
  98. }
  99. const checkConfirmPassword = (value: string) => {
  100. if (value !== state.form.newPassword) {
  101. return '两次输入的密码不一致'
  102. } else {
  103. return true
  104. }
  105. }
  106. const onSubmit = async () => {
  107. const [errValid] = await to(formRef.value.validate())
  108. if (errValid) return
  109. const params = JSON.parse(JSON.stringify(state.form))
  110. params.oldPassword = sm3(params.oldPassword)
  111. params.saltValue = encryptWithBackendConfig(params.newPassword)
  112. params.newPassword = sm3(params.newPassword)
  113. params.token = localStorage.getItem('animalToken')
  114. const [err]: ToResponse = await to(userApi.changePassword(params))
  115. if (err) return
  116. showNotify({
  117. type: 'success',
  118. message: '修改成功,请重新登录'
  119. })
  120. Session.clear();
  121. Local.remove('token')
  122. router.push('/login')
  123. }
  124. onMounted(() => {})
  125. </script>
  126. <style lang="scss" scoped>
  127. .app-container {
  128. header {
  129. background-color: #1c9bfd;
  130. color: #fff;
  131. padding: 10px;
  132. border-radius: 8px;
  133. margin-top: 10px;
  134. display: flex;
  135. img {
  136. width: 100px;
  137. height: 100px;
  138. border-radius: 50%;
  139. margin-right: 10px;
  140. }
  141. .content {
  142. flex: 1;
  143. display: flex;
  144. flex-direction: column;
  145. justify-content: space-around;
  146. overflow: hidden;
  147. .bold {
  148. display: flex;
  149. align-items: center;
  150. font-weight: bold;
  151. // flex-wrap: nowrap;
  152. white-space: nowrap;
  153. .van-text-ellipsis {
  154. flex: 1;
  155. }
  156. }
  157. }
  158. }
  159. .avatar {
  160. vertical-align: middle;
  161. }
  162. }
  163. .cropper-warp {
  164. width: 100%;
  165. display: flex;
  166. align-items: center;
  167. justify-content: center;
  168. background-color: #eee;
  169. .cropper-warp-left {
  170. height: 350px;
  171. width: 350px;
  172. }
  173. }
  174. </style>