|
@@ -0,0 +1,1526 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <cwg-page-wrapper>
|
|
|
|
|
+ <view class="page page-shadow">
|
|
|
|
|
+ <uni-forms ref="formRef" :model="formData" :rules="rules" labelWidth="200" label-position="top"
|
|
|
|
|
+ class="payment-form">
|
|
|
|
|
+ <!-- 第一步:个人信息 -->
|
|
|
|
|
+ <view v-show="currentStep === 1" class="form-section">
|
|
|
|
|
+ <h3 class="section-title">{{ t('ImproveImmediately.Title.BasicInformation') }}</h3>
|
|
|
|
|
+ <uni-row class="demo-uni-row uni-row1">
|
|
|
|
|
+ <!-- 客户类型 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item :label="t('ImproveImmediately.Label.CustomerType')">
|
|
|
|
|
+ <cwg-combox :clearable="false" v-model:value="formData.customType"
|
|
|
|
|
+ :options="customerTypeOptions" :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 公司名称 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-if="formData.customType == 2">
|
|
|
|
|
+ <uni-forms-item :label="t('ImproveImmediately.Label.CompanyName')">
|
|
|
|
|
+ <uni-easyinput :clearable="false" v-model="formData.companyName"
|
|
|
|
|
+ :placeholder="t('placeholder.input')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 姓 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item :label="formData.customType == 2
|
|
|
|
|
+ ? t('ImproveImmediately.Label.CorporationLastName')
|
|
|
|
|
+ : t('ImproveImmediately.Label.LastName')">
|
|
|
|
|
+ <uni-easyinput :clearable="false" v-model="formData.lastName" :placeholder="t('placeholder.input')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 名 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item :label="formData.customType == 2
|
|
|
|
|
+ ? t('ImproveImmediately.Label.CorporationName')
|
|
|
|
|
+ : t('ImproveImmediately.Label.Name')">
|
|
|
|
|
+ <uni-easyinput :clearable="false" v-model="formData.firstName" :placeholder="t('placeholder.input')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 法人中间名 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-if="lang == 'en'">
|
|
|
|
|
+ <uni-forms-item name="middle" :label="t('placeholder.middle')">
|
|
|
|
|
+ <uni-easyinput :clearable="false" v-model="formData.middle" :placeholder="t('placeholder.input')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 国家 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-if="countryOptions.length > 0">
|
|
|
|
|
+ <uni-forms-item name="nationality" :label="t('ImproveImmediately.Label.Nationality')">
|
|
|
|
|
+ <cwg-combox :clearable="false" :filterable="true"
|
|
|
|
|
+ v-model:value="formData.nationality" :options="countryOptions"
|
|
|
|
|
+ :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 证件类型 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="IdentityType" :label="identityLabel">
|
|
|
|
|
+ <cwg-combox :clearable="false" v-model:value="formData.IdentityType"
|
|
|
|
|
+ :options="identityTypes" :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 证件号 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="identity" :label="t('ImproveImmediately.Label.IdentityID')">
|
|
|
|
|
+ <uni-easyinput :clearable="false" v-model="formData.identity" :placeholder="t('placeholder.input')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 拼音 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-if="['cn', 'zhHant'].includes(lang)">
|
|
|
|
|
+ <uni-forms-item name="nameEn" :label="t('ImproveImmediately.Label.NamePinYin')">
|
|
|
|
|
+ <uni-easyinput :clearable="false" v-model="formData.nameEn" :placeholder="t('placeholder.input')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 性别 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="gender" :label="t('ImproveImmediately.Label.Gender')">
|
|
|
|
|
+ <cwg-combox :clearable="false" v-model:value="formData.gender" :options="genderOptions"
|
|
|
|
|
+ :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 生日 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="birth" :label="t('ImproveImmediately.Label.Birthday')">
|
|
|
|
|
+ <uni-datetime-picker :clear-icon="false" type="date" return-type="timestamp"
|
|
|
|
|
+ v-model="formData.birth" :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :span="24">
|
|
|
|
|
+ <view class="crm-title-box">
|
|
|
|
|
+ <text class="tit">{{ t('ImproveImmediately.Title.AddressInformation') }}</text>
|
|
|
|
|
+ <uni-popup ref="addressTipPopup" type="center">
|
|
|
|
|
+ <view class="popup-content">{{ t('ImproveImmediately.Title.AddressTip') }}</view>
|
|
|
|
|
+ </uni-popup>
|
|
|
|
|
+ <text class="icon-tip" @click="openAddressTip">ⓘ</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 国家/地区 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-if="countryOptions.length > 0">
|
|
|
|
|
+ <uni-forms-item name="country" :label="t('ImproveImmediately.Label.CountryRegionOfResidence')">
|
|
|
|
|
+ <cwg-combox :clearable="false" :filterable="true" v-model:value="formData.country"
|
|
|
|
|
+ :options="countryOptions" :placeholder="t('placeholder.choose')" @change="changeCountry" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 省份/州 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
|
|
|
|
|
+ v-if="formData.country == 'CN' || formData.country == 'CNX' || formData.country == 'CNA' || formData.country == 'CNT'">
|
|
|
|
|
+ <uni-forms-item name="state" :label="t('ImproveImmediately.Label.ProvinceRegion')">
|
|
|
|
|
+ <cwg-combox :clearable="false" :filterable="true" v-model:value="formData.state"
|
|
|
|
|
+ :options="stateOptions" :placeholder="t('placeholder.choose')" @change="changeState" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 国外省份/州 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-else>
|
|
|
|
|
+ <uni-forms-item name="state" :label="t('ImproveImmediately.Label.ProvinceRegion')">
|
|
|
|
|
+ <uni-easyinput :clearable="false" v-model="formData.state" :placeholder="t('placeholder.input')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 城市 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
|
|
|
|
|
+ v-if="formData.country == 'CN' || formData.country == 'CNX' || formData.country == 'CNA' || formData.country == 'CNT'">
|
|
|
|
|
+ <uni-forms-item name="city" :label="t('ImproveImmediately.Label.City')">
|
|
|
|
|
+ <cwg-combox :clearable="false" :filterable="true" v-model:value="formData.city"
|
|
|
|
|
+ :options="cityOptions" :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <!-- 国外城市 -->
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-else>
|
|
|
|
|
+ <uni-forms-item name="city" :label="t('ImproveImmediately.Label.City')">
|
|
|
|
|
+ <uni-easyinput :clearable="false" v-model="formData.city" :placeholder="t('placeholder.input')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="addressLines1" :label="t('ImproveImmediately.Label.DetailedAddress')">
|
|
|
|
|
+ <uni-easyinput :clearable="false" v-model="formData.addressLines1"
|
|
|
|
|
+ :placeholder="t('placeholder.input')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="zipCode" :label="t('ImproveImmediately.Label.ZipCode')">
|
|
|
|
|
+ <uni-easyinput :clearable="false" v-model="formData.zipCode" :placeholder="t('placeholder.input')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="addressLines2" :label="t('ImproveImmediately.Label.DetailedAddressStandby')">
|
|
|
|
|
+ <uni-easyinput :clearable="false" v-model="formData.addressLines2"
|
|
|
|
|
+ :placeholder="t('placeholder.input')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ </uni-row>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- 第二步:财务背景 -->
|
|
|
|
|
+ <view v-show="currentStep === 2" class="form-section">
|
|
|
|
|
+ <h3 class="section-title">{{ t('ImproveImmediately.Title.FinancialBackground') }}</h3>
|
|
|
|
|
+ <uni-row class="demo-uni-row uni-row1">
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="level" :label="t('ImproveImmediately.Label.Education')">
|
|
|
|
|
+ <cwg-combox :clearable="false" v-model:value="formData.level"
|
|
|
|
|
+ :options="educationOptions" :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="employmentStatus" :label="t('ImproveImmediately.Label.OnJob')">
|
|
|
|
|
+ <cwg-combox :clearable="false" v-model:value="formData.employmentStatus"
|
|
|
|
|
+ :options="employmentOptions" :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="tradingObjectives" :label="t('ImproveImmediately.Label.purposeTransaction')">
|
|
|
|
|
+ <cwg-combox :clearable="false" v-model:value="formData.tradingObjectives"
|
|
|
|
|
+ :options="transactionPurposeOptions" :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="sourceFunding" :label="t('ImproveImmediately.Label.SourceFunds')">
|
|
|
|
|
+ <cwg-combox :clearable="false" v-model:value="formData.sourceFunding"
|
|
|
|
|
+ :options="fundSourceOptions" :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="grossAnnualIncome" :label="t('ImproveImmediately.Label.TotalAnnualRevenue')">
|
|
|
|
|
+ <cwg-combox :clearable="false" v-model:value="formData.grossAnnualIncome"
|
|
|
|
|
+ :options="annualIncomeOptions" :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
|
|
|
|
|
+ <uni-forms-item name="totalNewWorth" :label="t('ImproveImmediately.Label.TotalNetAssets')">
|
|
|
|
|
+ <cwg-combox :clearable="false" v-model:value="formData.totalNewWorth"
|
|
|
|
|
+ :options="netWorthOptions" :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ </uni-row>
|
|
|
|
|
+ <h3 class="section-title">{{ t('ImproveImmediately.Title.TradingExperience') }}</h3>
|
|
|
|
|
+ <view class="experience">
|
|
|
|
|
+ <text class="Trad-experience">{{ t('ImproveImmediately.Content.TradingExperience1') }}</text>
|
|
|
|
|
+ <view class="Trad-choose">
|
|
|
|
|
+ <uni-data-checkbox v-model="formData.experienceTradingDerivative"
|
|
|
|
|
+ :localdata="radioList"></uni-data-checkbox>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="experience">
|
|
|
|
|
+ <text class="Trad-experience">{{ t('ImproveImmediately.Content.TradingExperience2') }}</text>
|
|
|
|
|
+ <view class="Trad-choose">
|
|
|
|
|
+ <uni-data-checkbox v-model="formData.experienceTradingForex" :localdata="radioList"></uni-data-checkbox>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="experience">
|
|
|
|
|
+ <text class="Trad-experience">{{ t('ImproveImmediately.Content.TradingExperience3') }}</text>
|
|
|
|
|
+ <view class="Trad-choose">
|
|
|
|
|
+ <uni-data-checkbox v-model="formData.derivativeProducts" :localdata="radioList"></uni-data-checkbox>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="experience">
|
|
|
|
|
+ <text class="Trad-experience">{{ t('ImproveImmediately.Content.TradingExperience4') }}</text>
|
|
|
|
|
+ <view class="Trad-choose">
|
|
|
|
|
+ <uni-data-checkbox v-model="formData.experienceQualification" :localdata="radioList"></uni-data-checkbox>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- 第三步:身份证明 -->
|
|
|
|
|
+ <view v-show="currentStep === 3" class="form-section">
|
|
|
|
|
+ <h3 class="section-title">{{ t('ImproveImmediately.Title.ProofIdentityUpdate') }}</h3>
|
|
|
|
|
+ <uni-row class="demo-uni-row uni-row1">
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
|
|
|
|
|
+ <uni-forms-item name="cardType" :label="t('ImproveImmediately.Label.CardType')">
|
|
|
|
|
+ <cwg-combox :clearable="false" v-model:value="formData.cardType"
|
|
|
|
|
+ :options="cardTypeOptions" :placeholder="t('placeholder.choose')" />
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ <uni-row class="demo-uni-row uni-row1">
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="10" :lg="10" :xl="10">
|
|
|
|
|
+ <cwg-file-picker
|
|
|
|
|
+ v-if="!fileListID1.path"
|
|
|
|
|
+ v-model="fileListID1.path"
|
|
|
|
|
+ :editable="fileListID1.status != 2"
|
|
|
|
|
+ :limit="1"
|
|
|
|
|
+ :fileMediatype="'all'"
|
|
|
|
|
+ uploadUrl="/custom/file/upload/1"
|
|
|
|
|
+ :baseUrl="updateUrl"
|
|
|
|
|
+ :imageWidth="150"
|
|
|
|
|
+ :imageHeight="150"
|
|
|
|
|
+ :showPreviewDelete="false"
|
|
|
|
|
+ :canDelete="false"
|
|
|
|
|
+ :uploadError="false"
|
|
|
|
|
+ :showProgress="false"
|
|
|
|
|
+ :image-styles="imageStyle"
|
|
|
|
|
+ @update:modelValue="(val) => handleFileUpdate(val, '1')"
|
|
|
|
|
+ customClass="avatar-uploader"
|
|
|
|
|
+ />
|
|
|
|
|
+ <view v-else>
|
|
|
|
|
+ <view class="file-item">
|
|
|
|
|
+ <image
|
|
|
|
|
+ v-if="!isPdf(fileListID1.path)"
|
|
|
|
|
+ class="avatar"
|
|
|
|
|
+ :src="updateUrl + fileListID1.path"
|
|
|
|
|
+ ></image>
|
|
|
|
|
+ <view v-else>
|
|
|
|
|
+ <image class="icon" :src="icon_doc" />
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="10" :lg="10" :xl="10">
|
|
|
|
|
+ <cwg-file-picker
|
|
|
|
|
+ v-if="!fileListID2.path"
|
|
|
|
|
+ v-model="fileListID2.path"
|
|
|
|
|
+ :editable="fileListID2.status != 2"
|
|
|
|
|
+ :limit="1"
|
|
|
|
|
+ :fileMediatype="'all'"
|
|
|
|
|
+ uploadUrl="/custom/file/upload/2"
|
|
|
|
|
+ :baseUrl="updateUrl"
|
|
|
|
|
+ :imageWidth="150"
|
|
|
|
|
+ :imageHeight="150"
|
|
|
|
|
+ :showPreviewDelete="false"
|
|
|
|
|
+ :canDelete="false"
|
|
|
|
|
+ :uploadError="false"
|
|
|
|
|
+ :showProgress="false"
|
|
|
|
|
+ :image-styles="imageStyle"
|
|
|
|
|
+ @update:modelValue="(val) => handleFileUpdate(val, '2')"
|
|
|
|
|
+ customClass="avatar-uploader"
|
|
|
|
|
+ >
|
|
|
|
|
+ </cwg-file-picker>
|
|
|
|
|
+ <view v-else>
|
|
|
|
|
+ <view class="file-item">
|
|
|
|
|
+ <image
|
|
|
|
|
+ v-if="!isPdf(fileListID2.path)"
|
|
|
|
|
+ class="avatar"
|
|
|
|
|
+ :src="updateUrl + fileListID2.path"
|
|
|
|
|
+ ></image>
|
|
|
|
|
+ <view v-else>
|
|
|
|
|
+ <image class="icon" :src="icon_doc" />
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="4" :lg="4" :xl="4">
|
|
|
|
|
+ <view class="refresh-icon">
|
|
|
|
|
+ <image style="width: 28px;" :src="icon_refresh" />
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ </uni-row>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
|
|
|
|
|
+
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ </uni-row>
|
|
|
|
|
+ <view class="descending">
|
|
|
|
|
+ <p class="title">
|
|
|
|
|
+ <span class="dian1">·</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Title.IdentificationStatement') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des">
|
|
|
|
|
+ <span class="dian">-</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofIdentity4') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des">
|
|
|
|
|
+ <span class="dian">-</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofIdentity5') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des" v-if="['cn', 'zhHant'].indexOf(lang) == -1">
|
|
|
|
|
+ <span class="dian">-</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofIdentity6') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des">
|
|
|
|
|
+ <span class="dian">·</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofIdentity1') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des">
|
|
|
|
|
+ <span class="dian">·</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofIdentity2') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des">
|
|
|
|
|
+ <span class="dian">·</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofIdentity3') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des" v-if="['cn', 'zhHant'].indexOf(lang) == -1">
|
|
|
|
|
+ <span class="dian">·</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofIdentity7') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des" v-if="['cn', 'zhHant'].indexOf(lang) == -1">
|
|
|
|
|
+ <span class="dian">·</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofIdentity8') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- 第四步:地址证明 -->
|
|
|
|
|
+ <view v-show="currentStep === 4" class="form-section">
|
|
|
|
|
+ <h3 class="section-title">{{ t('ImproveImmediately.Title.ProofAddress') }}</h3>
|
|
|
|
|
+ <uni-row class="demo-uni-row uni-row1">
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="24" :lg="16" :xl="16">
|
|
|
|
|
+ <uni-forms-item name="addressProofUrl" :label="t('ImproveImmediately.Label.AddressProof')">
|
|
|
|
|
+ <cwg-input
|
|
|
|
|
+ v-model:value="formData.addressProofUrl"
|
|
|
|
|
+ :required="true"
|
|
|
|
|
+ type="upload"
|
|
|
|
|
+ fkey="addressProofUrl"
|
|
|
|
|
+ rulesKey="addressProofUrl"
|
|
|
|
|
+ :is-upload-d="true"
|
|
|
|
|
+ accept="image/png, image/jpeg, image/jpg"
|
|
|
|
|
+ @change="handleChange">
|
|
|
|
|
+ <view class="cwg-upload">
|
|
|
|
|
+ <cwg-icon name="back-top" />
|
|
|
|
|
+ <view class="name">
|
|
|
|
|
+ {{ t('Btn.Upload') }}
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="back">{{ t('ImproveImmediately.Content.ProofAddress1') }}</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </cwg-input>
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ <uni-col :xs="24" :sm="24" :md="24" :lg="16" :xl="16">
|
|
|
|
|
+ <uni-forms-item name="otherFiles" :label="t('PersonalManagement.Title.AttachedFile')">
|
|
|
|
|
+ <cwg-input
|
|
|
|
|
+ v-model:value="formData.otherFiles"
|
|
|
|
|
+ type="upload"
|
|
|
|
|
+ multiple
|
|
|
|
|
+ fkey="otherFiles"
|
|
|
|
|
+ rulesKey="otherFiles"
|
|
|
|
|
+ :is-upload-d="true"
|
|
|
|
|
+ accept="image/png, image/jpeg, image/jpg, application/pdf"
|
|
|
|
|
+ @change="handleChange">
|
|
|
|
|
+ <view class="cwg-upload">
|
|
|
|
|
+ <cwg-icon name="back-top" />
|
|
|
|
|
+ <view class="name">
|
|
|
|
|
+ {{ t('Btn.Upload') }}
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="back">{{ t('ImproveImmediately.Content.ProofAddress6') }}</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </cwg-input>
|
|
|
|
|
+ </uni-forms-item>
|
|
|
|
|
+ </uni-col>
|
|
|
|
|
+ </uni-row>
|
|
|
|
|
+ <view class="descending">
|
|
|
|
|
+ <p class="title">
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Title.AddressDescription') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des">
|
|
|
|
|
+ <span class="dian">-</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofAddress1') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des">
|
|
|
|
|
+ <span class="dian">-</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofAddress2') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des">
|
|
|
|
|
+ <span class="dian">-</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofAddress3') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des">
|
|
|
|
|
+ <span class="dian" v-if="['cn', 'zhHant'].indexOf(lang) != -1">·</span>
|
|
|
|
|
+ <span class="dian" v-if="lang == 'en'">-</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofAddress4') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des">
|
|
|
|
|
+ <span class="dian">·</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofAddress6') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des" v-if="lang == 'en'">
|
|
|
|
|
+ <span class="dian">·</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofAddress7') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="des" v-if="lang == 'en'">
|
|
|
|
|
+ <span class="dian">·</span>
|
|
|
|
|
+ <span>{{ t('ImproveImmediately.Content.ProofAddress8') }}</span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- 步骤控制按钮 -->
|
|
|
|
|
+ <view>
|
|
|
|
|
+ <template v-if="currentStep === 4">
|
|
|
|
|
+ <view class="btns">
|
|
|
|
|
+ <view class="cwg-button two-btn">
|
|
|
|
|
+ <u-button plain block class="prev-btn btn-primary" @click="goStep(3)">
|
|
|
|
|
+ {{ t('Btn.Last') }}
|
|
|
|
|
+ </u-button>
|
|
|
|
|
+ <u-button type="primary" class="btn-primary" block :loading="loadingStates.submit" @click="Submit">
|
|
|
|
|
+ {{ t('Btn.Submit') }}
|
|
|
|
|
+ </u-button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else-if="currentStep === 3">
|
|
|
|
|
+ <view class="btns">
|
|
|
|
|
+ <view class="cwg-button two-btn">
|
|
|
|
|
+ <u-button plain block class="prev-btn btn-primary" @click="goStep(2)">
|
|
|
|
|
+ {{ t('Btn.Last') }}
|
|
|
|
|
+ </u-button>
|
|
|
|
|
+ <u-button class="btn-primary" type="primary" block :loading="loadingStates.next" @click="goStep(4)">
|
|
|
|
|
+ {{ t('Btn.Next') }}
|
|
|
|
|
+ </u-button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else-if="currentStep === 2">
|
|
|
|
|
+ <view class="btns">
|
|
|
|
|
+ <view class="cwg-button two-btn">
|
|
|
|
|
+ <u-button plain block class="prev-btn btn-primary" @click="goStep(1)">
|
|
|
|
|
+ {{ t('Btn.Last') }}
|
|
|
|
|
+ </u-button>
|
|
|
|
|
+ <u-button class="btn-primary" type="primary" block :loading="loadingStates.next" @click="goStep(3)">
|
|
|
|
|
+ {{ t('Btn.Next') }}
|
|
|
|
|
+ </u-button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else-if="currentStep === 1">
|
|
|
|
|
+ <view class="btns">
|
|
|
|
|
+ <view class="cwg-button">
|
|
|
|
|
+ <u-button class="btn-primary" type="primary" block :loading="loadingStates.next" @click="goStep(2)">
|
|
|
|
|
+ {{ t('Btn.Next') }}
|
|
|
|
|
+ </u-button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </uni-forms>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="form-tab"></view>
|
|
|
|
|
+ </cwg-page-wrapper>
|
|
|
|
|
+ <!--离开弹出框-->
|
|
|
|
|
+ <uni-popup ref="dialogCheck" type="center" :show="dialogCheck">
|
|
|
|
|
+ <view class="dia-content" v-if="dialogCheck1">
|
|
|
|
|
+ <view class="icon">
|
|
|
|
|
+ <i class="iconfont iconjingshi"></i>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="des1">{{ t('ImproveImmediately.Content.Leave1') }}</view>
|
|
|
|
|
+ <view class="des2">{{ t('ImproveImmediately.Content.Leave2') }}</view>
|
|
|
|
|
+ <view class="dialog-footer">
|
|
|
|
|
+ <u-button @click="closeDia">{{ t('Btn.TemporarilyNot') }}</u-button>
|
|
|
|
|
+ <u-button type="primary" @click="save">{{ t('Btn.Save') }}</u-button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="dia-content" v-if="!dialogCheck1">
|
|
|
|
|
+ <view class="icon">
|
|
|
|
|
+ <i class="iconfont iconchenggong"></i>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="des1">{{ t('ApplicationDialog.Des1') }}</view>
|
|
|
|
|
+ <QrCode :text="text1"></QrCode>
|
|
|
|
|
+ <view class="dialog-footer">
|
|
|
|
|
+ <u-button @click="closeDia">{{ t('Btn.Cancel') }}</u-button>
|
|
|
|
|
+ <u-button type="primary" @click="toHome">{{ t('Btn.Home') }}</u-button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </uni-popup>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+ import { ref, onMounted, onUnmounted, watch, computed } from 'vue'
|
|
|
|
|
+ import { useI18n } from 'vue-i18n'
|
|
|
|
|
+ import { onLoad } from '@dcloudio/uni-app'
|
|
|
|
|
+ import { personalApi } from '@/service/personal'
|
|
|
|
|
+ import Config from '@/config/index'
|
|
|
|
|
+ import QrCode from '@/components/QRCode.vue'
|
|
|
|
|
+ import { userToken } from '@/composables/config'
|
|
|
|
|
+ import useRouter from '@/hooks/useRouter'
|
|
|
|
|
+ import { Patterns, Validators } from '@/utils/validators'
|
|
|
|
|
+ import { pinyin } from 'pinyin-pro'
|
|
|
|
|
+ import config from '@/config/index'
|
|
|
|
|
+ import icon_doc from '@/static/icons/crm-document.svg'
|
|
|
|
|
+ import icon_refresh from '@/static/icons/crm-refresh.svg'
|
|
|
|
|
+
|
|
|
|
|
+ const router = useRouter()
|
|
|
|
|
+ const { t } = useI18n()
|
|
|
|
|
+ const currentStep = ref<number>(3)
|
|
|
|
|
+ const formRef = ref()
|
|
|
|
|
+ const lang = ref('cn')
|
|
|
|
|
+ const dialogCheck = ref(false)
|
|
|
|
|
+ const dialogCheck1 = ref(false)
|
|
|
|
|
+ const text1 = ref('')
|
|
|
|
|
+ const qrCodeStatus = ref(false)
|
|
|
|
|
+ const addressTipPopup = ref()
|
|
|
|
|
+
|
|
|
|
|
+ // 新增的响应式数据
|
|
|
|
|
+ const divActiveHelf = ref(false)
|
|
|
|
|
+ const divActiveAll = ref(false)
|
|
|
|
|
+ const websock = ref(null)
|
|
|
|
|
+ const isPC = ref(true)
|
|
|
|
|
+ const fileListID1 = ref({ againPath: '', id: null, path: '', status: null, type: null })
|
|
|
|
|
+ const fileListID2 = ref({ againPath: '', id: null, path: '', status: null, type: null })
|
|
|
|
|
+ const fileListAdd1 = ref({ againPath: '', id: null, path: '', status: null, type: null })
|
|
|
|
|
+ const fileListAdd2 = ref({ againPath: '', id: null, path: '', status: null, type: null })
|
|
|
|
|
+ const fileListOthers = ref([])
|
|
|
|
|
+ const actionID1 = ref('')
|
|
|
|
|
+ const actionID2 = ref('')
|
|
|
|
|
+ const actionAdd1 = ref('')
|
|
|
|
|
+ const actionAdd2 = ref('')
|
|
|
|
|
+ const actionOtherAdd = ref('')
|
|
|
|
|
+ const flag = ref(false)
|
|
|
|
|
+ const pictLoading = ref(false)
|
|
|
|
|
+ const pictLoadingImg = ref(false)
|
|
|
|
|
+ const isApprove = ref(false)
|
|
|
|
|
+ const metaInfo = ref({})
|
|
|
|
|
+ const HostWs = ref(Config.HostWs)
|
|
|
|
|
+ const cities = ref([])
|
|
|
|
|
+ const states = ref([])
|
|
|
|
|
+ const countries = ref([])
|
|
|
|
|
+ const uploadImage = ref(0)
|
|
|
|
|
+ const updateUrl = config.Host80
|
|
|
|
|
+
|
|
|
|
|
+ const imageStyle = ref({
|
|
|
|
|
+ width: 200,
|
|
|
|
|
+ height: 150,
|
|
|
|
|
+ border: {
|
|
|
|
|
+ radius: '5px',
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 验证函数
|
|
|
|
|
+ function validateName(a: any, b?: any, c?: any) {
|
|
|
|
|
+ const reg = /^[A-Z\s]+$/i
|
|
|
|
|
+ if (typeof c === 'function') {
|
|
|
|
|
+ const value = b
|
|
|
|
|
+ const callback = c
|
|
|
|
|
+ const val = String(value ?? '').trim()
|
|
|
|
|
+ if (!val) return callback(new Error(t('card.vaildate.v4')))
|
|
|
|
|
+ if (!reg.test(val)) return callback(new Error(t('card.vaildate.v38')))
|
|
|
|
|
+ if (val.length < 2 || val.length > 23) return callback(new Error(t('card.vaildate.v39')))
|
|
|
|
|
+ const firstName = String(formData.value?.firstName ?? '').trim()
|
|
|
|
|
+ const lastName = String(formData.value?.lastName ?? '').trim()
|
|
|
|
|
+ if (`${firstName} ${lastName}`.length > 23) return callback(new Error(t('card.vaildate.v40')))
|
|
|
|
|
+ return callback()
|
|
|
|
|
+ }
|
|
|
|
|
+ const val = String(a ?? '').trim()
|
|
|
|
|
+ if (!val) return t('card.vaildate.v4')
|
|
|
|
|
+ if (!reg.test(val)) return t('card.vaildate.v38')
|
|
|
|
|
+ if (val.length < 2 || val.length > 23) return t('card.vaildate.v39')
|
|
|
|
|
+ const firstName = String(formData.value?.firstName ?? '').trim()
|
|
|
|
|
+ const lastName = String(formData.value?.lastName ?? '').trim()
|
|
|
|
|
+ if (`${firstName} ${lastName}`.length > 23) return t('card.vaildate.v40')
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function validateBirthday(a: any, b?: any, c?: any) {
|
|
|
|
|
+ if (typeof c === 'function') {
|
|
|
|
|
+ const value = b
|
|
|
|
|
+ const callback = c
|
|
|
|
|
+ const val = value
|
|
|
|
|
+ if (!val) return callback(new Error(t('card.vaildate.v5')))
|
|
|
|
|
+ const today = new Date()
|
|
|
|
|
+ const birthDate = new Date(val)
|
|
|
|
|
+ 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) return callback(new Error(t('card.New.n3')))
|
|
|
|
|
+ return callback()
|
|
|
|
|
+ }
|
|
|
|
|
+ const val = a
|
|
|
|
|
+ if (!val) return t('card.vaildate.v5')
|
|
|
|
|
+ const today = new Date()
|
|
|
|
|
+ const birthDate = new Date(val)
|
|
|
|
|
+ let age = today.getFullYear() - birthDate.getFullYear()
|
|
|
|
|
+ const month = today.getMonth() - birthDate.getMonth()
|
|
|
|
|
+ if (month < 0 || (month === 0 && today.getDate() < birthDate.getDate())) age--
|
|
|
|
|
+ return age < 18 ? t('card.New.n3') : true
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function validateAddress(a: any, b?: any, c?: any) {
|
|
|
|
|
+ if (typeof c === 'function') {
|
|
|
|
|
+ const value = b
|
|
|
|
|
+ const callback = c
|
|
|
|
|
+ const val = String(value ?? '').trim()
|
|
|
|
|
+ if (!val) return callback(new Error(t('card.vaildate.v27')))
|
|
|
|
|
+ if (val.length < 2 || val.length > 40) return callback(new Error(t('card.New.n1')))
|
|
|
|
|
+ if (!Patterns.address.test(val)) return callback(new Error(t('card.New.n1')))
|
|
|
|
|
+ return callback()
|
|
|
|
|
+ }
|
|
|
|
|
+ const val = String(a ?? '').trim()
|
|
|
|
|
+ if (!val) return t('card.vaildate.v27')
|
|
|
|
|
+ if (val.length < 2 || val.length > 40) return t('card.New.n1')
|
|
|
|
|
+ return Patterns.address.test(val) ? true : t('card.New.n1')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const rules = {
|
|
|
|
|
+ customType: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ firstName: [Validators.required(t('card.vaildate.v3')), Validators.custom(validateName)],
|
|
|
|
|
+ lastName: [Validators.required(t('card.vaildate.v4')), Validators.custom(validateName)],
|
|
|
|
|
+ nationality: [Validators.required(t('card.vaildate.v6'), 'change')],
|
|
|
|
|
+ IdentityType: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ identity: [Validators.required(t('card.vaildate.v4'))],
|
|
|
|
|
+ gender: [Validators.required(t('card.vaildate.v9'), 'change')],
|
|
|
|
|
+ birth: [
|
|
|
|
|
+ Validators.required(t('card.vaildate.v5'), 'change'),
|
|
|
|
|
+ Validators.custom(validateBirthday, 'change'),
|
|
|
|
|
+ ],
|
|
|
|
|
+ country: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ state: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ city: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ addressLines1: [Validators.required(t('card.vaildate.v27')), Validators.custom(validateAddress)],
|
|
|
|
|
+ zipCode: [
|
|
|
|
|
+ Validators.required(t('card.vaildate.v8')),
|
|
|
|
|
+ Validators.pattern(Patterns.postcode, t('card.New.n2')),
|
|
|
|
|
+ ],
|
|
|
|
|
+ level: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ employmentStatus: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ tradingObjectives: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ sourceFunding: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ grossAnnualIncome: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ totalNewWorth: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ cardType: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ idFrontUrl: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ idBackUrl: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ addressProofUrl: [Validators.required(t('card.vaildate.v1'))],
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ onLoad((options) => {
|
|
|
|
|
+ currentStep.value = parseInt(options?.currentStep || '3', 10)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ function goStep(step: number) {
|
|
|
|
|
+ currentStep.value = step
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 选项数据
|
|
|
|
|
+ const customerTypeOptions = [
|
|
|
|
|
+ { value: 1, text: t('ImproveImmediately.Label.CustomerType1') },
|
|
|
|
|
+ { value: 2, text: t('ImproveImmediately.Label.CustomerType2') },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ const identityTypes = ref([
|
|
|
|
|
+ { text: t('ImproveImmediately.Label.IDCard'), value: 2 },
|
|
|
|
|
+ { text: t('ImproveImmediately.Label.Passport'), value: 3 },
|
|
|
|
|
+ ])
|
|
|
|
|
+
|
|
|
|
|
+ const genderOptions = [
|
|
|
|
|
+ { value: 1, text: t('PersonalManagement.Label.Men') },
|
|
|
|
|
+ { value: 2, text: t('PersonalManagement.Label.Women') },
|
|
|
|
|
+ ]
|
|
|
|
|
+ const radioList = [
|
|
|
|
|
+ { value: 1, text: t('ImproveImmediately.Label.Yes') },
|
|
|
|
|
+ { value: 0, text: t('ImproveImmediately.Label.No') },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ const educationOptions = [
|
|
|
|
|
+ { value: 1, text: t('ImproveImmediately.Label.Education1') },
|
|
|
|
|
+ { value: 2, text: t('ImproveImmediately.Label.Education2') },
|
|
|
|
|
+ { value: 3, text: t('ImproveImmediately.Label.Education3') },
|
|
|
|
|
+ { value: 4, text: t('ImproveImmediately.Label.Education4') },
|
|
|
|
|
+ { value: 5, text: t('ImproveImmediately.Label.Education5') },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ const employmentOptions = [
|
|
|
|
|
+ { value: 1, text: t('ImproveImmediately.Label.OnJob1') },
|
|
|
|
|
+ { value: 2, text: t('ImproveImmediately.Label.OnJob2') },
|
|
|
|
|
+ { value: 3, text: t('ImproveImmediately.Label.OnJob3') },
|
|
|
|
|
+ { value: 4, text: t('ImproveImmediately.Label.OnJob4') },
|
|
|
|
|
+ { value: 5, text: t('ImproveImmediately.Label.OnJob5') },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ const transactionPurposeOptions = [
|
|
|
|
|
+ { value: 1, text: t('ImproveImmediately.Label.purposeTransaction1') },
|
|
|
|
|
+ { value: 2, text: t('ImproveImmediately.Label.purposeTransaction2') },
|
|
|
|
|
+ { value: 3, text: t('ImproveImmediately.Label.purposeTransaction3') },
|
|
|
|
|
+ { value: 4, text: t('ImproveImmediately.Label.purposeTransaction4') },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ const fundSourceOptions = [
|
|
|
|
|
+ { value: 1, text: t('ImproveImmediately.Label.SourceFunds1') },
|
|
|
|
|
+ { value: 2, text: t('ImproveImmediately.Label.SourceFunds2') },
|
|
|
|
|
+ { value: 3, text: t('ImproveImmediately.Label.SourceFunds3') },
|
|
|
|
|
+ { value: 4, text: t('ImproveImmediately.Label.SourceFunds4') },
|
|
|
|
|
+ { value: 5, text: t('ImproveImmediately.Label.SourceFunds5') },
|
|
|
|
|
+ { value: 6, text: t('ImproveImmediately.Label.SourceFunds6') },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ const annualIncomeOptions = [
|
|
|
|
|
+ { value: 1, text: t('ImproveImmediately.Label.TotalAnnualRevenue1') },
|
|
|
|
|
+ { value: 2, text: t('ImproveImmediately.Label.TotalAnnualRevenue2') },
|
|
|
|
|
+ { value: 3, text: t('ImproveImmediately.Label.TotalAnnualRevenue3') },
|
|
|
|
|
+ { value: 4, text: t('ImproveImmediately.Label.TotalAnnualRevenue4') },
|
|
|
|
|
+ { value: 5, text: t('ImproveImmediately.Label.TotalAnnualRevenue5') },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ const netWorthOptions = [
|
|
|
|
|
+ { value: 1, text: t('ImproveImmediately.Label.TotalNetAssets1') },
|
|
|
|
|
+ { value: 2, text: t('ImproveImmediately.Label.TotalNetAssets2') },
|
|
|
|
|
+ { value: 3, text: t('ImproveImmediately.Label.TotalNetAssets3') },
|
|
|
|
|
+ { value: 4, text: t('ImproveImmediately.Label.TotalNetAssets4') },
|
|
|
|
|
+ { value: 5, text: t('ImproveImmediately.Label.TotalNetAssets5') },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ const cardTypeOptions = [
|
|
|
|
|
+ { value: 'ID_CARD', text: 'ID Card' },
|
|
|
|
|
+ { value: 'PASSPORT', text: 'Passport' },
|
|
|
|
|
+ { value: 'DRIVERS', text: 'Driver\'s License' },
|
|
|
|
|
+ { value: 'RESIDENCE_PERMIT', text: 'Residence Permit' },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ // 表单数据
|
|
|
|
|
+ const formData = ref({
|
|
|
|
|
+ customType: 1,
|
|
|
|
|
+ companyName: undefined,
|
|
|
|
|
+ lastName: undefined,
|
|
|
|
|
+ firstName: undefined,
|
|
|
|
|
+ middle: undefined,
|
|
|
|
|
+ nationality: undefined,
|
|
|
|
|
+ IdentityType: 1,
|
|
|
|
|
+ identity: undefined,
|
|
|
|
|
+ nameEn: undefined,
|
|
|
|
|
+ gender: undefined,
|
|
|
|
|
+ birth: undefined,
|
|
|
|
|
+ country: undefined,
|
|
|
|
|
+ state: undefined,
|
|
|
|
|
+ city: undefined,
|
|
|
|
|
+ addressLines1: undefined,
|
|
|
|
|
+ addressLines2: undefined,
|
|
|
|
|
+ zipCode: undefined,
|
|
|
|
|
+ level: undefined,
|
|
|
|
|
+ employmentStatus: undefined,
|
|
|
|
|
+ tradingObjectives: undefined,
|
|
|
|
|
+ sourceFunding: undefined,
|
|
|
|
|
+ grossAnnualIncome: undefined,
|
|
|
|
|
+ totalNewWorth: undefined,
|
|
|
|
|
+ experienceTradingDerivative: 0,
|
|
|
|
|
+ experienceTradingForex: 0,
|
|
|
|
|
+ derivativeProducts: 0,
|
|
|
|
|
+ experienceQualification: 0,
|
|
|
|
|
+ cardType: undefined,
|
|
|
|
|
+ idFrontUrl: undefined,
|
|
|
|
|
+ idBackUrl: undefined,
|
|
|
|
|
+ addressProofUrl: undefined,
|
|
|
|
|
+ otherFiles: undefined,
|
|
|
|
|
+ addressLines: [],
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 选项数据
|
|
|
|
|
+ const countryOptions = ref<Array<{ text: string; value: string }>>([])
|
|
|
|
|
+ const stateOptions = ref<Array<{ text: string; value: string }>>([])
|
|
|
|
|
+ const cityOptions = ref<Array<{ text: string; value: string }>>([])
|
|
|
|
|
+
|
|
|
|
|
+ // 加载状态
|
|
|
|
|
+ const loadingStates = ref({
|
|
|
|
|
+ next: false,
|
|
|
|
|
+ submit: false,
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 计算属性
|
|
|
|
|
+ const identityLabel = computed(() => {
|
|
|
|
|
+ if (formData.value.IdentityType === 2) return t('ImproveImmediately.Label.IDCard')
|
|
|
|
|
+ if (formData.value.IdentityType === 3) return t('ImproveImmediately.Label.Passport')
|
|
|
|
|
+ return t('ImproveImmediately.Label.IdentityID')
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 计算属性:当前选中国籍的 uploadCard 值
|
|
|
|
|
+ const currentUploadCard = computed(() => {
|
|
|
|
|
+ if (!formData.value.nationality || !countries.value.length) {
|
|
|
|
|
+ return 0
|
|
|
|
|
+ }
|
|
|
|
|
+ const selectedCountry = countries.value.find(
|
|
|
|
|
+ (item: any) => item.code === formData.value.nationality,
|
|
|
|
|
+ )
|
|
|
|
|
+ return selectedCountry ? (selectedCountry.uploadCard || 0) : 0
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 计算属性:当前选中国籍的 uploadAddress 值
|
|
|
|
|
+ const currentUploadAddress = computed(() => {
|
|
|
|
|
+ if (!formData.value.nationality || !countries.value.length) {
|
|
|
|
|
+ return 0
|
|
|
|
|
+ }
|
|
|
|
|
+ const selectedCountry = countries.value.find(
|
|
|
|
|
+ (item: any) => item.code === formData.value.nationality,
|
|
|
|
|
+ )
|
|
|
|
|
+ return selectedCountry ? (selectedCountry.uploadAddress || 0) : 0
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 方法
|
|
|
|
|
+ function changeCountry(value: any) {
|
|
|
|
|
+ // 处理国家选择变化
|
|
|
|
|
+ // 清空省份/城市选择//
|
|
|
|
|
+ formData.value.state = ''
|
|
|
|
|
+ formData.value.city = ''
|
|
|
|
|
+ stateOptions.value = []
|
|
|
|
|
+ cityOptions.value = []
|
|
|
|
|
+ states.value = []
|
|
|
|
|
+ cities.value = []
|
|
|
|
|
+ let item = {}
|
|
|
|
|
+ countries.value.forEach(element => {
|
|
|
|
|
+ if (element.code == value) {
|
|
|
|
|
+ item = element
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ getStateList(item.id)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function handleFileUpdate(value, type) {
|
|
|
|
|
+ console.log(value, type, 'uplaod')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function changeState(val) {
|
|
|
|
|
+ formData.value.city = ''
|
|
|
|
|
+ cityOptions.value = []
|
|
|
|
|
+ let item = {}
|
|
|
|
|
+ states.value.forEach((element) => {
|
|
|
|
|
+ if (element.name == val || element.enName == val) {
|
|
|
|
|
+ item = element
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ getCityList(item.id)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function handleChange(value: any) {
|
|
|
|
|
+ formData.value = { ...formData.value, [value.key]: value.value }
|
|
|
|
|
+ console.log(value)
|
|
|
|
|
+ if (value.key === 'country') {
|
|
|
|
|
+ formData.value.state = ''
|
|
|
|
|
+ formData.value.city = ''
|
|
|
|
|
+ stateOptions.value = []
|
|
|
|
|
+ cityOptions.value = []
|
|
|
|
|
+ if (value.value) {
|
|
|
|
|
+ getStateList(value.value)
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (value.key === 'state') {
|
|
|
|
|
+ formData.value.city = ''
|
|
|
|
|
+ cityOptions.value = []
|
|
|
|
|
+ if (value.value) {
|
|
|
|
|
+ getCityList(value.value)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function openAddressTip() {
|
|
|
|
|
+ // 打开地址提示弹窗
|
|
|
|
|
+ addressTipPopup.value.open()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function isPdf(url, image) {
|
|
|
|
|
+ let res = !!url
|
|
|
|
|
+ if (image) {
|
|
|
|
|
+ return res && url.substr(-3, 3) == 'pdf' &&
|
|
|
|
|
+ url.substr(-3, 3) == 'PDF'
|
|
|
|
|
+ }
|
|
|
|
|
+ return res && (url.substr(-3, 3) == 'pdf' ||
|
|
|
|
|
+ url.substr(-3, 3) == 'PDF')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function cancle() {
|
|
|
|
|
+ if (!isApprove.value) {
|
|
|
|
|
+ dialogCheck.value = true
|
|
|
|
|
+ dialogCheck1.value = true
|
|
|
|
|
+ } else {
|
|
|
|
|
+ router.push({ path: '/customer/index' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function closeDia() {
|
|
|
|
|
+ dialogCheck.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function toHome() {
|
|
|
|
|
+ dialogCheck.value = false
|
|
|
|
|
+ router.push({ path: '/customer/index' })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function save() {
|
|
|
|
|
+ await updateInfo(1)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function Submit() {
|
|
|
|
|
+ loadingStates.value.submit = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ formData.value.addressLines = []
|
|
|
|
|
+ if (formData.value.addressLines1) {
|
|
|
|
|
+ formData.value.addressLines.push(formData.value.addressLines1)
|
|
|
|
|
+ }
|
|
|
|
|
+ if (formData.value.addressLines2) {
|
|
|
|
|
+ formData.value.addressLines.push(formData.value.addressLines2)
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!formData.value.addressLines1 && !formData.value.addressLines2) {
|
|
|
|
|
+ formData.value.addressLines = []
|
|
|
|
|
+ }
|
|
|
|
|
+ if (formData.value.customType != 2) {
|
|
|
|
|
+ formData.value.companyName = ''
|
|
|
|
|
+ }
|
|
|
|
|
+ let res = await personalApi.CustomUpdateInfo({
|
|
|
|
|
+ ...formData.value,
|
|
|
|
|
+ })
|
|
|
|
|
+ if (res.code == Config.Code.StatusOK) {
|
|
|
|
|
+ await getCustomFileList()
|
|
|
|
|
+ await customApply()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.showToast({ title: res.msg, icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loadingStates.value.submit = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function updateInfo(save: number) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ formData.value.addressLines = []
|
|
|
|
|
+ if (formData.value.addressLines1) {
|
|
|
|
|
+ formData.value.addressLines.push(formData.value.addressLines1)
|
|
|
|
|
+ }
|
|
|
|
|
+ if (formData.value.addressLines2) {
|
|
|
|
|
+ formData.value.addressLines.push(formData.value.addressLines2)
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!formData.value.addressLines1 && !formData.value.addressLines2) {
|
|
|
|
|
+ formData.value.addressLines = []
|
|
|
|
|
+ }
|
|
|
|
|
+ let res = await personalApi.CustomUpdateInfo({
|
|
|
|
|
+ ...formData.value,
|
|
|
|
|
+ })
|
|
|
|
|
+ if (res.code == Config.Code.StatusOK) {
|
|
|
|
|
+ if (save) {
|
|
|
|
|
+ dialogCheck.value = false
|
|
|
|
|
+ router.push({ path: '/customer/index' })
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.showToast({ title: res.msg, icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function customApply() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let res = await personalApi.customApplyReal({})
|
|
|
|
|
+ if (res.code == Config.Code.StatusOK) {
|
|
|
|
|
+ isApprove.value = true
|
|
|
|
|
+ await getLoginInfo()
|
|
|
|
|
+ dialogCheck.value = true
|
|
|
|
|
+ dialogCheck1.value = false
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.showToast({ title: res.msg, icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function getCountryList() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let res = await personalApi.Country({})
|
|
|
|
|
+ if (res.code == Config.Code.StatusOK) {
|
|
|
|
|
+ countryOptions.value = res.data.map((item: any) => ({
|
|
|
|
|
+ text: item.enName,
|
|
|
|
|
+ value: item.code,
|
|
|
|
|
+ }))
|
|
|
|
|
+ countries.value = res.data
|
|
|
|
|
+ const country = formData.value.country
|
|
|
|
|
+ if (country) {
|
|
|
|
|
+ countries.value.forEach((item) => {
|
|
|
|
|
+ if (item.code == country) {
|
|
|
|
|
+ getStateList(item.id)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function getStateList(pid: string) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let res = await personalApi.Country({ pid })
|
|
|
|
|
+ if (res.code == Config.Code.StatusOK) {
|
|
|
|
|
+ stateOptions.value = res.data.map((item: any) => ({
|
|
|
|
|
+ text: lang.value === 'en' ? item.enName : item.name,
|
|
|
|
|
+ value: lang.value === 'en' ? item.enName : item.name,
|
|
|
|
|
+ }))
|
|
|
|
|
+ states.value = res.data
|
|
|
|
|
+ const state = formData.value.state
|
|
|
|
|
+ if (state) {
|
|
|
|
|
+ states.value.forEach((item) => {
|
|
|
|
|
+ if (
|
|
|
|
|
+ item.name == state ||
|
|
|
|
|
+ item.enName == state
|
|
|
|
|
+ ) {
|
|
|
|
|
+ getCityList(item.id)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function getCityList(pid: string) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let res = await personalApi.Country({ pid })
|
|
|
|
|
+ if (res.code == Config.Code.StatusOK) {
|
|
|
|
|
+ cityOptions.value = res.data.map((item: any) => ({
|
|
|
|
|
+ text: lang.value === 'en' ? item.enName : item.name,
|
|
|
|
|
+ value: lang.value === 'en' ? item.enName : item.name,
|
|
|
|
|
+ }))
|
|
|
|
|
+ cities.value = res.data
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function getLoginInfo() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let res = await personalApi.CustomLoginInfo()
|
|
|
|
|
+ if (res.code == Config.Code.StatusOK) {
|
|
|
|
|
+ formData.value = res.data.customInfo
|
|
|
|
|
+ if (formData.value.addressLines != null && formData.value.addressLines.length) {
|
|
|
|
|
+ formData.value.addressLines1 = formData.value.addressLines[0]
|
|
|
|
|
+ formData.value.addressLines2 = formData.value.addressLines[1]
|
|
|
|
|
+ }
|
|
|
|
|
+ formData.value.customType = formData.value.customType ? formData.value.customType : 1
|
|
|
|
|
+ await getCountryList()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.showToast({ title: t('Msg.SystemError'), icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取二维码
|
|
|
|
|
+ async function getMobileInfo() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let res = await personalApi.CustomFileMobileFiles({
|
|
|
|
|
+ responseType: 'arraybuffer',
|
|
|
|
|
+ })
|
|
|
|
|
+ // console.log(res);
|
|
|
|
|
+ const mobile = 'data:image/png;base64,' + Buffer.from(res).toString('base64')
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取上传文件信息
|
|
|
|
|
+ async function getCustomFileList() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let res = await personalApi.CustomFileList()
|
|
|
|
|
+ if (res.code == Config.Code.StatusOK) {
|
|
|
|
|
+ let myData = res.data
|
|
|
|
|
+ fileListOthers.value = []
|
|
|
|
|
+ myData.forEach((item: any) => {
|
|
|
|
|
+ if (item.type == 1) {
|
|
|
|
|
+ fileListID1.value = item
|
|
|
|
|
+ } else if (item.type == 2) {
|
|
|
|
|
+ fileListID2.value = item
|
|
|
|
|
+ } else if (item.type == 3) {
|
|
|
|
|
+ fileListAdd1.value = item
|
|
|
|
|
+ } else if (item.type == 4) {
|
|
|
|
|
+ fileListAdd2.value = item
|
|
|
|
|
+ } else if (item.type == 10) {
|
|
|
|
|
+ fileListOthers.value.push(item)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ actionType()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.showToast({ title: res.msg, icon: 'none' })
|
|
|
|
|
+ flag.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 请求头
|
|
|
|
|
+ function actionType() {
|
|
|
|
|
+ if (fileListID1.value.id) {
|
|
|
|
|
+ actionID1.value = Config.Host80 + '/custom/file/upload/1/' + fileListID1.value.id
|
|
|
|
|
+ } else {
|
|
|
|
|
+ actionID1.value = Config.Host80 + '/custom/file/upload/1'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (fileListID2.value.id) {
|
|
|
|
|
+ actionID2.value = Config.Host80 + '/custom/file/upload/2/' + fileListID2.value.id
|
|
|
|
|
+ } else {
|
|
|
|
|
+ actionID2.value = Config.Host80 + '/custom/file/upload/2'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (fileListAdd1.value.id) {
|
|
|
|
|
+ actionAdd1.value = Config.Host80 + '/custom/file/upload/3/' + fileListAdd1.value.id
|
|
|
|
|
+ } else {
|
|
|
|
|
+ actionAdd1.value = Config.Host80 + '/custom/file/upload/3'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (fileListAdd2.value.id) {
|
|
|
|
|
+ actionAdd2.value = Config.Host80 + '/custom/file/upload/4/' + fileListAdd2.value.id
|
|
|
|
|
+ } else {
|
|
|
|
|
+ actionAdd2.value = Config.Host80 + '/custom/file/upload/4'
|
|
|
|
|
+ }
|
|
|
|
|
+ actionOtherAdd.value = Config.Host80 + '/custom/file/upload/10'
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // WebSocket
|
|
|
|
|
+ function initWebSocket() {
|
|
|
|
|
+ // 初始化WebSocket
|
|
|
|
|
+ let token = localStorage.getItem('access_token')
|
|
|
|
|
+ if (typeof WebSocket == 'undefined') {
|
|
|
|
|
+ uni.showToast({ title: t('Msg.socket'), icon: 'none' })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const wsUrl = HostWs.value + '/webSocket?Access-Token=' + token
|
|
|
|
|
+ websock.value = new WebSocket(wsUrl)
|
|
|
|
|
+ websock.value.onmessage = websocketonmessage
|
|
|
|
|
+ websock.value.onopen = websocketonopen
|
|
|
|
|
+ websock.value.onerror = websocketonerror
|
|
|
|
|
+ websock.value.onclose = websocketclose
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function websocketonopen() {
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function websocketonerror() {
|
|
|
|
|
+ initWebSocket()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function websocketonmessage(e: any) {
|
|
|
|
|
+ let data = JSON.parse(e.data)
|
|
|
|
|
+ if (data.newsType == 1) {
|
|
|
|
|
+ let myData = JSON.parse(e.data)
|
|
|
|
|
+ if (myData.type == 1) {
|
|
|
|
|
+ fileListID1.value = myData
|
|
|
|
|
+ } else if (myData.type == 2) {
|
|
|
|
|
+ fileListID2.value = myData
|
|
|
|
|
+ } else if (myData.type == 3) {
|
|
|
|
|
+ fileListAdd1.value = myData
|
|
|
|
|
+ } else if (myData.type == 4) {
|
|
|
|
|
+ fileListAdd2.value = myData
|
|
|
|
|
+ } else if (myData.type == 10) {
|
|
|
|
|
+ if (!fileListOthers.value.length) {
|
|
|
|
|
+ fileListOthers.value.push(myData)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ let flag = true
|
|
|
|
|
+ fileListOthers.value.forEach((item: any) => {
|
|
|
|
|
+ if (item.id == myData.id) {
|
|
|
|
|
+ item = myData
|
|
|
|
|
+ flag = false
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ if (flag) {
|
|
|
|
|
+ fileListOthers.value.push(myData)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ actionType()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function websocketclose() {
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 判断是否为PC端
|
|
|
|
|
+ function IsPC() {
|
|
|
|
|
+ let userAgentInfo = navigator.userAgent
|
|
|
|
|
+ let Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
|
|
|
|
|
+ let flag = true
|
|
|
|
|
+ for (let v = 0; v < Agents.length; v++) {
|
|
|
|
|
+ if (userAgentInfo.indexOf(Agents[v]) > 0) {
|
|
|
|
|
+ flag = false
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return flag
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // div大小改变重载
|
|
|
|
|
+ function divInit() {
|
|
|
|
|
+ // 由于elementResizeDetectorMaker在UniApp中可能不可用,这里简化处理
|
|
|
|
|
+ const width = window.innerWidth
|
|
|
|
|
+ if (width <= 1100 && width > 800) {
|
|
|
|
|
+ divActiveHelf.value = true
|
|
|
|
|
+ divActiveAll.value = false
|
|
|
|
|
+ } else if (width <= 800) {
|
|
|
|
|
+ divActiveAll.value = true
|
|
|
|
|
+ divActiveHelf.value = false
|
|
|
|
|
+ } else if (1100 < width) {
|
|
|
|
|
+ divActiveAll.value = false
|
|
|
|
|
+ divActiveHelf.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 监听表单字段变化
|
|
|
|
|
+ watch(
|
|
|
|
|
+ () => formData.value.firstName,
|
|
|
|
|
+ () => {
|
|
|
|
|
+ if (localStorage.getItem('lang') == 'cn' && formData.value.firstName && formData.value.lastName) {
|
|
|
|
|
+ formData.value.nameEn = pinyin(`${formData.value.firstName} ${formData.value.lastName}`)
|
|
|
|
|
+ pinyin
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ watch(
|
|
|
|
|
+ () => formData.value.lastName,
|
|
|
|
|
+ () => {
|
|
|
|
|
+ if (localStorage.getItem('lang') == 'cn' && formData.value.firstName && formData.value.lastName) {
|
|
|
|
|
+ formData.value.nameEn = pinyin(`${formData.value.firstName} ${formData.value.lastName}`, {
|
|
|
|
|
+ style: 'first',
|
|
|
|
|
+ separator: ' ',
|
|
|
|
|
+ }).toUpperCase()
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ // 生命周期
|
|
|
|
|
+ onMounted(async () => {
|
|
|
|
|
+ divInit()
|
|
|
|
|
+ await getLoginInfo()
|
|
|
|
|
+ await getMobileInfo()
|
|
|
|
|
+ await getCustomFileList()
|
|
|
|
|
+ // WebSocket
|
|
|
|
|
+ initWebSocket()
|
|
|
|
|
+ isPC.value = IsPC()
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 组件销毁时
|
|
|
|
|
+ onUnmounted(() => {
|
|
|
|
|
+ if (websock.value) {
|
|
|
|
|
+ websock.value.close() // 离开路由之后断开WebSocket连接
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+ @import "@/uni.scss";
|
|
|
|
|
+
|
|
|
|
|
+ .form-tab {
|
|
|
|
|
+ height: px2rpx(100);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .form-section {
|
|
|
|
|
+ margin: px2rpx(8) 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .section-title {
|
|
|
|
|
+ color: #1a1a1a;
|
|
|
|
|
+ font-family: Roboto;
|
|
|
|
|
+ font-size: px2rpx(22);
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ margin: px2rpx(10) 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.file-picker__box) {
|
|
|
|
|
+ width: px2rpx(200) !important;
|
|
|
|
|
+ height: px2rpx(150) !important;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.uni-file-picker) {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .avatar-uploader {
|
|
|
|
|
+ border: 1px dashed;
|
|
|
|
|
+ width: px2rpx(200);
|
|
|
|
|
+ height: px2rpx(150);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ /*float: left;*/
|
|
|
|
|
+ //overflow: hidden;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .file-item {
|
|
|
|
|
+ border: 1px dashed;
|
|
|
|
|
+ border-radius: px2rpx(5);
|
|
|
|
|
+ width: px2rpx(200);
|
|
|
|
|
+ height: px2rpx(150);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+
|
|
|
|
|
+ .icon {
|
|
|
|
|
+ width: px2rpx(24);
|
|
|
|
|
+ height: px2rpx(24);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .avatar {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .custom-upload-btn {
|
|
|
|
|
+ width: px2rpx(200);
|
|
|
|
|
+ height: px2rpx(150);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+
|
|
|
|
|
+ .plus {
|
|
|
|
|
+ font-size: px2rpx(24);
|
|
|
|
|
+ color: #9ca3af;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .experience {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ margin: px2rpx(10) 0;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .Trad-experience {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ color: #1a1a1a;
|
|
|
|
|
+ font-size: px2rpx(16);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .Trad-choose {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .descending {
|
|
|
|
|
+ margin: px2rpx(20) 0;
|
|
|
|
|
+ padding: px2rpx(20);
|
|
|
|
|
+ background-color: #f5f5f5;
|
|
|
|
|
+ border-radius: px2rpx(8);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .title {
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ margin-bottom: px2rpx(10);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .des {
|
|
|
|
|
+ margin: px2rpx(5) 0;
|
|
|
|
|
+ font-size: px2rpx(14);
|
|
|
|
|
+ color: #666;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .dian1 {
|
|
|
|
|
+ font-size: px2rpx(20);
|
|
|
|
|
+ margin-right: px2rpx(5);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .dian {
|
|
|
|
|
+ margin-right: px2rpx(10);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .btns {
|
|
|
|
|
+ margin-top: px2rpx(30);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .cwg-button {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: px2rpx(15);
|
|
|
|
|
+
|
|
|
|
|
+ &.two-btn {
|
|
|
|
|
+ flex-direction: row;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+
|
|
|
|
|
+ u-button {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ margin: 0 px2rpx(10);
|
|
|
|
|
+
|
|
|
|
|
+ &:first-child {
|
|
|
|
|
+ margin-left: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &:last-child {
|
|
|
|
|
+ margin-right: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .btn-primary {
|
|
|
|
|
+ height: px2rpx(80);
|
|
|
|
|
+ font-size: px2rpx(18);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .prev-btn {
|
|
|
|
|
+ border-color: #4a6cf7;
|
|
|
|
|
+ color: #4a6cf7;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .crm-title-box {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ margin: px2rpx(20) 0;
|
|
|
|
|
+
|
|
|
|
|
+ .tit {
|
|
|
|
|
+ font-size: px2rpx(18);
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ color: #1a1a1a;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .icon-tip {
|
|
|
|
|
+ margin-left: px2rpx(10);
|
|
|
|
|
+ font-size: px2rpx(16);
|
|
|
|
|
+ color: #4a6cf7;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .popup-content {
|
|
|
|
|
+ padding: px2rpx(20);
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .dia-content {
|
|
|
|
|
+ padding: px2rpx(30);
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+
|
|
|
|
|
+ .icon {
|
|
|
|
|
+ margin-bottom: px2rpx(20);
|
|
|
|
|
+
|
|
|
|
|
+ i {
|
|
|
|
|
+ font-size: px2rpx(60);
|
|
|
|
|
+ color: #4a6cf7;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .des1 {
|
|
|
|
|
+ font-size: px2rpx(18);
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ margin-bottom: px2rpx(10);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .des2 {
|
|
|
|
|
+ font-size: px2rpx(14);
|
|
|
|
|
+ color: #666;
|
|
|
|
|
+ margin-bottom: px2rpx(30);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .dialog-footer {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ margin-top: px2rpx(30);
|
|
|
|
|
+
|
|
|
|
|
+ u-button {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ margin: 0 px2rpx(10);
|
|
|
|
|
+
|
|
|
|
|
+ &:first-child {
|
|
|
|
|
+ margin-left: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &:last-child {
|
|
|
|
|
+ margin-right: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .cwg-upload {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ padding: px2rpx(40);
|
|
|
|
|
+ border: 1px dashed #ddd;
|
|
|
|
|
+ border-radius: px2rpx(8);
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+
|
|
|
|
|
+ cwg-icon {
|
|
|
|
|
+ font-size: px2rpx(40);
|
|
|
|
|
+ margin-bottom: px2rpx(10);
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .name {
|
|
|
|
|
+ font-size: px2rpx(16);
|
|
|
|
|
+ margin-bottom: px2rpx(5);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .back {
|
|
|
|
|
+ font-size: px2rpx(12);
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+</style>
|