AddBankDialog.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. <template>
  2. <uni-popup ref="popupRef" type="center" background-color="#fff">
  3. <view class="dialog-container">
  4. <view class="dialog-header">
  5. <text class="dialog-title">{{ t('blockchain.item2') }}</text>
  6. <view class="dialog-close" @click="close">
  7. <text>×</text>
  8. </view>
  9. </view>
  10. <uni-forms ref="formRef" :rules="rules" :model="form" labelWidth="200" label-position="top"
  11. class="crm-form">
  12. <uni-row class="form-row uni-row1">
  13. <template v-if="form.type === 1">
  14. <uni-col :xs="24">
  15. <uni-forms-item>
  16. <cwg-file-picker v-model="form.bankFront" :editable="editingId === form.id" :limit="1"
  17. uploadUrl="/custom/bank/upload" :baseUrl="updateUrl" :imageWidth="150"
  18. :imageHeight="150" uploadText="点击上传" replaceText="点击替换" noImageText="暂无图片"
  19. :showPreviewDelete="editingId === form.id"
  20. @update:modelValue="(val) => handleFileUpdate(val, form, 'bankFront')" />
  21. </uni-forms-item>
  22. </uni-col>
  23. <uni-col :xs="24">
  24. <uni-forms-item :label="t('PersonalManagement.Label.BankAccountName')">
  25. <uni-easyinput :clearable="false" v-model="form.bankUname"
  26. :placeholder="locale == 'es' ? 'Introduzca el nombre de la red' : t('placeholder.input')" />
  27. </uni-forms-item>
  28. </uni-col>
  29. <uni-col :xs="24">
  30. <uni-forms-item :label="t('PersonalManagement.Label.BankName')">
  31. <cwg-combox :clearable="false" :filterable="true" v-model:value="form.bankName"
  32. :options="bankOptions" :placeholder="t('placeholder.choose')"
  33. @change="onStateChange" />
  34. </uni-forms-item>
  35. </uni-col>
  36. <uni-col :xs="24">
  37. <uni-forms-item :label="t('PersonalManagement.Label.BankAccount')">
  38. <uni-easyinput :clearable="false" v-model="form.bankCardNum"
  39. :placeholder="locale == 'es' ? 'Introduzca la dirección de la billetera' : t('placeholder.input')" />
  40. </uni-forms-item>
  41. </uni-col>
  42. <uni-col :xs="24">
  43. <uni-forms-item :label="t('PersonalManagement.Label.AccountOpeningBranch')">
  44. <uni-easyinput :clearable="false" v-model="form.bankBranchName"
  45. :placeholder="locale == 'es' ? 'Introduzca la dirección de la billetera' : t('placeholder.input')" />
  46. </uni-forms-item>
  47. </uni-col>
  48. </template>
  49. <template v-if="form.type === 4">
  50. <!-- 区块链名称 -->
  51. <uni-col :xs="24">
  52. <uni-forms-item prop="addressName" :label="t('blockchain.item3')">
  53. <uni-easyinput :clearable="false" v-model="form.addressName"
  54. :placeholder="t('placeholder.input')" />
  55. </uni-forms-item>
  56. </uni-col>
  57. <!-- 钱包地址 -->
  58. <uni-col :xs="24">
  59. <uni-forms-item prop="address" :label="t('blockchain.item4')">
  60. <uni-easyinput :clearable="false" v-model="form.address"
  61. :placeholder="t('placeholder.input')" />
  62. </uni-forms-item>
  63. </uni-col>
  64. </template>
  65. <template v-if="form.type === 2">
  66. <uni-col :xs="24">
  67. <uni-forms-item :label="t('PersonalManagement.Label.BankAccountName')">
  68. <uni-easyinput :clearable="false" v-model="form.bankUname" :disabled="true"
  69. :placeholder="locale == 'es' ? 'Introduzca el nombre de la red' : t('placeholder.input')" />
  70. </uni-forms-item>
  71. </uni-col>
  72. <uni-col :xs="24">
  73. <uni-forms-item :label="t('PersonalManagement.Label.BankAccount')">
  74. <uni-easyinput :clearable="false" v-model="form.bankCardNum"
  75. :placeholder="locale == 'es' ? 'Introduzca la dirección de la billetera' : t('placeholder.input')" />
  76. </uni-forms-item>
  77. </uni-col>
  78. <uni-col :xs="24">
  79. <uni-forms-item :label="t('PersonalManagement.Label.BankName')">
  80. <uni-easyinput :clearable="false" v-model="form.bankName"
  81. :placeholder="locale == 'es' ? 'Introduzca el nombre del banco' : t('placeholder.input')" />
  82. </uni-forms-item>
  83. </uni-col>
  84. <uni-col :xs="24">
  85. <uni-forms-item :label="t('PersonalManagement.Label.BankAddress')">
  86. <uni-easyinput :clearable="false" v-model="form.bankAddr"
  87. :placeholder="locale == 'es' ? 'Introduzca la dirección del banco' : t('placeholder.input')" />
  88. </uni-forms-item>
  89. </uni-col>
  90. <uni-col :xs="24">
  91. <uni-forms-item :label="t('PersonalManagement.Label.SwiftBIC')">
  92. <uni-easyinput :clearable="false" v-model="form.swiftCode"
  93. :placeholder="locale == 'es' ? 'Introduzca el SWIFT/BIC' : t('placeholder.input')" />
  94. </uni-forms-item>
  95. </uni-col>
  96. <uni-col :xs="24">
  97. <uni-forms-item :label="t('PersonalManagement.Label.BankCode')">
  98. <uni-easyinput :clearable="false" v-model="form.bankCode"
  99. :placeholder="locale == 'es' ? 'Introduzca el código del banco' : t('placeholder.input')" />
  100. </uni-forms-item>
  101. </uni-col>
  102. <uni-col :xs="24">
  103. <uni-forms-item
  104. :label="locale == 'es' ? 'Número de sucursal (opcional)' : 'Account Agency NO'">
  105. <uni-easyinput :clearable="false" v-model="form.agencyNo"
  106. :placeholder="locale == 'es' ? 'Introduzca el número de sucursal' : t('placeholder.input')" />
  107. </uni-forms-item>
  108. </uni-col>
  109. </template>
  110. <template v-if="form.type === 3">
  111. <uni-col :xs="24">
  112. <uni-forms-item :label="t('PersonalManagement.Label.CreditCardAccountName')">
  113. <uni-easyinput :clearable="false" v-model="form.bankUname" :disabled="true"
  114. :placeholder="t('placeholder.input')" />
  115. </uni-forms-item>
  116. </uni-col>
  117. <uni-col :xs="24">
  118. <uni-forms-item :label="t('PersonalManagement.Label.CreditCardAccount')">
  119. <uni-easyinput :clearable="false" v-model="form.bankCardNum"
  120. :placeholder="locale == 'es' ? 'Introduzca el número de tarjeta' : t('placeholder.input')" />
  121. </uni-forms-item>
  122. </uni-col>
  123. <uni-col :xs="24">
  124. <uni-forms-item :label="t('PersonalManagement.Label.ExpirationYear')">
  125. <uni-easyinput :clearable="false" v-model="form.expiryYearMonth"
  126. :placeholder="locale == 'es' ? 'Introduzca MM/AA' : t('placeholder.input')" />
  127. </uni-forms-item>
  128. </uni-col>
  129. <uni-col :xs="24">
  130. <uni-forms-item :label="t('CVV')">
  131. <uni-easyinput :clearable="false" v-model="form.cvv"
  132. :placeholder="locale == 'es' ? 'Introduzca el CVV' : t('placeholder.input')" />
  133. </uni-forms-item>
  134. </uni-col>
  135. </template>
  136. <uni-col :xs="24">
  137. <uni-forms-item class="checkbox-item" prop="defaultBank">
  138. <uni-data-checkbox v-model="form.defaultBank" multiple :localdata="hobbys" />
  139. </uni-forms-item>
  140. </uni-col>
  141. </uni-row>
  142. </uni-forms>
  143. <view class="dialog-footer">
  144. <view class="btn btn-cancel" @click="close">{{ t('Btn.Cancel') }}</view>
  145. <view class="btn btn-confirm" @click="submit">{{ t('Btn.Confirm') }}</view>
  146. </view>
  147. </view>
  148. </uni-popup>
  149. </template>
  150. <script setup lang="ts">
  151. import { ref, nextTick, computed, onMounted } from 'vue';
  152. import { useI18n } from 'vue-i18n';
  153. import { Validators } from '@/utils/validators';
  154. import { personalApi } from '@/service/personal';
  155. const { t, locale } = useI18n();
  156. interface AddBankForm {
  157. addressName: string;
  158. address: string;
  159. checkboxGroup: string[];
  160. }
  161. const hobbys = computed(() => [
  162. { value: 1, text: t('blockchain.item8') }
  163. ]);
  164. const emit = defineEmits(["success"]);
  165. const popupRef = ref<any>(null);
  166. const formRef = ref<any>(null);
  167. const form = ref<AddBankForm>({});
  168. const rules = {
  169. addressName: [Validators.required(t('blockchain.item3') + t('common.cannotbeempty'))],
  170. address: [Validators.required(t('blockchain.item4') + t('common.cannotbeempty'))]
  171. };
  172. // 打开弹窗
  173. const open = async (type: number) => {
  174. form.value = {}
  175. await nextTick();
  176. form.value.type = type;
  177. getBankList()
  178. popupRef.value?.open();
  179. };
  180. // 关闭弹窗
  181. const close = () => {
  182. popupRef.value?.close();
  183. resetForm();
  184. };
  185. // 重置表单
  186. const resetForm = () => {
  187. form.value = {};
  188. formRef.value?.clearValidate();
  189. };
  190. // 提交表单
  191. const submit = async () => {
  192. console.log(form.value, 42342342);
  193. try {
  194. // 校验表单
  195. const valid = await formRef.value?.validate();
  196. console.log(valid, 23123);
  197. if (!valid) {
  198. return;
  199. }
  200. // 调用 API 添加钱包
  201. const submitData = {
  202. ...form.value,
  203. expiryYear: form.value?.expiryYearMonth ? form.value.expiryYearMonth.split("/")[0] : undefined,
  204. expiryMonth: form.value?.expiryYearMonth ? form.value.expiryYearMonth.split("/")[1] : undefined,
  205. defaultBank: form.value?.defaultBank && form.value?.defaultBank[0] ? 1 : 0,
  206. };
  207. let res = await personalApi.customBankAdd({
  208. bankUname: 'username',
  209. ...submitData,
  210. });
  211. if (res.code == 200) {
  212. uni.showToast({ title: t('Msg.Success'), icon: 'success' });
  213. emit("success", res.data);
  214. } else {
  215. uni.showToast({ title: res.msg || t('common.error'), icon: 'none' });
  216. }
  217. close();
  218. } catch (error: any) {
  219. console.log(error);
  220. uni.showToast({ title: error.message || error.msg || t('common.error'), icon: 'none' });
  221. }
  222. };
  223. const bankList = ref([])
  224. const isZh = computed(() => ['cn', 'zh', 'zhHant'].includes(locale.value));
  225. const getLangName = (item: any) => (isZh.value ? item.name : item.enName);
  226. const createOptions = (list: any[], valueKey = 'code') => {
  227. return list.map((item) => ({
  228. text: getLangName(item),
  229. value: getLangName(item)
  230. }));
  231. };
  232. const bankOptions = computed(() => createOptions(bankList.value, 'name'));
  233. // 获取银行列表
  234. const getBankList = async () => {
  235. const res = await personalApi.BankList({})
  236. if (res.code === 200) {
  237. bankList.value = res.data
  238. }
  239. }
  240. // 文件更新处理
  241. const handleFileUpdate = (newValue, item, field) => {
  242. item[field] = newValue
  243. }
  244. // 暴露方法
  245. defineExpose({
  246. open,
  247. close
  248. });
  249. </script>
  250. <style scoped lang="scss">
  251. @import "@/uni.scss";
  252. .dialog-container {
  253. width: 80vw;
  254. max-width: px2rpx(800);
  255. max-height: 85vh;
  256. padding: px2rpx(24);
  257. overflow: hidden;
  258. border-radius: px2rpx(12);
  259. .dialog-header {
  260. display: flex;
  261. justify-content: space-between;
  262. align-items: center;
  263. margin-bottom: px2rpx(24);
  264. padding-bottom: px2rpx(16);
  265. border-bottom: 1px solid #f3f4f6;
  266. .dialog-title {
  267. font-size: px2rpx(18);
  268. font-weight: 600;
  269. color: #1f2937;
  270. }
  271. .dialog-close {
  272. width: px2rpx(32);
  273. height: px2rpx(32);
  274. display: flex;
  275. align-items: center;
  276. justify-content: center;
  277. font-size: px2rpx(28);
  278. color: #9ca3af;
  279. cursor: pointer;
  280. transition: all 0.3s;
  281. &:hover {
  282. color: #1f2937;
  283. }
  284. }
  285. }
  286. .dialog-footer {
  287. display: flex;
  288. gap: px2rpx(12);
  289. justify-content: flex-end;
  290. padding-top: px2rpx(16);
  291. border-top: 1px solid #f3f4f6;
  292. .btn {
  293. min-width: px2rpx(120);
  294. padding: px2rpx(12) px2rpx(24);
  295. border-radius: px2rpx(6);
  296. font-size: px2rpx(14);
  297. font-weight: 600;
  298. border: none;
  299. cursor: pointer;
  300. text-align: center;
  301. transition: all 0.3s;
  302. display: flex;
  303. align-items: center;
  304. justify-content: center;
  305. &.btn-cancel {
  306. background: #f3f4f6;
  307. color: #6b7280;
  308. &:hover {
  309. background: #e5e7eb;
  310. }
  311. &:active {
  312. background: #d1d5db;
  313. }
  314. }
  315. &.btn-confirm {
  316. background: #ea2027;
  317. color: #fff;
  318. &:hover {
  319. background: #d11920;
  320. }
  321. &:active {
  322. background: #c01819;
  323. }
  324. }
  325. }
  326. }
  327. .crm-form {
  328. overflow-y: auto;
  329. max-height: 70vh;
  330. }
  331. }
  332. </style>