TerminalChangePasswordDialog.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <template>
  2. <cwg-popup :title="props.pwdType == 1 ? t('vu.item3') : t('vu.item4')" :visible="props.visible" :showFooters="false"
  3. @update:visible="$emit('update:visible', $event)">
  4. <view class="popup-content">
  5. <text class="account-number">{{ accountLabel }} {{ account.login }}</text>
  6. <uni-forms :model="passwordInfo" labelWidth="200" label-position="top" class="crm-form">
  7. <uni-forms-item
  8. :label="props.pwdType == 1 ? t('Custom.Settings.LoginPwdOld') : t('Custom.Settings.InvestorPwdOld')">
  9. <uni-easyinput type="password" :clearable="false" v-model="passwordInfo.oldPassword"
  10. :placeholder="props.pwdType == 1 ? t('Custom.Settings.LoginPwdOld') : t('Custom.Settings.InvestorPwdOld')" />
  11. </uni-forms-item>
  12. <uni-forms-item :label="t('Custom.Settings.NewPwd')">
  13. <uni-easyinput type="password" :clearable="false" v-model="passwordInfo.newPassword"
  14. :placeholder="t('Custom.Settings.NewPwd')" />
  15. </uni-forms-item>
  16. </uni-forms>
  17. <view class="notice-list">
  18. <view v-for="(item, index) in noticeItems" :key="index"
  19. :class="['notice-item', item.valid ? 'isOK' : '']">
  20. {{ item.label }}
  21. </view>
  22. </view>
  23. <view class="save-btn">
  24. <view class="btn primary" @click="save" v-t="'Btn.Save'" />
  25. </view>
  26. </view>
  27. </cwg-popup>
  28. </template>
  29. <script setup>
  30. import { ref, computed, watch } from 'vue'
  31. import { customApi } from '@/service/custom';
  32. import { useI18n } from 'vue-i18n'
  33. import { showToast } from "@/utils/toast";
  34. const { t } = useI18n()
  35. const props = defineProps({
  36. visible: { type: Boolean, default: false },
  37. account: { type: Object, default: () => ({}) },
  38. accountLabel: { type: String, default: '账户: #' },
  39. // 1: 交易密码, 2: 投资者密码
  40. pwdType: { type: [Number, String], default: 1 },
  41. })
  42. const emit = defineEmits(['update:visible', 'save'])
  43. const passwordInfo = ref({
  44. oldPassword: '',
  45. newPassword: ''
  46. });
  47. const rule1 = computed(() => {
  48. if (!passwordInfo.value.newPassword) return false;
  49. return /^.{8,16}$/.test(passwordInfo.value.newPassword);
  50. });
  51. const rule2 = computed(() => {
  52. return /^(?=.*?[a-z])(?=.*?[A-Z]).*$/.test(passwordInfo.value.newPassword);
  53. });
  54. const rule3 = computed(() => {
  55. return /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?!.*([~!@&%$^\\(\\)#_]).*\\1.*\\1)[A-Za-z0-9~!@&%$^\\(\\)#_]{8,16}$/.test(
  56. passwordInfo.value.newPassword
  57. );
  58. });
  59. const rule4 = computed(() => {
  60. return /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~!@&%$^*./\\(\\)\\+\\=#_-])[A-Za-z0-9~!@&%$^*./\\(\\)\\+\\=#_-]{8,16}$/.test(
  61. passwordInfo.value.newPassword
  62. );
  63. });
  64. const noticeItems = computed(() => [
  65. { label: t('signup.form.rules.1st'), valid: rule1.value },
  66. { label: t('signup.form.rules.2nd'), valid: rule2.value },
  67. { label: t('signup.form.rules.4rd'), valid: rule4.value }
  68. ]);
  69. const flag = ref(false); // 防止重复提交
  70. const save = async () => {
  71. if (!/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~!@&%$^*./\\(\\)\\+\\=#_-])[A-Za-z0-9~!@&%$^*./\\(\\)\\+\\=#_-]{8,16}$/.test(passwordInfo.value.oldPassword)) {
  72. showToast(t('vaildate.password.format'));
  73. return;
  74. }
  75. if (!rule1.value || !rule2.value || !rule4.value) {
  76. return;
  77. }
  78. if (flag.value) return;
  79. flag.value = true;
  80. try {
  81. let res;
  82. if (props.pwdType == 1) {
  83. // 修改交易账户密码
  84. res = await customApi.ChangeDealPassword({
  85. login: props.account.login,
  86. ...passwordInfo.value
  87. });
  88. } else {
  89. // 修改投资者密码
  90. res = await customApi.ChangeInvestorOassword({
  91. login: props.account.login,
  92. ...passwordInfo.value
  93. });
  94. }
  95. if (res.code == 200) {
  96. showToast(t('Msg.Success'));
  97. emit('update:visible', false);
  98. passwordInfo.value = {
  99. oldPassword: '',
  100. newPassword: ''
  101. }
  102. emit('save');
  103. } else {
  104. showToast(res.msg);
  105. }
  106. } catch (error) {
  107. showToast(error.msg);
  108. emit('update:visible', false);
  109. } finally {
  110. flag.value = false;
  111. }
  112. }
  113. watch(() => props.visible, (newVal) => {
  114. if (newVal) {
  115. passwordInfo.value = {
  116. oldPassword: '',
  117. newPassword: ''
  118. }
  119. flag.value = false;
  120. }
  121. })
  122. </script>
  123. <style scoped lang="scss">
  124. @import "@/uni.scss";
  125. @media (min-width: 768px) {
  126. :deep(.cwg-dialog) {
  127. background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;
  128. border-radius: px2rpx(8);
  129. width: px2rpx(480) !important;
  130. }
  131. }
  132. .popup-content {
  133. padding: px2rpx(16);
  134. }
  135. .account-number {
  136. text-align: left;
  137. display: block;
  138. font-size: px2rpx(14);
  139. color: var(--bs-emphasis-color);
  140. margin-bottom: px2rpx(24);
  141. }
  142. .crm-form {
  143. :deep(.uni-forms-item) {
  144. margin-bottom: px2rpx(16);
  145. }
  146. :deep(.uni-easyinput__content) {
  147. border: none !important;
  148. background-color: var(--color-zinc-100) !important;
  149. }
  150. }
  151. .notice-list {
  152. margin: px2rpx(10) 0;
  153. padding: 0 px2rpx(12) px2rpx(12) 0;
  154. .notice-item {
  155. text-align: left;
  156. font-size: px2rpx(14);
  157. color: var(--bs-emphasis-color);
  158. line-height: px2rpx(24);
  159. &::before {
  160. content: '●';
  161. display: inline-block;
  162. font-size: px2rpx(10);
  163. margin-right: px2rpx(4);
  164. }
  165. }
  166. .isOK {
  167. color: var(--bs-success);
  168. }
  169. }
  170. .save-btn {
  171. width: 100%;
  172. display: flex;
  173. justify-content: flex-end;
  174. margin-top: px2rpx(20);
  175. .btn {
  176. border: 1px solid rgba(108, 133, 149, 0);
  177. border-radius: px2rpx(8);
  178. padding: px2rpx(8) px2rpx(20);
  179. font-size: px2rpx(14);
  180. color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important;
  181. display: inline-flex;
  182. align-items: center;
  183. justify-content: center;
  184. gap: px2rpx(8);
  185. cursor: pointer;
  186. transition: all 0.2s;
  187. height: px2rpx(40);
  188. box-sizing: border-box;
  189. background-color: rgba(108, 133, 149, 0.08);
  190. &.primary {
  191. background-color: #cf1322;
  192. ;
  193. color: var(--bs-emphasis-color);
  194. &:hover {
  195. background-color: var(--color-navy-600);
  196. }
  197. &[disabled] {
  198. cursor: not-allowed;
  199. }
  200. }
  201. }
  202. }
  203. </style>