| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587 |
- <template>
- <cwg-popup :title="title" :visible="visible" @close="close" @confirm="submit">
- <!-- <uni-popup ref="popupRef" type="center" style="z-index: 999;">-->
- <!-- <view class="dialog-container">-->
- <!-- <view class="dialog-header">-->
- <!-- <text class="dialog-title" v-t="typeMap[form.type]"></text>-->
- <!-- <view class="dialog-close" @click="close">-->
- <!-- <text>×</text>-->
- <!-- </view>-->
- <!-- </view>-->
- <uni-forms ref="formRef" :rules="rules" :model="form" labelWidth="200" label-position="top"
- validate-trigger="submit" class="crm-form">
- <uni-row class="form-row uni-row1">
- <template v-if="form.type === 1">
- <uni-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
- <uni-forms-item required name="bankFront" :label="t('vu.item19')">
- <cwg-file-picker-wrapper v-model:value="form.bankFront" :limit="1" uploadUrl="/custom/bank/upload"
- :baseUrl="updateUrl" :imageWidth="200" :imageHeight="200" uploadText="点击上传" replaceText="点击替换"
- noImageText="暂无图片" @update:modelValue="(val) => handleFileUpdate(val, form, 'bankFront')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
- <view class="qrcode">
- <cwg-icon name="icon_mobile" :size="36" />
- <view class="qr-code-wrapper">
- <image v-if="mobile" :src="mobile" mode="aspectFit" class="qr-image" @click="previewImage" />
- <view v-else class="image-slot">
- <uni-icons type="image" size="30" color="#ccc"></uni-icons>
- </view>
- </view>
- </view>
- </uni-col>
- <uni-col :span="24">
- <view class="updatePrompt">
- <text class="icon-tip">ⓘ</text>
- <text>{{ t('Drawer.Content.UpdatePrompt') }}</text>
- </view>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item :label="t('PersonalManagement.Label.BankAccountName')">
- <uni-easyinput disabled v-model="username"
- :placeholder="locale == 'es' ? 'Introduzca el nombre de la red' : t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item required :label="t('PersonalManagement.Label.BankName')" name="bankName">
- <cwg-combox :clearable="false" :filterable="true" v-model:value="form.bankName" :options="bankOptions"
- :placeholder="t('placeholder.choose')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item required :label="t('PersonalManagement.Label.BankAccount')" name="bankCardNum">
- <uni-easyinput :clearable="false" v-model="form.bankCardNum" :placeholder="t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item required :label="t('PersonalManagement.Label.AccountOpeningBranch')"
- name="bankBranchName">
- <uni-easyinput :clearable="false" v-model="form.bankBranchName" :placeholder="t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- </template>
- <template v-if="form.type === 4">
- <!-- 区块链名称 -->
- <uni-col :xs="24">
- <uni-forms-item required name="addressName" :label="t('blockchain.item3')">
- <uni-easyinput :clearable="false" v-model="form.addressName" :placeholder="t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <!-- 钱包地址 -->
- <uni-col :xs="24">
- <uni-forms-item required name="address" :label="t('blockchain.item4')">
- <uni-easyinput :clearable="false" v-model="form.address" :placeholder="t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- </template>
- <template v-if="form.type === 2">
- <uni-col :xs="24">
- <uni-forms-item :label="t('PersonalManagement.Label.BankAccountName')">
- <uni-easyinput :clearable="false" v-model="username" :disabled="true"
- :placeholder="locale == 'es' ? 'Introduzca el nombre de la red' : t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item required :label="t('PersonalManagement.Label.BankAccount')" name="bankCardNum">
- <uni-easyinput :clearable="false" v-model="form.bankCardNum"
- :placeholder="locale == 'es' ? 'Introduzca la dirección de la billetera' : t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item required :label="t('PersonalManagement.Label.BankName')" name="bankName">
- <uni-easyinput :clearable="false" v-model="form.bankName"
- :placeholder="locale == 'es' ? 'Introduzca el nombre del banco' : t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item required :label="t('PersonalManagement.Label.BankAddress')" name="bankAddr">
- <uni-easyinput :clearable="false" v-model="form.bankAddr"
- :placeholder="locale == 'es' ? 'Introduzca la dirección del banco' : t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item required :label="t('PersonalManagement.Label.SwiftBIC')" name="swiftCode">
- <uni-easyinput :clearable="false" v-model="form.swiftCode"
- :placeholder="locale == 'es' ? 'Introduzca el SWIFT/BIC' : t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item required :label="t('PersonalManagement.Label.BankCode')" name="bankCode">
- <uni-easyinput :clearable="false" v-model="form.bankCode"
- :placeholder="locale == 'es' ? 'Introduzca el código del banco' : t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item :label="locale == 'es' ? 'Número de sucursal (opcional)' : 'Account Agency NO'">
- <uni-easyinput :clearable="false" v-model="form.agencyNo"
- :placeholder="locale == 'es' ? 'Introduzca el número de sucursal' : t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- </template>
- <template v-if="form.type === 3">
- <uni-col :xs="24">
- <uni-forms-item :label="t('PersonalManagement.Label.CreditCardAccountName')">
- <uni-easyinput :clearable="false" v-model="username" :disabled="true"
- :placeholder="t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item required :label="t('PersonalManagement.Label.CreditCardAccount')" name="bankCardNum">
- <uni-easyinput :clearable="false" v-model="form.bankCardNum"
- :placeholder="locale == 'es' ? 'Introduzca el número de tarjeta' : t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item required :label="t('PersonalManagement.Label.ExpirationYear')" name="expiryYearMonth">
- <uni-easyinput :clearable="false" v-model="form.expiryYearMonth"
- :placeholder="locale == 'es' ? 'Introduzca MM/AA' : t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- <uni-col :xs="24">
- <uni-forms-item :label="t('CVV')">
- <uni-easyinput :clearable="false" v-model="form.cvv"
- :placeholder="locale == 'es' ? 'Introduzca el CVV' : t('placeholder.input')" />
- </uni-forms-item>
- </uni-col>
- </template>
- <uni-col :xs="24">
- <uni-forms-item class="checkbox-item" prop="defaultBank">
- <uni-data-checkbox v-model="form.defaultBank" multiple :localdata="hobbys" />
- </uni-forms-item>
- </uni-col>
- </uni-row>
- </uni-forms>
- <!-- <view class="dialog-footer">-->
- <!-- <view class="btn btn-cancel" @click="close">{{ t('Btn.Cancel') }}</view>-->
- <!-- <view class="btn btn-confirm" @click="submit">{{ t('Btn.Confirm') }}</view>-->
- <!-- </view>-->
- <!-- </view>-->
- <!-- </uni-popup>-->
- </cwg-popup>
- </template>
- <script setup lang="ts">
- import { ref, nextTick, computed, onMounted } from 'vue'
- import { useI18n } from 'vue-i18n'
- import { personalApi } from '@/service/personal'
- import useUserStore from '@/stores/use-user-store'
- import config from '@/config'
- const userStore = useUserStore()
- const { t, locale } = useI18n()
- const updateUrl = config.Host80
- const typeMap = {
- 4: 'blockchain.item2',
- 1: 'PersonalManagement.Title.ChinaUnionPayCard',
- 2: 'PersonalManagement.Title.BankWireTransfer',
- 3: 'PersonalManagement.Label.CreditCard',
- }
- const title = computed(()=>{
- return form.value.type?t(typeMap[form.value.type]):''
- })
- const username = computed(() => {
- let first = userStore?.userInfo?.customInfo.firstName
- let middle = userStore?.userInfo?.customInfo.middle
- let lastName = userStore?.userInfo?.customInfo.lastName
- return (first ? first + ' ' : '') +
- (middle ? middle + ' ' : '') +
- (lastName ? lastName : '')
- })
- interface AddBankForm {
- addressName: string;
- address: string;
- checkboxGroup: string[];
- }
- const hobbys = computed(() => {
- let value = [
- { value: 1, text: t('blockchain.item8') },
- ]
- switch (form.value.type) {
- case 1:
- value = [
- { value: 1, text: t('PersonalManagement.Title.DefaultBank') },
- ]
- break
- case 2:
- value = [
- { value: 1, text: t('PersonalManagement.Title.DefaultWire') },
- ]
- break
- case 3:
- value = [
- { value: 1, text: t('PersonalManagement.Title.DefaultCredit') },
- ]
- break
- case 4:
- value = [
- { value: 1, text: t('blockchain.item8') },
- ]
- break
- }
- return value
- })
- const emit = defineEmits(['success'])
- const formRef = ref<any>(null)
- const visible =ref(false)
- const form = ref({
- bankFront: ''
- })
- const rules = computed(() => ({
- bankFront: {
- rules: [
- {
- required: true,
- errorMessage: t('vaildate.select.empty'),
- trigger: 'blur',
- },
- ],
- },
- bankName: {
- rules: [
- {
- required: true,
- errorMessage: t('vaildate.input.empty'),
- trigger: 'blur',
- },
- ],
- },
- bankCardNum: {
- rules: [
- {
- required: true,
- errorMessage: t('vaildate.input.empty'),
- trigger: 'change',
- },
- ],
- },
- bankBranchName: {
- rules: [
- {
- required: true,
- errorMessage: t('vaildate.input.empty'),
- trigger: 'blur',
- },
- ],
- },
- bankAddr: {
- rules: [
- {
- required: true,
- errorMessage: t('vaildate.input.empty'),
- trigger: 'blur',
- },
- ],
- },
- swiftCode: {
- rules: [
- {
- required: true,
- errorMessage: t('vaildate.input.empty'),
- trigger: 'blur',
- },
- ],
- },
- bankCode: {
- rules: [
- {
- required: true,
- errorMessage: t('vaildate.input.empty'),
- trigger: 'blur',
- },
- ],
- },
- expiryYearMonth: {
- rules: [
- {
- required: true,
- errorMessage: t('vaildate.input.empty'),
- trigger: 'blur',
- },
- ],
- },
- addressName: {
- rules: [
- {
- required: true,
- errorMessage: t('vaildate.input.empty'),
- trigger: 'blur',
- },
- ],
- },
- address: {
- rules: [
- {
- required: true,
- errorMessage: t('vaildate.input.empty'),
- trigger: 'blur',
- },
- ],
- },
- }))
- // 打开弹窗
- const open = async (type: number) => {
- form.value = {}
- await nextTick()
- form.value.type = type
- getBankList()
- if (type === 1) {
- getMobileInfo()
- }
- visible.value = true
- }
- // 关闭弹窗
- const close = () => {
- resetForm();
- visible.value = false
- }
- // 弹窗真正关闭后清空表单
- const onPopupClose = () => {
- };
- // 重置表单
- const resetForm = () => {
- form.value = {}
- formRef.value?.clearValidate()
- }
- // 提交表单
- const submit = async () => {
- try {
- // 校验表单
- await formRef.value?.validate()
- // 调用 API 添加钱包
- const submitData = {
- ...form.value,
- expiryYear: form.value?.expiryYearMonth ? form.value.expiryYearMonth.split('/')[0] : undefined,
- expiryMonth: form.value?.expiryYearMonth ? form.value.expiryYearMonth.split('/')[1] : undefined,
- defaultBank: form.value?.defaultBank && form.value?.defaultBank[0] ? 1 : 0,
- }
- let res = await personalApi.customBankAdd({
- bankUname: username.value,
- ...submitData,
- })
- if (res.code == 200) {
- uni.showToast({ title: t('Msg.Success'), icon: 'success' })
- emit('success', res.data)
- } else {
- uni.showToast({ title: res.msg || t('common.error'), icon: 'none' })
- }
- close()
- } catch (error) {
- console.log(error, 12121)
- if (error instanceof Array) {
- uni.showToast({ title: error[0].errorMessage, icon: 'none' })
- return
- } else {
- uni.showToast({ title: error.msg || t('common.error'), icon: 'none' })
- }
- }
- }
- const bankList = ref([])
- const isZh = computed(() => ['cn', 'zh', 'zhHant'].includes(locale.value))
- const getLangName = (item: any) => (isZh.value ? item.name : item.enName)
- const createOptions = (list: any[], valueKey = 'code') => {
- return list.map((item) => ({
- text: getLangName(item),
- value: getLangName(item),
- }))
- }
- const bankOptions = computed(() => createOptions(bankList.value, 'name'))
- // 获取银行列表
- const getBankList = async () => {
- const res = await personalApi.BankList({})
- if (res.code === 200) {
- bankList.value = res.data
- }
- }
- // 文件更新处理
- const handleFileUpdate = (newValue, item, field) => {
- item[field] = newValue
- }
- const mobile = ref('')
- // 获取二维码
- const getMobileInfo = async () => {
- try {
- let res = await personalApi.CustomFileMobileFiles({}, {
- responseType: 'arraybuffer',
- })
- mobile.value = 'data:image/png;base64,' + uni.arrayBufferToBase64(res)
- } catch (error) {
- console.error(error)
- }
- }
- // 预览二维码图片
- const previewImage = () => {
- if (mobile.value) {
- uni.previewImage({
- urls: [mobile.value],
- current: 0,
- })
- }
- }
- // 暴露方法
- defineExpose({
- open,
- close,
- })
- </script>
- <style scoped lang="scss">
- @import "@/uni.scss";
- .qrcode {
- display: flex;
- align-items: end;
- margin-bottom: px2rpx(20);
- }
- .qr-code-wrapper {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- width: px2rpx(100);
- height: px2rpx(100);
- border: 1px dashed #dcdfe6;
- border-radius: px2rpx(8);
- background-color: #fafafa;
- //margin: 0 auto;
- .qr-image {
- width: 100%;
- height: 100%;
- object-fit: contain;
- }
- .image-slot {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 100%;
- height: 100%;
- color: var(--bs-heading-color);
- }
- }
- .dialog-container {
- width: 80vw;
- max-width: px2rpx(600);
- max-height: 85vh;
- padding: px2rpx(24);
- overflow: hidden;
- border-radius: px2rpx(12);
- display: flex;
- flex-direction: column;
- background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;
- .uni-row1{
- flex: 1;
- height: 100%;
- overflow-y: scroll;
- }
- .dialog-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: px2rpx(24);
- padding-bottom: px2rpx(16);
- border-bottom: 1px solid #f3f4f6;
- .dialog-title {
- font-size: px2rpx(18);
- font-weight: 600;
- color: var(--bs-emphasis-color);
- }
- .dialog-close {
- width: px2rpx(32);
- height: px2rpx(32);
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: px2rpx(28);
- color: var(--bs-emphasis-color);
- cursor: pointer;
- transition: all 0.3s;
- &:hover {
- color: var(--bs-emphasis-color);
- }
- }
- }
- .dialog-footer {
- display: flex;
- gap: px2rpx(12);
- justify-content: space-around;
- padding: px2rpx(16) 0 0;
- border-top: 1px solid #f3f4f6;
- .btn {
- min-width: px2rpx(120);
- padding: px2rpx(12) px2rpx(24);
- border-radius: px2rpx(6);
- font-size: px2rpx(14);
- font-weight: 600;
- box-sizing: border-box;
- border: none;
- cursor: pointer;
- text-align: center;
- transition: all 0.3s;
- display: flex;
- align-items: center;
- justify-content: center;
- &.btn-cancel {
- background: #f3f4f6;
- color: #6b7280;
- &:hover {
- background: #e5e7eb;
- }
- &:active {
- background: #d1d5db;
- }
- }
- &.btn-confirm {
- background: #ea2027;
- color: #fff;
- &:hover {
- background: #d11920;
- }
- &:active {
- background: #c01819;
- }
- }
- }
- }
- .crm-form {
- overflow-y: auto;
- max-height: 70vh;
- }
- }
- </style>
|