|
|
@@ -0,0 +1,1549 @@
|
|
|
+<template>
|
|
|
+ <div
|
|
|
+ id="review_Email"
|
|
|
+ v-loading="pictLoading"
|
|
|
+ class="view"
|
|
|
+ element-loading-background="rgba(43, 48, 67, 0.65)"
|
|
|
+ element-loading-spinner="el-icon-loading"
|
|
|
+ >
|
|
|
+ <div class="crm_search">
|
|
|
+ <el-form ref="form" label-position="" :model="search" label-width="">
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="24" :md="24" :lg="24">
|
|
|
+ <el-form-item>
|
|
|
+ <el-select
|
|
|
+ v-model="search.tag"
|
|
|
+ class="crm_search_down crm-border-radius-no select-tag"
|
|
|
+ :placeholder="$t('Placeholder.Choose')"
|
|
|
+ >
|
|
|
+ <el-option :label="$t('Ucard.Business.text2')" :value="1"></el-option>
|
|
|
+ <el-option :label="$t('Ucard.Business.text4')" :value="3"></el-option>
|
|
|
+ <el-option :label="$t('Ucard.Business.text5')" :value="4"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-input
|
|
|
+ v-if="search.tag == 1"
|
|
|
+ v-model.trim="search.cId"
|
|
|
+ class="crm-border-left-no crm-border-radius-no"
|
|
|
+ clearable
|
|
|
+ :placeholder="$t('Placeholder.Input')"
|
|
|
+ @keyup.enter="toSearch"
|
|
|
+ ></el-input>
|
|
|
+ <el-input
|
|
|
+ v-if="search.tag == 3"
|
|
|
+ v-model.trim="search.email"
|
|
|
+ class="crm-border-left-no crm-border-radius-no"
|
|
|
+ clearable
|
|
|
+ :placeholder="$t('Placeholder.Input')"
|
|
|
+ @keyup.enter="toSearch"
|
|
|
+ ></el-input>
|
|
|
+ <el-input
|
|
|
+ v-if="search.tag == 4"
|
|
|
+ v-model.trim="search.mobile"
|
|
|
+ class="crm-border-left-no crm-border-radius-no"
|
|
|
+ clearable
|
|
|
+ :placeholder="$t('Placeholder.Input')"
|
|
|
+ @keyup.enter="toSearch"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button class="crm-border-radius-no crm-border-left-no" @click="toSearch">
|
|
|
+ <el-icon><Search /></el-icon>
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button
|
|
|
+ v-if="display['R-Business-Export'] && display['R-Business-Export'].show"
|
|
|
+ type="primary"
|
|
|
+ style="margin-left: 8px"
|
|
|
+ @click="exportAgents"
|
|
|
+ ><span>{{ $t('Btn.Export') }}</span></el-button
|
|
|
+ >
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <div class="search_action_btn">
|
|
|
+ <span
|
|
|
+ v-if="display['R-Business-Add'] && display['R-Business-Add'].show"
|
|
|
+ class="crm-cursor"
|
|
|
+ @click="
|
|
|
+ () => {
|
|
|
+ dialogBusinessEdit = true
|
|
|
+ isAdd = true
|
|
|
+ }
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <el-icon><Plus /></el-icon>
|
|
|
+ <span>{{ $t('signup.title') }}</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <!-- 合作商户信息管理表格和新增按钮 -->
|
|
|
+ <div class="business-mock-demo" style="margin: 30px 0">
|
|
|
+ <el-table :data="businessList" stripe style="margin-top: 20px; width: 100%">
|
|
|
+ <el-table-column prop="cId" :label="$t('Ucard.Business.item1')">
|
|
|
+ <template #default="scope">
|
|
|
+ <span
|
|
|
+ v-if="scope.row.cId"
|
|
|
+ class="crm-text-underline"
|
|
|
+ style="cursor: pointer"
|
|
|
+ @click="accountOpen(scope.row.cId)"
|
|
|
+ >{{ scope.row.cId }}</span
|
|
|
+ >
|
|
|
+ <span v-else>--</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="$t('Ucard.Business.item5')">
|
|
|
+ <template #default="scope">
|
|
|
+ {{ scope.row.lastName }} {{ scope.row.firstName }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="email" :label="$t('Ucard.Business.item4')" />
|
|
|
+ <el-table-column :label="$t('Ucard.Business.item3')">
|
|
|
+ <template #default="scope"> {{ scope.row.areaCode }} {{ scope.row.mobile }} </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="countryEnName" :label="$t('Ucard.Business.item8')" />
|
|
|
+ <el-table-column prop="townEnName" :label="$t('Ucard.Business.item11')" />
|
|
|
+ <el-table-column prop="address" :label="$t('Ucard.Business.item12')" />
|
|
|
+ <el-table-column prop="postCode" :label="$t('Ucard.Business.item13')" />
|
|
|
+ <el-table-column prop="balance" :label="$t('Ucard.Business.item21')">
|
|
|
+ <template #default="scope"> $ {{ scope.row.balance || 0 }} </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="balance" :label="$t('card.New1.f4')">
|
|
|
+ <template #default="scope">
|
|
|
+ <span v-if="scope.row.photoStatus == '1'" class="state crm_state_blue">{{
|
|
|
+ $t('State.Yes')
|
|
|
+ }}</span>
|
|
|
+ <span v-if="scope.row.photoStatus != '1'" class="state crm_state_red">{{
|
|
|
+ $t('State.No')
|
|
|
+ }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="$t('Ucard.Business.item20')" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-dropdown trigger="click" @command="handleCommand">
|
|
|
+ <span class="el-dropdown-link crm-cursor">
|
|
|
+ <i style="font-weight: bold; font-size: 20px" class="iconfont iconcaidan"></i>
|
|
|
+ </span>
|
|
|
+ <template #dropdown>
|
|
|
+ <el-dropdown-menu>
|
|
|
+ <el-dropdown-item
|
|
|
+ v-if="display['R-Business-Single'].show"
|
|
|
+ :command="{ type: 0, row: scope.row }"
|
|
|
+ >
|
|
|
+ <el-icon><View /></el-icon>
|
|
|
+ <span>{{ $t('R-Business-Single') }}</span>
|
|
|
+ </el-dropdown-item>
|
|
|
+ <el-dropdown-item
|
|
|
+ v-if="display['R-Business-Update'].show"
|
|
|
+ :command="{ type: 'edit', row: scope.row }"
|
|
|
+ >
|
|
|
+ <el-icon><EditPen /></el-icon>
|
|
|
+ <span>{{ $t('R-Business-Update') }}</span>
|
|
|
+ </el-dropdown-item>
|
|
|
+ <el-dropdown-item
|
|
|
+ v-if="display['R-Business-Btn1'].show"
|
|
|
+ :command="{ type: 1, row: scope.row }"
|
|
|
+ >
|
|
|
+ <el-icon><Operation /></el-icon>
|
|
|
+ <span>{{ $t('R-Business-Btn1') }}</span>
|
|
|
+ </el-dropdown-item>
|
|
|
+ <el-dropdown-item
|
|
|
+ v-if="display['R-Business-Btn2'].show"
|
|
|
+ :command="{ type: 2, row: scope.row }"
|
|
|
+ >
|
|
|
+ <el-icon><Setting /></el-icon>
|
|
|
+ <span>{{ $t('R-Business-Btn2') }}</span>
|
|
|
+ </el-dropdown-item>
|
|
|
+ </el-dropdown-menu>
|
|
|
+ </template>
|
|
|
+ </el-dropdown>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-if="pagerInfo.rowTotal" class="crm_pagination">
|
|
|
+ <div class="crm_page_total">
|
|
|
+ <span>{{ $t('Page.total.item1') }}</span>
|
|
|
+ <span>{{ pagerInfo.rowTotal }}</span>
|
|
|
+ <span>{{ $t('Page.total.item2') }}</span>
|
|
|
+ </div>
|
|
|
+ <el-pagination
|
|
|
+ class="page"
|
|
|
+ background
|
|
|
+ layout="sizes, prev, pager, next"
|
|
|
+ :page-sizes="[10, 20, 50, 100]"
|
|
|
+ :page-size="pagerInfo.row"
|
|
|
+ :total="pagerInfo.rowTotal"
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ @size-change="handleSizeChange"
|
|
|
+ >
|
|
|
+ </el-pagination>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 新增/修改弹出 -->
|
|
|
+ <!-- <trading-info-add></trading-info-add> -->
|
|
|
+ <trading-info-add
|
|
|
+ :dialog-info-trading-add="dialogInfoTradingAdd"
|
|
|
+ :editor="editor"
|
|
|
+ :add-type="addType"
|
|
|
+ :my-info="myInfo"
|
|
|
+ :form-list="formList"
|
|
|
+ @confirm-to-reload="confirmToReload"
|
|
|
+ @close-add="closeAdd"
|
|
|
+ ></trading-info-add>
|
|
|
+ <div v-if="dialogInfoTradingAdd" class="crm_verified_info_mask" @click="closeAdd"></div>
|
|
|
+
|
|
|
+ <kyc-auth
|
|
|
+ :dialog-info-trading-add="dialogKycAuth"
|
|
|
+ :add-type="addType"
|
|
|
+ :form-list="kycFormList"
|
|
|
+ @confirm-to-reload="confirmToReload"
|
|
|
+ @close-add="closeKycAuth"
|
|
|
+ ></kyc-auth>
|
|
|
+
|
|
|
+ <review-email
|
|
|
+ :dialog-info-trading-add="dialogKycUpload"
|
|
|
+ :add-type="'kyc_upload'"
|
|
|
+ :form-list="kycUploadForm"
|
|
|
+ @confirm-to-reload="confirmToReload"
|
|
|
+ @close-add="closeKycUpload"
|
|
|
+ />
|
|
|
+
|
|
|
+ <div v-if="dialogKycAuth || dialogKycUpload" class="crm_verified_info_mask"></div>
|
|
|
+
|
|
|
+ <!-- 查看图片弹框 -->
|
|
|
+ <el-dialog v-model="showImgDialog" width="20%" :title="$t('Ucard.Business.p35')">
|
|
|
+ <img v-if="currentImgUrl" :src="currentImgUrl" style="width: 100%" alt="" />
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <detailed-info-cid
|
|
|
+ :dialog-info-cid="dialogInfoCid"
|
|
|
+ :form-info="formInfo"
|
|
|
+ :is-trading="true"
|
|
|
+ @close="closeCidDialog"
|
|
|
+ />
|
|
|
+ <el-dialog
|
|
|
+ v-if="dialogBusinessEdit"
|
|
|
+ v-model="dialogBusinessEdit"
|
|
|
+ :title="$t('Ucard.Business.p1')"
|
|
|
+ :rules="rules"
|
|
|
+ width="900px"
|
|
|
+ >
|
|
|
+ <el-form
|
|
|
+ ref="businessFormRef"
|
|
|
+ :rules="rules"
|
|
|
+ :model="businessForm"
|
|
|
+ label-width="130px"
|
|
|
+ label-position="right"
|
|
|
+ class="business-edit-form"
|
|
|
+ >
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <div v-if="isAdd" class="merchant-search-bar">
|
|
|
+ <div class="custom-select-wrapper" style="flex: 1; position: relative">
|
|
|
+ <el-input
|
|
|
+ v-model="searchEmail"
|
|
|
+ :placeholder="$t('Ucard.Business.p2')"
|
|
|
+ style="width: 100%"
|
|
|
+ @focus="showOptions = true"
|
|
|
+ @input="debouncedRemoteMethod"
|
|
|
+ >
|
|
|
+ <template #append>
|
|
|
+ <el-button
|
|
|
+ icon="el-icon-search"
|
|
|
+ style="color: #fff; background-color: #409eff; border-color: #409eff"
|
|
|
+ @click="handleSearch"
|
|
|
+ >{{ $t('Ucard.Business.p3') }}</el-button
|
|
|
+ >
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ <div v-show="showOptions && options.length > 0" class="custom-options">
|
|
|
+ <div
|
|
|
+ v-for="item in options"
|
|
|
+ :key="item.value"
|
|
|
+ class="custom-option"
|
|
|
+ style="
|
|
|
+ padding: 8px 10px;
|
|
|
+ cursor: pointer;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ "
|
|
|
+ :class="{
|
|
|
+ 'option-active': businessForm.cId === item.value,
|
|
|
+ }"
|
|
|
+ :style="{
|
|
|
+ 'background-color': hoveredOption === item.value ? '#F5F7FA' : 'white',
|
|
|
+ }"
|
|
|
+ @click="selectOption(item)"
|
|
|
+ @mouseover="hoveredOption = item.value"
|
|
|
+ @mouseout="hoveredOption = null"
|
|
|
+ >
|
|
|
+ <span>{{ item.label }}</span>
|
|
|
+ <span style="color: #8492a6; font-size: 13px">
|
|
|
+ {{ item.name ? item.name + ' | ' : '' }}{{ item.nationality || '--' }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="lastName" :label="$t('card.Form.f4')">
|
|
|
+ <el-input v-model="businessForm.lastName" :placeholder="$t('card.vaildate.v4')" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="firstName" :label="$t('card.Form.f5')">
|
|
|
+ <el-input v-model="businessForm.firstName" :placeholder="$t('card.vaildate.v3')" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="areaCode" :label="$t('card.Form.f1')">
|
|
|
+ <el-select
|
|
|
+ v-model="businessForm.areaCode"
|
|
|
+ filterable
|
|
|
+ :placeholder="$t('card.vaildate.v1')"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in countryCityList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.areaCode + ' ' + item.enName"
|
|
|
+ :value="item.areaCode"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="mobile" :label="$t('card.Form.f2')">
|
|
|
+ <el-input v-model="businessForm.mobile" :placeholder="$t('card.vaildate.v2')" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="email" :label="$t('card.Form.f3')">
|
|
|
+ <el-input v-model="businessForm.email" :placeholder="$t('card.vaildate.v28')" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="birthday" :label="$t('card.Form.f6')">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="businessForm.birthday"
|
|
|
+ type="date"
|
|
|
+ :placeholder="$t('card.vaildate.v5')"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="gender" :label="$t('card.Form.f8')">
|
|
|
+ <el-select v-model="businessForm.gender" :placeholder="$t('card.vaildate.v9')">
|
|
|
+ <el-option :label="$t('card.Form.v1')" value="M" />
|
|
|
+ <el-option :label="$t('card.Form.v2')" value="F" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="nationality" :label="$t('card.Form.f7')">
|
|
|
+ <el-select
|
|
|
+ v-model="businessForm.nationality"
|
|
|
+ filterable
|
|
|
+ :placeholder="$t('card.vaildate.v6')"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in countryCityList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.enName"
|
|
|
+ :value="item.code"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="town" :label="$t('card.Form.f9')">
|
|
|
+ <el-select
|
|
|
+ v-model="businessForm.town"
|
|
|
+ filterable
|
|
|
+ :placeholder="$t('card.vaildate.v7')"
|
|
|
+ :disabled="!businessForm.nationality"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in cityList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.enName"
|
|
|
+ :value="item.code"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="addressCn" :label="$t('card.Form.f10')">
|
|
|
+ <el-input
|
|
|
+ v-model="businessForm.addressCn"
|
|
|
+ :placeholder="$t('card.vaildate.v27')"
|
|
|
+ @change="setAddress"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="address" :label="$t('card.New.n11')">
|
|
|
+ <el-input v-model="businessForm.address" :placeholder="$t('card.vaildate.v27')" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="postCode" :label="$t('card.Form.f11')">
|
|
|
+ <el-input v-model="businessForm.postCode" :placeholder="$t('card.vaildate.v8')" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item
|
|
|
+ :prop="createType == 'v1' ? '' : 'occupation'"
|
|
|
+ :label="$t('card.Form.f12')"
|
|
|
+ >
|
|
|
+ <el-select
|
|
|
+ v-model="businessForm.occupation"
|
|
|
+ filterable
|
|
|
+ :placeholder="$t('card.vaildate.v10')"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in occupationList"
|
|
|
+ :key="item.occupationCode"
|
|
|
+ :label="item.description"
|
|
|
+ :value="item.occupationCode"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item
|
|
|
+ :prop="createType == 'v1' ? '' : 'annualSalary'"
|
|
|
+ :label="$t('card.Form.f13')"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="businessForm.annualSalary"
|
|
|
+ :placeholder="$t('card.vaildate.v11')"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item
|
|
|
+ :prop="createType == 'v1' ? '' : 'accountPurpose'"
|
|
|
+ :label="$t('card.Form.f14')"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="businessForm.accountPurpose"
|
|
|
+ :placeholder="$t('card.vaildate.v12')"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item
|
|
|
+ :prop="createType == 'v1' ? '' : 'expectedMonthlyVolume'"
|
|
|
+ :label="$t('card.Form.f15')"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="businessForm.expectedMonthlyVolume"
|
|
|
+ :placeholder="$t('card.vaildate.v13')"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="idType" :label="$t('card.Form.f16')">
|
|
|
+ <el-select v-model="businessForm.idType" :placeholder="$t('card.vaildate.v14')">
|
|
|
+ <el-option
|
|
|
+ v-for="(item, index) in idTypeList1"
|
|
|
+ :key="index"
|
|
|
+ :label="$t(item.name)"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="idNumber" :label="$t('card.Form.f17')">
|
|
|
+ <el-input v-model="businessForm.idNumber" :placeholder="$t('card.vaildate.v15')" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col v-if="businessForm.nationality == 'US'" :span="12">
|
|
|
+ <el-form-item prop="ssn" :label="$t('card.Form.f18')">
|
|
|
+ <el-input v-model="businessForm.ssn" :placeholder="$t('card.vaildate.v16')" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="issueDate" :label="$t('card.Form.f19')">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="businessForm.issueDate"
|
|
|
+ type="date"
|
|
|
+ :placeholder="$t('card.vaildate.v17')"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item prop="idNoExpiryDate" :label="$t('card.Form.f20')">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="businessForm.idNoExpiryDate"
|
|
|
+ type="date"
|
|
|
+ :placeholder="$t('card.vaildate.v18')"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <!-- 上传证件照 -->
|
|
|
+ <template v-if="businessForm.photoStatus == '1'">
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item :label="$t('card.Form.f21')" :prop="!isAdd ? '' : 'idFrontUrl'">
|
|
|
+ <el-upload
|
|
|
+ class="id-uploader"
|
|
|
+ :action="imgUrl + '/wasabi/upload/file'"
|
|
|
+ :headers="AccessToken"
|
|
|
+ :show-file-list="false"
|
|
|
+ :on-success="handleAvatarSuccessBankEn"
|
|
|
+ :before-upload="beforeAvatarUpload"
|
|
|
+ accept="image/*"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ v-if="businessForm.idFrontUrl"
|
|
|
+ :src="imgUrl + businessForm.idFrontUrl"
|
|
|
+ class="avatar"
|
|
|
+ />
|
|
|
+ <i v-else class="el-icon-upload"
|
|
|
+ ><span>{{ $t('card.vaildate.v19') }}</span></i
|
|
|
+ >
|
|
|
+ </el-upload>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item :label="$t('card.Form.f22')" :prop="!isAdd ? '' : 'idBackUrl'">
|
|
|
+ <el-upload
|
|
|
+ class="id-uploader"
|
|
|
+ :action="imgUrl + '/wasabi/upload/file'"
|
|
|
+ :headers="AccessToken"
|
|
|
+ :show-file-list="false"
|
|
|
+ :on-success="handleAvatarSuccessBankEn1"
|
|
|
+ :before-upload="beforeAvatarUpload"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ v-if="businessForm.idBackUrl"
|
|
|
+ :src="imgUrl + businessForm.idBackUrl"
|
|
|
+ class="avatar"
|
|
|
+ />
|
|
|
+ <i v-else class="el-icon-upload"
|
|
|
+ ><span>{{ $t('card.vaildate.v20') }}</span></i
|
|
|
+ >
|
|
|
+ </el-upload>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item :label="$t('card.Form.f23')" :prop="!isAdd ? '' : 'idHoldUrl'">
|
|
|
+ <el-upload
|
|
|
+ class="id-uploader"
|
|
|
+ :action="imgUrl + '/wasabi/upload/file'"
|
|
|
+ :headers="AccessToken"
|
|
|
+ :show-file-list="false"
|
|
|
+ :on-success="handleAvatarSuccessBankEn2"
|
|
|
+ :before-upload="beforeAvatarUpload"
|
|
|
+ accept="image/*"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ v-if="businessForm.idHoldUrl"
|
|
|
+ :src="imgUrl + businessForm.idHoldUrl"
|
|
|
+ class="avatar"
|
|
|
+ />
|
|
|
+ <i v-else class="el-icon-upload"
|
|
|
+ ><span>{{ $t('card.vaildate.v21') }}</span></i
|
|
|
+ >
|
|
|
+ </el-upload>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </template>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="dialogBusinessEdit = false"
|
|
|
+ ><span>{{ $t('Ucard.Business.p32') }}</span></el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ :disabled="isAdd && !isBusinessFormValid()"
|
|
|
+ @click="saveBusiness"
|
|
|
+ >{{ isAdd ? '注册' : '保存' }}</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ <ViewCardSingle
|
|
|
+ :dialog-info-trading-single="dialogInfoTradingSingle"
|
|
|
+ :form-list="formSingle"
|
|
|
+ :editor-type="editorType"
|
|
|
+ @close-single="closeSingle"
|
|
|
+ >
|
|
|
+ </ViewCardSingle>
|
|
|
+ <div v-if="dialogInfoTradingSingle" class="crm_verified_info_mask" @click="closeSingle"></div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+ import { ref, reactive, computed, onMounted, watch, inject } from 'vue'
|
|
|
+ import { useRouter } from 'vue-router'
|
|
|
+ import { ElMessage as Message } from 'element-plus'
|
|
|
+ import Config from '@/config/index'
|
|
|
+ import TradingInfoAdd from '@/views/components/VirtualCard/index.vue'
|
|
|
+ import ViewCardSingle from '@/views/components/ViewCardSingle/index.vue'
|
|
|
+ import KycAuth from '@/views/components/KycAuth'
|
|
|
+ import ReviewEmail from '@/views/components/ReviewEmail'
|
|
|
+ import UcardService from '@/service/ucard'
|
|
|
+ import Service from '@/service/system'
|
|
|
+ import { pinyin } from 'pinyin-pro'
|
|
|
+ import DetailedInfoCid from '@/views/components/DetailedInfoCid'
|
|
|
+ import _ from 'lodash'
|
|
|
+ import { exportExcel } from '@/utils/export'
|
|
|
+ import { EditPen, Operation, Plus, Search, View } from '@element-plus/icons-vue'
|
|
|
+ import { useI18n } from 'vue-i18n'
|
|
|
+
|
|
|
+ const { Code } = Config
|
|
|
+ const { t } = useI18n()
|
|
|
+ const Session = inject('session')
|
|
|
+ const pigeon = inject('pigeon')
|
|
|
+ const router = useRouter()
|
|
|
+
|
|
|
+ // 响应式数据
|
|
|
+ const formSingle = ref({})
|
|
|
+ const url = Config.Host85
|
|
|
+ const createType = ref('v1')
|
|
|
+ const imgUrl = Config.Host85
|
|
|
+ const pictLoading = ref(false)
|
|
|
+ const editorType = ref(6)
|
|
|
+ const dialogInfoTradingSingle = ref(false)
|
|
|
+ const action = Config.Host85 + '/web/oc/excel'
|
|
|
+ const file = ref('')
|
|
|
+ const countryList = ref([])
|
|
|
+ const dialogInfoTradingAdd = ref(false)
|
|
|
+ const dialogKycAuth = ref(false)
|
|
|
+ const dialogKycUpload = ref(false)
|
|
|
+ const editor = ref('')
|
|
|
+ const addType = ref('')
|
|
|
+ const formList = ref({})
|
|
|
+ const myInfo = ref({})
|
|
|
+ const showImgDialog = ref(false)
|
|
|
+ const currentImgUrl = ref('')
|
|
|
+ // 表单引用
|
|
|
+ const businessFormRef = ref(null)
|
|
|
+ const search = reactive({
|
|
|
+ tag: 1,
|
|
|
+ cId: '',
|
|
|
+ email: '',
|
|
|
+ mobile: '',
|
|
|
+ })
|
|
|
+
|
|
|
+ const pagerInfo = reactive({ row: 10, current: 1, pageTotal: 0, rowTotal: 0 })
|
|
|
+ const businessList = ref([])
|
|
|
+ const idBackUrl = ref([])
|
|
|
+ const idHoldUrl = ref([])
|
|
|
+ const idFrontUrl = ref([])
|
|
|
+ const dialogBusinessEdit = ref(false)
|
|
|
+
|
|
|
+ const businessForm = reactive({
|
|
|
+ merchantOrderNo: '',
|
|
|
+ cardTypeId: 0,
|
|
|
+ areaCode: '',
|
|
|
+ mobile: '',
|
|
|
+ email: '',
|
|
|
+ firstName: '',
|
|
|
+ lastName: '',
|
|
|
+ birthday: '',
|
|
|
+ nationality: '',
|
|
|
+ country: '',
|
|
|
+ town: '',
|
|
|
+ address: '',
|
|
|
+ postCode: '',
|
|
|
+ gender: '',
|
|
|
+ occupation: '',
|
|
|
+ annualSalary: '',
|
|
|
+ accountPurpose: '',
|
|
|
+ expectedMonthlyVolume: '',
|
|
|
+ idType: '',
|
|
|
+ idNumber: '',
|
|
|
+ ssn: '',
|
|
|
+ issueDate: '',
|
|
|
+ idNoExpiryDate: '',
|
|
|
+ idFrontUrl: '',
|
|
|
+ idBackUrl: '',
|
|
|
+ idHoldUrl: '',
|
|
|
+ ipAddress: '',
|
|
|
+ cId: undefined,
|
|
|
+ customId: undefined,
|
|
|
+ })
|
|
|
+
|
|
|
+ const options = ref([])
|
|
|
+ const searchUserList = ref([])
|
|
|
+ const isAdd = ref(true)
|
|
|
+ const selectedUserCid = ref('')
|
|
|
+ const kycUploadForm = reactive({
|
|
|
+ uniqueId: '',
|
|
|
+ kycUploadForm: {
|
|
|
+ type: '',
|
|
|
+ data: '',
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const idTypeList1 = ref([])
|
|
|
+ const idTypeList = ref([
|
|
|
+ { name: 'card.Form.v4', value: 'PASSPORT' },
|
|
|
+ { name: 'card.Form.v3', value: 'HK_HKID' },
|
|
|
+ { name: 'card.Form.v5', value: 'DLN' },
|
|
|
+ { name: 'card.Form.v6', value: 'GOVERNMENT_ISSUED_ID_CARD' },
|
|
|
+ ])
|
|
|
+ const kycUploadUniqueId = ref('')
|
|
|
+ const kycFormList = ref({})
|
|
|
+ const searchEmail = ref('')
|
|
|
+ const selectVisible = ref(false)
|
|
|
+ const showOptions = ref(false)
|
|
|
+ const hoveredOption = ref(null)
|
|
|
+ const countryCityList = ref([])
|
|
|
+ const cityList = ref([])
|
|
|
+ const occupationList = ref([])
|
|
|
+ const dialogInfoCid = ref(false)
|
|
|
+ const formInfo = ref({})
|
|
|
+
|
|
|
+ // 计算属性
|
|
|
+ const display = computed(() => {
|
|
|
+ return JSON.parse(Session.Get('display', true) || '{}')
|
|
|
+ })
|
|
|
+
|
|
|
+ const AccessToken = computed(() => {
|
|
|
+ const token = Session.Get('access_token')
|
|
|
+ return token ? { 'Access-Token': token } : {}
|
|
|
+ })
|
|
|
+
|
|
|
+ const user = computed(() => {
|
|
|
+ return JSON.parse(Session.Get('user', true) || '{}')
|
|
|
+ })
|
|
|
+ // ts没有变量提升,把这个放在rules前面
|
|
|
+ const validateName = (rule, value, callback) => {
|
|
|
+ const reg = /^[A-Za-z\s]+$/
|
|
|
+ if (!value) {
|
|
|
+ return callback(new Error(t('card.vaildate.v4')))
|
|
|
+ }
|
|
|
+ if (!reg.test(value)) {
|
|
|
+ return callback(new Error(t('card.vaildate.v38')))
|
|
|
+ }
|
|
|
+ if (value.length < 2 || value.length > 23) {
|
|
|
+ return callback(new Error(t('card.vaildate.v39')))
|
|
|
+ }
|
|
|
+ // 额外检查:firstName + lastName 总长度不能超过 23
|
|
|
+ const firstName = businessForm.firstName || ''
|
|
|
+ const lastName = businessForm.lastName || ''
|
|
|
+ if ((firstName + ' ' + lastName).trim().length > 23) {
|
|
|
+ return callback(new Error(t('card.vaildate.v40')))
|
|
|
+ }
|
|
|
+ callback()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证规则保持不变
|
|
|
+ const rules = {
|
|
|
+ password: [
|
|
|
+ {
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
+ if (Config.Pattern.Password.test(value)) {
|
|
|
+ callback()
|
|
|
+ } else {
|
|
|
+ callback(new Error(t('vaildate.password.format')))
|
|
|
+ }
|
|
|
+ },
|
|
|
+ trigger: 'blur',
|
|
|
+ required: true,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ areaCode: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v1'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ login: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('placeholder.choose'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ mobile: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v2'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ email: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v28'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ firstName: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v3'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ { validator: validateName, trigger: 'blur' },
|
|
|
+ ],
|
|
|
+ lastName: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v4'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ { validator: validateName, trigger: 'blur' },
|
|
|
+ ],
|
|
|
+ birthday: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v5'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
+ if (!value) {
|
|
|
+ callback(new Error(t('card.vaildate.v5')))
|
|
|
+ } else {
|
|
|
+ const today = new Date()
|
|
|
+ const birthDate = new Date(value)
|
|
|
+ let age = today.getFullYear() - birthDate.getFullYear()
|
|
|
+ const month = today.getMonth() - birthDate.getMonth()
|
|
|
+ if (month < 0 || (month === 0 && today.getDate() < birthDate.getDate())) {
|
|
|
+ age--
|
|
|
+ }
|
|
|
+ if (age < 18) {
|
|
|
+ callback(new Error(t('card.New.n3')))
|
|
|
+ } else {
|
|
|
+ callback()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ nationality: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v6'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ country: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v6'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ town: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v7'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ address: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v27'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
+ const regex = /[\u4e00-\u9fa5]/
|
|
|
+ if (value.length < 2 || value.length > 40) {
|
|
|
+ callback(new Error(t('card.New.n1')))
|
|
|
+ } else if (regex.test(value)) {
|
|
|
+ callback(new Error(t('card.New.n1')))
|
|
|
+ } else {
|
|
|
+ callback()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ addressCn: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v27'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ gender: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v9'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ occupation: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v10'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ annualSalary: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v11'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ accountPurpose: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v12'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ expectedMonthlyVolume: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v13'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ idType: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v14'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ idNumber: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v15'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ ssn: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v16'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ issueDate: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v17'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ idNoExpiryDate: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v18'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+
|
|
|
+ idFrontUrl: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v19'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ idBackUrl: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v20'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ idHoldUrl: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v21'),
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ postCode: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('card.vaildate.v8'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
+ const regex = /^[a-zA-Z0-9]{1,15}$/ // Updated regex
|
|
|
+ if (!regex.test(value)) {
|
|
|
+ callback(new Error(t('card.New.n2'))) // Custom error message
|
|
|
+ } else {
|
|
|
+ callback()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ }
|
|
|
+
|
|
|
+ // 方法
|
|
|
+ const idTypesConfigList = async (code) => {
|
|
|
+ try {
|
|
|
+ let res = await UcardService.idTypesConfigList({
|
|
|
+ code,
|
|
|
+ page: {
|
|
|
+ current: pagerInfo.current,
|
|
|
+ row: pagerInfo.row,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const data = res.data
|
|
|
+ if (data && data.length) {
|
|
|
+ const selectedValues = data[0].idType.split(',')
|
|
|
+ idTypeList1.value = idTypeList.value.filter((item) => selectedValues.includes(item.value))
|
|
|
+ } else {
|
|
|
+ idTypeList1.value = idTypeList.value
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const exportAgents = async () => {
|
|
|
+ exportExcel(pigeon, '/wasabi/merchant/user/list/export', { ...search }, 'Merchant_User_List')
|
|
|
+ }
|
|
|
+
|
|
|
+ const setAddress = (e) => {
|
|
|
+ const containsChinese = (str) => /[\u4e00-\u9fa5]/.test(str)
|
|
|
+ if (containsChinese(e)) {
|
|
|
+ businessForm.address = formatText(e)
|
|
|
+ } else {
|
|
|
+ businessForm.address = e
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const formatText = (input) => {
|
|
|
+ const chinesePattern = /[\u4e00-\u9fa5]+/g
|
|
|
+ let formattedText = input.replace(chinesePattern, (match) => {
|
|
|
+ return ' ' + pinyin(match, { toneType: 'none', type: 'capitalize' }) + ' '
|
|
|
+ })
|
|
|
+ return formattedText
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleAvatarSuccessBankEn = (res) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ pigeon.MessageOK(t('Msg.Success'))
|
|
|
+ businessForm.idFrontUrl = res.data
|
|
|
+ } else {
|
|
|
+ pigeon.MessageError(res.code)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleAvatarSuccessBankEn1 = (res) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ pigeon.MessageOK(t('Msg.Success'))
|
|
|
+ businessForm.idBackUrl = res.data
|
|
|
+ } else {
|
|
|
+ pigeon.MessageError(res.code)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleAvatarSuccessBankEn2 = (res) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ pigeon.MessageOK(t('Msg.Success'))
|
|
|
+ businessForm.idHoldUrl = res.data
|
|
|
+ } else {
|
|
|
+ pigeon.MessageError(res.code)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleExceed = () => {
|
|
|
+ pigeon.MessageError(t('Msg.OverLimit'))
|
|
|
+ }
|
|
|
+
|
|
|
+ const beforeAvatarUpload = (file) => {
|
|
|
+ const isJPG =
|
|
|
+ ['jpeg', 'JPEG', 'png', 'PNG', 'jpg', 'JPG'].indexOf(file.name.split('.')[1]) == -1
|
|
|
+ ? false
|
|
|
+ : true
|
|
|
+ const isLt2M = file.size / 1024 / 1024 < 2
|
|
|
+
|
|
|
+ if (!isJPG) {
|
|
|
+ pigeon.MessageError(t('Msg.JPG1'))
|
|
|
+ }
|
|
|
+ if (!isLt2M) {
|
|
|
+ pigeon.MessageError(t('card.Msg.m19'))
|
|
|
+ }
|
|
|
+ return isJPG && isLt2M
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleCommand = (command) => {
|
|
|
+ if (command.type === 'edit') {
|
|
|
+ isAdd.value = false
|
|
|
+ editBusiness(command.row)
|
|
|
+ } else if (command.type === 'payment') {
|
|
|
+ addType.value = 'payment'
|
|
|
+ dialogInfoTradingAdd.value = true
|
|
|
+ formList.value = command.row
|
|
|
+ } else if (command.type === 'kyc_upload') {
|
|
|
+ dialogKycUpload.value = true
|
|
|
+ kycUploadForm.uniqueId = command.row.uniqueId
|
|
|
+ kycUploadForm.kycUploadForm = {
|
|
|
+ type: '',
|
|
|
+ data: '',
|
|
|
+ }
|
|
|
+ } else if (command.type === 'kycup') {
|
|
|
+ addType.value = 'kyc_auth'
|
|
|
+ dialogKycAuth.value = true
|
|
|
+ kycFormList.value = {
|
|
|
+ uniqueId: command.row.uniqueId,
|
|
|
+ cId: command.row.cId,
|
|
|
+ lastName: command.row.lastName,
|
|
|
+ firstName: command.row.firstName,
|
|
|
+ email: command.row.email,
|
|
|
+ mobile: command.row.mobile,
|
|
|
+ }
|
|
|
+ } else if (command.type === 0) {
|
|
|
+ dialogInfoTradingSingle.value = true
|
|
|
+ formSingle.value = command.row
|
|
|
+ } else if (command.type === 1) {
|
|
|
+ addType.value = 10
|
|
|
+ dialogInfoTradingAdd.value = true
|
|
|
+ formList.value = command.row
|
|
|
+ } else if (command.type === 2) {
|
|
|
+ photoManually(command.row)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const closeSingle = () => {
|
|
|
+ dialogInfoTradingSingle.value = false
|
|
|
+ }
|
|
|
+
|
|
|
+ const previewImg = (url) => {
|
|
|
+ currentImgUrl.value = imgUrl + url
|
|
|
+ showImgDialog.value = true
|
|
|
+ }
|
|
|
+
|
|
|
+ const getCountryList = async () => {
|
|
|
+ const res = await Service.countryGet({})
|
|
|
+ if (res.code === 200 || res.code === 0) {
|
|
|
+ countryList.value = res.data
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const photoManually = async ({ id, uniqueId, cId }) => {
|
|
|
+ const res = await UcardService.photoManually({ id, uniqueId, cId })
|
|
|
+ if (res.code === 200 || res.code === 0) {
|
|
|
+ pigeon.MessageOK(t('Msg.SearchSuccess'))
|
|
|
+ toSearch()
|
|
|
+ } else {
|
|
|
+ Message.error(res.msg)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const closeKycUpload = () => {
|
|
|
+ dialogKycUpload.value = false
|
|
|
+ kycUploadForm.uniqueId = ''
|
|
|
+ kycUploadForm.kycUploadForm = { type: '', data: '' }
|
|
|
+ }
|
|
|
+
|
|
|
+ const toSearch = () => {
|
|
|
+ pagerInfo.current = 1
|
|
|
+ searchFunc()
|
|
|
+ }
|
|
|
+
|
|
|
+ const searchFunc = async () => {
|
|
|
+ if (!display.value['R-Business-Search']?.show) {
|
|
|
+ pigeon.MessageWarning(t('Msg.NotDisplay'))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ pictLoading.value = true
|
|
|
+ try {
|
|
|
+ const params = {
|
|
|
+ ...search,
|
|
|
+ page: {
|
|
|
+ current: pagerInfo.current,
|
|
|
+ row: pagerInfo.row,
|
|
|
+ },
|
|
|
+ }
|
|
|
+ const res = await UcardService.merchantList(params)
|
|
|
+ if (res.code === Code.StatusOK) {
|
|
|
+ businessList.value = res.data
|
|
|
+ pagerInfo.rowTotal = res.page?.rowTotal || 0
|
|
|
+ pagerInfo.pageTotal = res.page?.pageTotal || 0
|
|
|
+ pigeon.MessageOK(t('Msg.SearchSuccess'))
|
|
|
+ } else {
|
|
|
+ pigeon.MessageError(res.msg || t('Ucard.Business.ms2'))
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Search error:', error)
|
|
|
+ pigeon.MessageError(t('Ucard.Business.ms2'))
|
|
|
+ } finally {
|
|
|
+ pictLoading.value = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleSizeChange = (val) => {
|
|
|
+ pagerInfo.row = val
|
|
|
+ searchFunc()
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleCurrentChange = (val) => {
|
|
|
+ pagerInfo.current = val
|
|
|
+ searchFunc()
|
|
|
+ }
|
|
|
+
|
|
|
+ const editBusiness = (row) => {
|
|
|
+ isAdd.value = false
|
|
|
+ Object.assign(businessForm, JSON.parse(JSON.stringify(row)))
|
|
|
+ dialogBusinessEdit.value = true
|
|
|
+ }
|
|
|
+
|
|
|
+ const saveBusiness = async () => {
|
|
|
+ businessForm.ipAddress = sessionStorage.getItem('CLIENT')
|
|
|
+ businessForm.country = businessForm.nationality
|
|
|
+
|
|
|
+ try {
|
|
|
+ const valid = await businessFormRef.value.validate()
|
|
|
+ if (!valid) return
|
|
|
+
|
|
|
+ if (isAdd.value) {
|
|
|
+ const res = await UcardService.merchantRegister({
|
|
|
+ cId: selectedUserCid.value,
|
|
|
+ operateUser: user.value.id,
|
|
|
+ ...businessForm,
|
|
|
+ })
|
|
|
+ if (res.code !== 200) {
|
|
|
+ throw new Error(res.msg)
|
|
|
+ }
|
|
|
+ Message.success(t('Ucard.Business.ms5'))
|
|
|
+ } else if (businessForm.uniqueId) {
|
|
|
+ const res = await UcardService.merchantUpdate({
|
|
|
+ ...businessForm,
|
|
|
+ merchantOrderNo: businessForm.uniqueId || '',
|
|
|
+ })
|
|
|
+ if (res.code !== 200) {
|
|
|
+ throw new Error(res.msg)
|
|
|
+ }
|
|
|
+ Message.success(t('Ucard.Business.ms7'))
|
|
|
+ } else {
|
|
|
+ throw new Error(t('Ucard.Business.ms13'))
|
|
|
+ }
|
|
|
+
|
|
|
+ dialogBusinessEdit.value = false
|
|
|
+ resetForm()
|
|
|
+ await searchFunc()
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const closeAdd = () => {
|
|
|
+ dialogInfoTradingAdd.value = false
|
|
|
+ }
|
|
|
+
|
|
|
+ const closeDiaAdd = () => {
|
|
|
+ dialogInfoTradingAdd.value = false
|
|
|
+ }
|
|
|
+
|
|
|
+ const confirmToReload = () => {
|
|
|
+ closeDiaAdd()
|
|
|
+ searchFunc()
|
|
|
+ }
|
|
|
+
|
|
|
+ const remoteMethod = async (query) => {
|
|
|
+ if (!query) return
|
|
|
+ const params = { email: query }
|
|
|
+ try {
|
|
|
+ const res = await UcardService.merchantSearch(params)
|
|
|
+ if (res.code === 200) {
|
|
|
+ searchUserList.value = res.data
|
|
|
+ options.value = res.data.map((item) => ({
|
|
|
+ label: item.email,
|
|
|
+ value: item.cId,
|
|
|
+ name: item.firstName && item.lastName ? item.lastName + item.firstName : '',
|
|
|
+ nationality: item.nationality,
|
|
|
+ }))
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ // console.log(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const getOccupationList = async () => {
|
|
|
+ try {
|
|
|
+ const res = await UcardService.getOccupationList()
|
|
|
+ if (res.code === 200) {
|
|
|
+ occupationList.value = res.data
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ occupationList.value = []
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const changeSelect = (cId) => {
|
|
|
+ const selectedUser = searchUserList.value.find((item) => item.cId === cId)
|
|
|
+ if (selectedUser) {
|
|
|
+ businessForm.uniqueId = selectedUser.uniqueId || undefined
|
|
|
+ businessForm.areaCode = selectedUser.areaCode || undefined
|
|
|
+ businessForm.mobile = selectedUser.phone || undefined
|
|
|
+ businessForm.email = selectedUser.email || undefined
|
|
|
+ businessForm.customId = selectedUser.id || undefined
|
|
|
+
|
|
|
+ const lastName = selectedUser.lastName || undefined
|
|
|
+ const firstName = selectedUser.firstName || undefined
|
|
|
+ const containsChinese = (str) => /[\u4e00-\u9fa5]/.test(str)
|
|
|
+
|
|
|
+ if (containsChinese(lastName)) {
|
|
|
+ businessForm.lastName = pinyin(lastName, {
|
|
|
+ toneType: 'none',
|
|
|
+ type: 'capitalize',
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ businessForm.lastName = lastName
|
|
|
+ }
|
|
|
+
|
|
|
+ if (containsChinese(firstName)) {
|
|
|
+ businessForm.firstName = pinyin(firstName, {
|
|
|
+ toneType: 'none',
|
|
|
+ type: 'capitalize',
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ businessForm.firstName = firstName
|
|
|
+ }
|
|
|
+
|
|
|
+ businessForm.address = selectedUser.address || undefined
|
|
|
+ businessForm.postCode = selectedUser.postCode || undefined
|
|
|
+ businessForm.birthday = selectedUser.birthday || undefined
|
|
|
+ businessForm.nationality = selectedUser.nationality || undefined
|
|
|
+ businessForm.sex = selectedUser.sex || undefined
|
|
|
+ businessForm.country = selectedUser.country || selectedUser.countryCode || undefined
|
|
|
+ businessForm.town = selectedUser.town || undefined
|
|
|
+ businessForm.idType = selectedUser.idType || undefined
|
|
|
+ businessForm.idNo = selectedUser.idNo || undefined
|
|
|
+ businessForm.idNoExpiryDate = selectedUser.idNoExpiryDate || undefined
|
|
|
+ businessForm.idFrontUrl = selectedUser.idFrontUrl || undefined
|
|
|
+ businessForm.idBackUrl = selectedUser.idBackUrl || undefined
|
|
|
+ businessForm.extField = selectedUser.extField || undefined
|
|
|
+ selectedUserCid.value = selectedUser.cId
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const resetForm = () => {
|
|
|
+ const defaultForm = {
|
|
|
+ uniqueId: undefined,
|
|
|
+ areaCode: undefined,
|
|
|
+ mobile: undefined,
|
|
|
+ email: undefined,
|
|
|
+ lastName: undefined,
|
|
|
+ firstName: undefined,
|
|
|
+ birthday: undefined,
|
|
|
+ nationality: undefined,
|
|
|
+ sex: undefined,
|
|
|
+ country: undefined,
|
|
|
+ town: undefined,
|
|
|
+ address: undefined,
|
|
|
+ postCode: undefined,
|
|
|
+ idType: undefined,
|
|
|
+ idNo: undefined,
|
|
|
+ idNoExpiryDate: undefined,
|
|
|
+ idFrontUrl: undefined,
|
|
|
+ idBackUrl: undefined,
|
|
|
+ extField: undefined,
|
|
|
+ cId: undefined,
|
|
|
+ }
|
|
|
+
|
|
|
+ Object.assign(businessForm, defaultForm)
|
|
|
+ options.value = []
|
|
|
+ searchUserList.value = []
|
|
|
+ isAdd.value = true
|
|
|
+ selectedUserCid.value = ''
|
|
|
+ searchEmail.value = ''
|
|
|
+ showOptions.value = false
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleKycFileUpload = async (option) => {
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('file', option.file)
|
|
|
+ try {
|
|
|
+ const res = await UcardService.ucardUpload(formData)
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
+ kycUploadForm.data = res.data
|
|
|
+ Message.success(t('Ucard.Business.ms11'))
|
|
|
+ option.onSuccess(res, option.file)
|
|
|
+ } else {
|
|
|
+ Message.error(res.msg)
|
|
|
+ option.onError()
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ Message.error(t('Ucard.Business.ms12'))
|
|
|
+ option.onError()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const submitKycUpload = async () => {
|
|
|
+ const uniqueId = kycUploadUniqueId.value || businessForm.uniqueId
|
|
|
+ if (!uniqueId) {
|
|
|
+ Message.error(t('Ucard.Business.ms13'))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!kycUploadForm.type || !kycUploadForm.data) {
|
|
|
+ Message.error(t('Ucard.Business.ms14'))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const params = {
|
|
|
+ uniqueId,
|
|
|
+ type: kycUploadForm.type,
|
|
|
+ data: kycUploadForm.data,
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ const res = await UcardService.kycUpload(params)
|
|
|
+ if (res.code === 0) {
|
|
|
+ Message.success(res.msg)
|
|
|
+ kycUploadForm.type = ''
|
|
|
+ kycUploadForm.data = ''
|
|
|
+ dialogKycUpload.value = false
|
|
|
+ } else {
|
|
|
+ Message.error(res.msg)
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ Message.error(t('Ucard.Business.ms16'))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const closeKycAuth = (val) => {
|
|
|
+ dialogKycAuth.value = val
|
|
|
+ }
|
|
|
+
|
|
|
+ const debouncedRemoteMethod = _.debounce((query) => {
|
|
|
+ if (!query) return
|
|
|
+ remoteMethod(query)
|
|
|
+ }, 500)
|
|
|
+
|
|
|
+ const updateSearchEmail = (val) => {
|
|
|
+ searchEmail.value = val
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleSearch = () => {
|
|
|
+ if (!searchEmail.value) return
|
|
|
+ debouncedRemoteMethod(searchEmail.value)
|
|
|
+ showOptions.value = true
|
|
|
+ }
|
|
|
+
|
|
|
+ const selectOption = (item) => {
|
|
|
+ businessForm.cId = item.value
|
|
|
+ searchEmail.value = item.label
|
|
|
+ changeSelect(item.value)
|
|
|
+ showOptions.value = false
|
|
|
+ }
|
|
|
+
|
|
|
+ const getCountryListForSelect = async () => {
|
|
|
+ const res = await UcardService.ucardCountryCity({ code: '' })
|
|
|
+ if (res.code === 200 || res.code === 0) {
|
|
|
+ countryCityList.value = res.data || []
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const getCityListForSelect = async (countryCode) => {
|
|
|
+ const res = await UcardService.ucardCountryCity({ code: countryCode })
|
|
|
+ if (res.code === 200 || res.code === 0) {
|
|
|
+ cityList.value = res.data || []
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const accountOpen = (cId) => {
|
|
|
+ router.push({ name: 'R-CustomerDetail', params: { cId: cId } })
|
|
|
+ }
|
|
|
+
|
|
|
+ const closeCidDialog = (val) => {
|
|
|
+ dialogInfoCid.value = val
|
|
|
+ }
|
|
|
+
|
|
|
+ const isBusinessFormValid = () => {
|
|
|
+ const requiredFields = ['areaCode', 'mobile', 'email', 'lastName', 'firstName', 'address']
|
|
|
+ return requiredFields.every((field) => !!businessForm[field])
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生命周期
|
|
|
+ onMounted(async () => {
|
|
|
+ try {
|
|
|
+ await Promise.all([searchFunc(), getCountryListForSelect()])
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Initialization error:', error)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 监听器
|
|
|
+ watch(
|
|
|
+ () => search.tag,
|
|
|
+ () => {
|
|
|
+ search.cId = ''
|
|
|
+ search.email = ''
|
|
|
+ search.mobile = ''
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+ watch(dialogBusinessEdit, (val) => {
|
|
|
+ if (val) {
|
|
|
+ getOccupationList()
|
|
|
+ if (isAdd.value) {
|
|
|
+ searchEmail.value = ''
|
|
|
+ showOptions.value = false
|
|
|
+ options.value = []
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ resetForm()
|
|
|
+ isAdd.value = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ watch(
|
|
|
+ () => businessForm.nationality,
|
|
|
+ (val) => {
|
|
|
+ if (val) {
|
|
|
+ getCityListForSelect(val)
|
|
|
+ idTypesConfigList(val)
|
|
|
+ } else {
|
|
|
+ cityList.value = []
|
|
|
+ businessForm.town = ''
|
|
|
+ businessForm.idType = ''
|
|
|
+ }
|
|
|
+ }
|
|
|
+ )
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+ @import 'index.scss';
|
|
|
+</style>
|
|
|
+<style lang="scss">
|
|
|
+ #review_Email {
|
|
|
+ .dialog_header_w {
|
|
|
+ .crm_search_down {
|
|
|
+ width: 400px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|