improveImmediately.vue 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957
  1. <template>
  2. <cwg-page-wrapper>
  3. <view class="page page-shadow">
  4. <uni-forms ref="formRef" :model="formData" :rules="rules" labelWidth="200" label-position="top"
  5. class="payment-form">
  6. <!-- 第一步:个人信息 -->
  7. <view v-show="currentStep === 1" class="form-section">
  8. <h3 class="section-title">{{ t('ImproveImmediately.Title.BasicInformation') }}</h3>
  9. <uni-row class="demo-uni-row uni-row1">
  10. <!-- 客户类型 -->
  11. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  12. <uni-forms-item :label="t('ImproveImmediately.Label.CustomerType')">
  13. <cwg-combox :clearable="false" v-model:value="formData.customType"
  14. :options="customerTypeOptions" :placeholder="t('placeholder.choose')" />
  15. </uni-forms-item>
  16. </uni-col>
  17. <!-- 公司名称 -->
  18. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-if="formData.customType == 2">
  19. <uni-forms-item :label="t('ImproveImmediately.Label.CompanyName')">
  20. <uni-easyinput :clearable="false" v-model="formData.companyName"
  21. :placeholder="t('placeholder.input')" />
  22. </uni-forms-item>
  23. </uni-col>
  24. <!-- 姓 -->
  25. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  26. <uni-forms-item :label="formData.customType == 2
  27. ? t('ImproveImmediately.Label.CorporationLastName')
  28. : t('ImproveImmediately.Label.LastName')">
  29. <uni-easyinput :clearable="false" v-model="formData.lastName" :placeholder="t('placeholder.input')" />
  30. </uni-forms-item>
  31. </uni-col>
  32. <!-- 名 -->
  33. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  34. <uni-forms-item :label="formData.customType == 2
  35. ? t('ImproveImmediately.Label.CorporationName')
  36. : t('ImproveImmediately.Label.Name')">
  37. <uni-easyinput :clearable="false" v-model="formData.firstName" :placeholder="t('placeholder.input')" />
  38. </uni-forms-item>
  39. </uni-col>
  40. <!-- 法人中间名 -->
  41. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-if="local == 'en'">
  42. <uni-forms-item name="middle" :label="t('placeholder.middle')">
  43. <uni-easyinput :clearable="false" v-model="formData.middle" :placeholder="t('placeholder.input')" />
  44. </uni-forms-item>
  45. </uni-col>
  46. <!-- 国家 -->
  47. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-if="countryOptions.length > 0">
  48. <uni-forms-item name="nationality" :label="t('ImproveImmediately.Label.Nationality')">
  49. <cwg-combox :clearable="false" :filterable="true"
  50. v-model:value="formData.nationality" :options="countryOptions"
  51. :placeholder="t('placeholder.choose')" />
  52. </uni-forms-item>
  53. </uni-col>
  54. <!-- 证件类型 -->
  55. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  56. <uni-forms-item name="IdentityType" :label="identityLabel">
  57. <cwg-combox :clearable="false" v-model:value="formData.IdentityType"
  58. :options="identityTypes" :placeholder="t('placeholder.choose')" />
  59. </uni-forms-item>
  60. </uni-col>
  61. <!-- 证件号 -->
  62. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  63. <uni-forms-item name="identity" :label="t('ImproveImmediately.Label.IdentityID')">
  64. <uni-easyinput :clearable="false" v-model="formData.identity" :placeholder="t('placeholder.input')" />
  65. </uni-forms-item>
  66. </uni-col>
  67. <!-- 拼音 -->
  68. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-if="['cn', 'zhHant'].includes(local)">
  69. <uni-forms-item name="nameEn" :label="t('ImproveImmediately.Label.NamePinYin')">
  70. <uni-easyinput :clearable="false" v-model="formData.nameEn" :placeholder="t('placeholder.input')" />
  71. </uni-forms-item>
  72. </uni-col>
  73. <!-- 性别 -->
  74. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  75. <uni-forms-item name="gender" :label="t('ImproveImmediately.Label.Gender')">
  76. <cwg-combox :clearable="false" v-model:value="formData.gender" :options="genderOptions"
  77. :placeholder="t('placeholder.choose')" />
  78. </uni-forms-item>
  79. </uni-col>
  80. <!-- 生日 -->
  81. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  82. <uni-forms-item name="birth" :label="t('ImproveImmediately.Label.Birthday')">
  83. <uni-datetime-picker :clear-icon="false" type="date" return-type="timestamp"
  84. v-model="formData.birth" :placeholder="t('placeholder.choose')" />
  85. </uni-forms-item>
  86. </uni-col>
  87. <uni-col :span="24">
  88. <view class="crm-title-box">
  89. <text class="tit">{{ t('ImproveImmediately.Title.AddressInformation') }}</text>
  90. <uni-tooltip placement="top">
  91. <text class="icon-tip">ⓘ</text>
  92. <template v-slot:content>
  93. <view class="address-tip">
  94. {{ t('ImproveImmediately.Title.AddressTip') }}
  95. </view>
  96. </template>
  97. </uni-tooltip>
  98. </view>
  99. </uni-col>
  100. <!-- 国家/地区 -->
  101. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-if="countryOptions.length > 0">
  102. <uni-forms-item name="country" :label="t('ImproveImmediately.Label.CountryRegionOfResidence')">
  103. <cwg-combox :clearable="false" :filterable="true" v-model:value="formData.country"
  104. :options="countryOptions" :placeholder="t('placeholder.choose')" @change="changeCountry" />
  105. </uni-forms-item>
  106. </uni-col>
  107. <!-- 省份/州 -->
  108. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
  109. v-if="formData.country == 'CN' || formData.country == 'CNX' || formData.country == 'CNA' || formData.country == 'CNT'">
  110. <uni-forms-item name="state" :label="t('ImproveImmediately.Label.ProvinceRegion')">
  111. <cwg-combox :clearable="false" :filterable="true" v-model:value="formData.state"
  112. :options="stateOptions" :placeholder="t('placeholder.choose')" @change="changeState" />
  113. </uni-forms-item>
  114. </uni-col>
  115. <!-- 国外省份/州 -->
  116. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-else>
  117. <uni-forms-item name="state" :label="t('ImproveImmediately.Label.ProvinceRegion')">
  118. <uni-easyinput :clearable="false" v-model="formData.state" :placeholder="t('placeholder.input')" />
  119. </uni-forms-item>
  120. </uni-col>
  121. <!-- 城市 -->
  122. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
  123. v-if="formData.country == 'CN' || formData.country == 'CNX' || formData.country == 'CNA' || formData.country == 'CNT'">
  124. <uni-forms-item name="city" :label="t('ImproveImmediately.Label.City')">
  125. <cwg-combox :clearable="false" :filterable="true" v-model:value="formData.city"
  126. :options="cityOptions" :placeholder="t('placeholder.choose')" />
  127. </uni-forms-item>
  128. </uni-col>
  129. <!-- 国外城市 -->
  130. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8" v-else>
  131. <uni-forms-item name="city" :label="t('ImproveImmediately.Label.City')">
  132. <uni-easyinput :clearable="false" v-model="formData.city" :placeholder="t('placeholder.input')" />
  133. </uni-forms-item>
  134. </uni-col>
  135. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  136. <uni-forms-item name="addressLines1" :label="t('ImproveImmediately.Label.DetailedAddress')">
  137. <uni-easyinput :clearable="false" v-model="formData.addressLines1"
  138. :placeholder="t('placeholder.input')" />
  139. </uni-forms-item>
  140. </uni-col>
  141. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  142. <uni-forms-item name="zipCode" :label="t('ImproveImmediately.Label.ZipCode')">
  143. <uni-easyinput :clearable="false" v-model="formData.zipCode" :placeholder="t('placeholder.input')" />
  144. </uni-forms-item>
  145. </uni-col>
  146. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  147. <uni-forms-item name="addressLines2" :label="t('ImproveImmediately.Label.DetailedAddressStandby')">
  148. <uni-easyinput :clearable="false" v-model="formData.addressLines2"
  149. :placeholder="t('placeholder.input')" />
  150. </uni-forms-item>
  151. </uni-col>
  152. </uni-row>
  153. </view>
  154. <!-- 第二步:财务背景 -->
  155. <view v-show="currentStep === 2" class="form-section">
  156. <h3 class="section-title">{{ t('ImproveImmediately.Title.FinancialBackground') }}</h3>
  157. <uni-row class="demo-uni-row uni-row1">
  158. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  159. <uni-forms-item name="level" :label="t('ImproveImmediately.Label.Education')">
  160. <cwg-combox :clearable="false" v-model:value="formData.level"
  161. :options="educationOptions" :placeholder="t('placeholder.choose')" />
  162. </uni-forms-item>
  163. </uni-col>
  164. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  165. <uni-forms-item name="employmentStatus" :label="t('ImproveImmediately.Label.OnJob')">
  166. <cwg-combox :clearable="false" v-model:value="formData.employmentStatus"
  167. :options="employmentOptions" :placeholder="t('placeholder.choose')" />
  168. </uni-forms-item>
  169. </uni-col>
  170. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  171. <uni-forms-item name="tradingObjectives" :label="t('ImproveImmediately.Label.purposeTransaction')">
  172. <cwg-combox :clearable="false" v-model:value="formData.tradingObjectives"
  173. :options="transactionPurposeOptions" :placeholder="t('placeholder.choose')" />
  174. </uni-forms-item>
  175. </uni-col>
  176. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  177. <uni-forms-item name="sourceFunding" :label="t('ImproveImmediately.Label.SourceFunds')">
  178. <cwg-combox :clearable="false" v-model:value="formData.sourceFunding"
  179. :options="fundSourceOptions" :placeholder="t('placeholder.choose')" />
  180. </uni-forms-item>
  181. </uni-col>
  182. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  183. <uni-forms-item name="grossAnnualIncome" :label="t('ImproveImmediately.Label.TotalAnnualRevenue')">
  184. <cwg-combox :clearable="false" v-model:value="formData.grossAnnualIncome"
  185. :options="annualIncomeOptions" :placeholder="t('placeholder.choose')" />
  186. </uni-forms-item>
  187. </uni-col>
  188. <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
  189. <uni-forms-item name="totalNewWorth" :label="t('ImproveImmediately.Label.TotalNetAssets')">
  190. <cwg-combox :clearable="false" v-model:value="formData.totalNewWorth"
  191. :options="netWorthOptions" :placeholder="t('placeholder.choose')" />
  192. </uni-forms-item>
  193. </uni-col>
  194. </uni-row>
  195. <h3 class="section-title">{{ t('ImproveImmediately.Title.TradingExperience') }}</h3>
  196. <view class="experience">
  197. <text class="Trad-experience">{{ t('ImproveImmediately.Content.TradingExperience1') }}</text>
  198. <view class="Trad-choose">
  199. <uni-data-checkbox v-model="formData.experienceTradingDerivative"
  200. :localdata="radioList"></uni-data-checkbox>
  201. </view>
  202. </view>
  203. <view class="experience">
  204. <text class="Trad-experience">{{ t('ImproveImmediately.Content.TradingExperience2') }}</text>
  205. <view class="Trad-choose">
  206. <uni-data-checkbox v-model="formData.experienceTradingForex" :localdata="radioList"></uni-data-checkbox>
  207. </view>
  208. </view>
  209. <view class="experience">
  210. <text class="Trad-experience">{{ t('ImproveImmediately.Content.TradingExperience3') }}</text>
  211. <view class="Trad-choose">
  212. <uni-data-checkbox v-model="formData.derivativeProducts" :localdata="radioList"></uni-data-checkbox>
  213. </view>
  214. </view>
  215. <view class="experience">
  216. <text class="Trad-experience">{{ t('ImproveImmediately.Content.TradingExperience4') }}</text>
  217. <view class="Trad-choose">
  218. <uni-data-checkbox v-model="formData.experienceQualification" :localdata="radioList"></uni-data-checkbox>
  219. </view>
  220. </view>
  221. </view>
  222. <!-- 第三步:身份证明 -->
  223. <view v-show="currentStep === 3" class="form-section">
  224. <uni-row class="demo-uni-row uni-row1">
  225. <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  226. <view class="crm-title-box">
  227. <text class="tit">{{ t('ImproveImmediately.Title.ProofIdentityUpdate') }}</text>
  228. <uni-tooltip placement="bottom">
  229. <text class="icon-tip">ⓘ</text>
  230. <template v-slot:content>
  231. <view class="address-tip">
  232. {{ t('ImproveImmediately.Content.popover1') }}
  233. </view>
  234. </template>
  235. </uni-tooltip>
  236. </view>
  237. <uni-forms-item name="cardType" :label="t('ImproveImmediately.Label.CardType')">
  238. <cwg-combox :clearable="false" v-model:value="formData.cardType"
  239. :options="cardTypeOptions" :placeholder="t('placeholder.choose')" />
  240. </uni-forms-item>
  241. <uni-row class="demo-uni-row uni-row1">
  242. <uni-col :xs="24" :sm="24" :md="10" :lg="10" :xl="10">
  243. <cwg-file-picker-wrapper
  244. v-model="fileListID1.path"
  245. :editable="fileListID1.status != 2"
  246. :limit="1"
  247. :fileMediatype="'all'"
  248. uploadUrl="/custom/file/upload/1"
  249. :baseUrl="updateUrl"
  250. :imageWidth="150"
  251. :imageHeight="150"
  252. :showPreviewDelete="false"
  253. :canDelete="false"
  254. :uploadError="false"
  255. :showProgress="false"
  256. :canChoose="true"
  257. :showError="false"
  258. :show-progress="false"
  259. disablePreview
  260. :image-styles="imageStyle"
  261. @update:modelValue="(val) => handleFileUpdate(val, '1')"
  262. customClass="avatar-uploader"
  263. >
  264. <view class="file-item">
  265. <image
  266. v-if="!isPdf(fileListID1.path)"
  267. class="avatar"
  268. :src="updateUrl + (fileListID1.path)"
  269. ></image>
  270. <view v-else>
  271. <image class="icon" :src="icon_doc" />
  272. </view>
  273. </view>
  274. </cwg-file-picker-wrapper>
  275. <!-- <view v-else>-->
  276. <!-- <view class="file-item">-->
  277. <!-- <image-->
  278. <!-- v-if="!isPdf(fileListID1.path)"-->
  279. <!-- class="avatar"-->
  280. <!-- :src="updateUrl + fileListID1.path"-->
  281. <!-- ></image>-->
  282. <!-- <view v-else>-->
  283. <!-- <image class="icon" :src="icon_doc" />-->
  284. <!-- </view>-->
  285. <!-- </view>-->
  286. <!-- </view>-->
  287. </uni-col>
  288. <uni-col :xs="24" :sm="24" :md="10" :lg="10" :xl="10">
  289. <cwg-file-picker-wrapper
  290. v-model="fileListID2.path"
  291. :editable="fileListID2.status != 2"
  292. :limit="1"
  293. :fileMediatype="'all'"
  294. uploadUrl="/custom/file/upload/2"
  295. :baseUrl="updateUrl"
  296. :imageWidth="150"
  297. :imageHeight="150"
  298. :showPreviewDelete="false"
  299. :canDelete="false"
  300. :uploadError="false"
  301. :showProgress="false"
  302. :canChoose="true"
  303. :showError="false"
  304. :show-progress="false"
  305. disablePreview
  306. :image-styles="imageStyle"
  307. @update:modelValue="(val) => handleFileUpdate(val, '2')"
  308. customClass="avatar-uploader"
  309. >
  310. <view class="file-item">
  311. <image
  312. v-if="!isPdf(fileListID2.path)"
  313. class="avatar"
  314. :src="updateUrl + (fileListID2.path)"
  315. ></image>
  316. <view v-else>
  317. <image class="icon" :src="icon_doc" />
  318. </view>
  319. </view>
  320. </cwg-file-picker-wrapper>
  321. </uni-col>
  322. <uni-col :xs="24" :sm="24" :md="4" :lg="4" :xl="4">
  323. <view class="refresh">
  324. <image :src="icon_refresh" @click="getCustomFileList" />
  325. </view>
  326. </uni-col>
  327. </uni-row>
  328. </uni-col>
  329. <uni-col v-if="isPC" :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  330. <view class="crm-title-box">
  331. <text class="tit">{{ t('ImproveImmediately.Title.MobileDeviceUpload') }}</text>
  332. <uni-tooltip placement="bottom">
  333. <text class="icon-tip">ⓘ</text>
  334. <template v-slot:content>
  335. <view class="address-tip">
  336. {{ t('ImproveImmediately.Content.popover2') }}
  337. </view>
  338. </template>
  339. </uni-tooltip>
  340. </view>
  341. <view class="con-box">
  342. <view class="box">
  343. <image class="mobile" :src="icon_mobile" />
  344. <image class="arrow" :src="icon_arrowR" />
  345. <image
  346. class="img_mobile"
  347. style="
  348. display: inline-block;
  349. width: 120px;
  350. height: 120px;
  351. border: 8px solid var(--color-gray);
  352. "
  353. :src="mobile"
  354. >
  355. <div slot="error" class="image-slot">
  356. <i class="el-icon-picture-outline"></i>
  357. </div>
  358. </image>
  359. <image class="icon_refresh" :src="icon_refresh" @click="getMobileInfo" />
  360. </view>
  361. </view>
  362. </uni-col>
  363. </uni-row>
  364. <view class="descending">
  365. <p class="title">
  366. <span class="dian1">·</span>
  367. <span>{{ t('ImproveImmediately.Title.IdentificationStatement') }}</span>
  368. </p>
  369. <p class="des">
  370. <span class="dian">-</span>
  371. <span>{{ t('ImproveImmediately.Content.ProofIdentity4') }}</span>
  372. </p>
  373. <p class="des">
  374. <span class="dian">-</span>
  375. <span>{{ t('ImproveImmediately.Content.ProofIdentity5') }}</span>
  376. </p>
  377. <p class="des" v-if="['cn', 'zhHant'].indexOf(local) == -1">
  378. <span class="dian">-</span>
  379. <span>{{ t('ImproveImmediately.Content.ProofIdentity6') }}</span>
  380. </p>
  381. <p class="des">
  382. <span class="dian">·</span>
  383. <span>{{ t('ImproveImmediately.Content.ProofIdentity1') }}</span>
  384. </p>
  385. <p class="des">
  386. <span class="dian">·</span>
  387. <span>{{ t('ImproveImmediately.Content.ProofIdentity2') }}</span>
  388. </p>
  389. <p class="des">
  390. <span class="dian">·</span>
  391. <span>{{ t('ImproveImmediately.Content.ProofIdentity3') }}</span>
  392. </p>
  393. <p class="des" v-if="['cn', 'zhHant'].indexOf(local) == -1">
  394. <span class="dian">·</span>
  395. <span>{{ t('ImproveImmediately.Content.ProofIdentity7') }}</span>
  396. </p>
  397. <p class="des" v-if="['cn', 'zhHant'].indexOf(local) == -1">
  398. <span class="dian">·</span>
  399. <span>{{ t('ImproveImmediately.Content.ProofIdentity8') }}</span>
  400. </p>
  401. </view>
  402. </view>
  403. <!-- 第四步:地址证明 -->
  404. <view v-show="currentStep === 4" class="form-section">
  405. <uni-row class="demo-uni-row uni-row1">
  406. <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  407. <view class="crm-title-box">
  408. <text class="tit">{{ t('ImproveImmediately.Title.ProofAddress') }}</text>
  409. <uni-tooltip placement="bottom">
  410. <text class="icon-tip">ⓘ</text>
  411. <template v-slot:content>
  412. <view class="address-tip">
  413. {{ t('ImproveImmediately.Content.ProofAddress5') }}
  414. </view>
  415. </template>
  416. </uni-tooltip>
  417. </view>
  418. <uni-row class="demo-uni-row uni-row1">
  419. <uni-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
  420. <cwg-file-picker-wrapper
  421. v-model="fileListAdd1.path"
  422. :editable="fileListAdd1.status != 2"
  423. :limit="1"
  424. :fileMediatype="'all'"
  425. uploadUrl="/custom/file/upload/3"
  426. :baseUrl="updateUrl"
  427. :imageWidth="150"
  428. :imageHeight="150"
  429. :showPreviewDelete="false"
  430. :canDelete="false"
  431. :uploadError="false"
  432. :showProgress="false"
  433. :canChoose="true"
  434. :showError="false"
  435. :show-progress="false"
  436. disablePreview
  437. :image-styles="imageStyle"
  438. @update:modelValue="(val) => handleFileUpdate(val, '1')"
  439. customClass="avatar-uploader"
  440. >
  441. <view class="file-item">
  442. <image
  443. v-if="!isPdf(fileListAdd1.path)"
  444. class="avatar"
  445. :src="updateUrl + fileListAdd1.path"
  446. ></image>
  447. <view v-else>
  448. <image class="icon" :src="icon_doc" />
  449. </view>
  450. </view>
  451. </cwg-file-picker-wrapper>
  452. </uni-col>
  453. <uni-col :xs="24" :sm="24" :md="4" :lg="4" :xl="4">
  454. <view class="refresh">
  455. <image :src="icon_refresh" @click="getCustomFileList" />
  456. </view>
  457. </uni-col>
  458. </uni-row>
  459. </uni-col>
  460. <uni-col v-if="isPC" :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  461. <view class="crm-title-box">
  462. <text class="tit">{{ t('ImproveImmediately.Title.MobileDeviceUpload') }}</text>
  463. <uni-tooltip placement="bottom">
  464. <text class="icon-tip">ⓘ</text>
  465. <template v-slot:content>
  466. <view class="address-tip">
  467. {{ t('ImproveImmediately.Content.popover2') }}
  468. </view>
  469. </template>
  470. </uni-tooltip>
  471. </view>
  472. <view class="con-box">
  473. <view class="box">
  474. <cwg-icon name="icon_mobile" :size="50"/>
  475. <!-- <image class="mobile" :src="icon_mobile" />-->
  476. <image class="arrow" :src="icon_arrowR" />
  477. <image
  478. class="img_mobile"
  479. style="
  480. display: inline-block;
  481. width: 120px;
  482. height: 120px;
  483. border: 8px solid var(--color-gray);
  484. "
  485. :src="mobile"
  486. >
  487. <div slot="error" class="image-slot">
  488. <i class="el-icon-picture-outline"></i>
  489. </div>
  490. </image>
  491. <image class="icon_refresh" :src="icon_refresh" @click="getMobileInfo" />
  492. </view>
  493. </view>
  494. </uni-col>
  495. </uni-row>
  496. <uni-row class="demo-uni-row uni-row1">
  497. <uni-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  498. <view class="crm-title-box">
  499. <text class="tit">{{ t('PersonalManagement.Title.AttachedFile') }}</text>
  500. </view>
  501. <uni-row class="demo-uni-row uni-row1">
  502. <uni-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  503. <cwg-file-picker
  504. :limit="9"
  505. :multiple="true"
  506. :editable="true"
  507. :fileMediatype="'all'"
  508. uploadUrl="/custom/file/upload/10"
  509. :baseUrl="updateUrl"
  510. :imageWidth="100"
  511. :imageHeight="60"
  512. :showPreviewDelete="false"
  513. :canDelete="false"
  514. :uploadError="false"
  515. :showProgress="false"
  516. :image-styles="imageStyle"
  517. @update:modelValue="(val) => handleFileUpdate(val, '10')"
  518. custom-class="fileOther"
  519. :showError="false"
  520. >
  521. <button type="primary">{{ t('Btn.Upload') }}</button>
  522. </cwg-file-picker>
  523. <view class="fileList">
  524. <view id="files" v-for="(item,index) in fileListOthers" :key="index">
  525. <cwg-file-picker-wrapper
  526. customClass="list_upload"
  527. v-model="item.path"
  528. :editable="item.status != 2"
  529. :limit="1"
  530. :fileMediatype="'all'"
  531. :uploadUrl="'/custom/file/upload/10/'+item.id"
  532. :baseUrl="updateUrl"
  533. :uploadError="false"
  534. :showProgress="false"
  535. :imageWidth="100"
  536. :imageHeight="60"
  537. :showPreviewDelete="true"
  538. :disablePreview="true"
  539. :image-styles="imageStyle"
  540. :canChoose="true"
  541. @update:modelValue="(val) => handleFileUpdate(val, '1')"
  542. >
  543. <view class="file-item">
  544. <image
  545. v-if="!isPdf(item.path) || !isPdf(item.againPath)"
  546. class="avatar"
  547. :src="updateUrl + (item.againPath || item.path)"
  548. ></image>
  549. <view v-else>
  550. <image class="icon" :src="icon_doc" />
  551. </view>
  552. </view>
  553. </cwg-file-picker-wrapper>
  554. <view class="options">
  555. <u-button
  556. style="margin-right: 20px;"
  557. :disabled="item.status == 2"
  558. >
  559. <a
  560. :href="updateUrl + (item.againPath || item.path)"
  561. target="_blank"
  562. >
  563. {{ t('Btn.item12') }}
  564. </a>
  565. </u-button>
  566. <u-button
  567. :disabled="item.status == 2"
  568. @click="fileOtherDelete(item.id)"
  569. >
  570. {{ t('Btn.Delete') }}
  571. </u-button>
  572. </view>
  573. </view>
  574. </view>
  575. </uni-col>
  576. <uni-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  577. <view class="refresh">
  578. <image :src="icon_refresh" @click="getCustomFileList" />
  579. </view>
  580. </uni-col>
  581. </uni-row>
  582. </uni-col>
  583. </uni-row>
  584. <view class="descending">
  585. <p class="title">
  586. <span>{{ t('ImproveImmediately.Title.AddressDescription') }}</span>
  587. </p>
  588. <p class="des">
  589. <span class="dian">-</span>
  590. <span>{{ t('ImproveImmediately.Content.ProofAddress1') }}</span>
  591. </p>
  592. <p class="des">
  593. <span class="dian">-</span>
  594. <span>{{ t('ImproveImmediately.Content.ProofAddress2') }}</span>
  595. </p>
  596. <p class="des">
  597. <span class="dian">-</span>
  598. <span>{{ t('ImproveImmediately.Content.ProofAddress3') }}</span>
  599. </p>
  600. <p class="des">
  601. <span class="dian" v-if="['cn', 'zhHant'].indexOf(local) != -1">·</span>
  602. <span class="dian" v-if="local == 'en'">-</span>
  603. <span>{{ t('ImproveImmediately.Content.ProofAddress4') }}</span>
  604. </p>
  605. <p class="des">
  606. <span class="dian">·</span>
  607. <span>{{ t('ImproveImmediately.Content.ProofAddress6') }}</span>
  608. </p>
  609. <p class="des" v-if="local == 'en'">
  610. <span class="dian">·</span>
  611. <span>{{ t('ImproveImmediately.Content.ProofAddress7') }}</span>
  612. </p>
  613. <p class="des" v-if="local == 'en'">
  614. <span class="dian">·</span>
  615. <span>{{ t('ImproveImmediately.Content.ProofAddress8') }}</span>
  616. </p>
  617. </view>
  618. </view>
  619. <!-- 步骤控制按钮 -->
  620. <view>
  621. <template v-if="currentStep === 4">
  622. <view class="btns">
  623. <view class="cwg-button two-btn">
  624. <u-button class="btn-primary" type="primary" block @click="cancle">
  625. {{ t('Btn.Cancel') }}
  626. </u-button>
  627. <u-button plain block class="prev-btn btn-primary" @click="goStep(3)">
  628. {{ t('Btn.Last') }}
  629. </u-button>
  630. <u-button type="primary" class="btn-primary" block :loading="loadingStates.submit" @click="Submit">
  631. {{ t('Btn.Submit') }}
  632. </u-button>
  633. </view>
  634. </view>
  635. </template>
  636. <template v-else-if="currentStep === 3">
  637. <view class="btns">
  638. <view class="cwg-button two-btn">
  639. <u-button class="btn-primary" type="primary" block @click="cancle">
  640. {{ t('Btn.Cancel') }}
  641. </u-button>
  642. <u-button plain block class="prev-btn btn-primary" @click="goStep(2)">
  643. {{ t('Btn.Last') }}
  644. </u-button>
  645. <u-button class="btn-primary" type="primary" block :loading="loadingStates.next" @click="goStep(4)">
  646. {{ t('Btn.Next') }}
  647. </u-button>
  648. </view>
  649. </view>
  650. </template>
  651. <template v-else-if="currentStep === 2">
  652. <view class="btns">
  653. <view class="cwg-button two-btn">
  654. <u-button class="btn-primary" type="primary" block @click="cancle">
  655. {{ t('Btn.Cancel') }}
  656. </u-button>
  657. <u-button plain block class="prev-btn btn-primary" @click="goStep(1)">
  658. {{ t('Btn.Last') }}
  659. </u-button>
  660. <u-button class="btn-primary" type="primary" block :loading="loadingStates.next" @click="goStep(3)">
  661. {{ t('Btn.Next') }}
  662. </u-button>
  663. </view>
  664. </view>
  665. </template>
  666. <template v-else-if="currentStep === 1">
  667. <view class="btns">
  668. <view class="cwg-button two-btn">
  669. <u-button class="btn-primary" type="primary" block @click="cancle">
  670. {{ t('Btn.Cancel') }}
  671. </u-button>
  672. <u-button class="btn-primary" type="primary" block :loading="loadingStates.next" @click="goStep(2)">
  673. {{ t('Btn.Next') }}
  674. </u-button>
  675. </view>
  676. </view>
  677. </template>
  678. </view>
  679. </uni-forms>
  680. </view>
  681. <view class="form-tab"></view>
  682. </cwg-page-wrapper>
  683. <!--离开弹出框-->
  684. <uni-popup ref="dialogCheck" type="center" background-color="#fff">
  685. <view class="dia-content" v-if="dialogCheck1">
  686. <view class="icon">
  687. <i class="iconfont iconjingshi"></i>
  688. </view>
  689. <view class="des1">{{ t('ImproveImmediately.Content.Leave1') }}</view>
  690. <view class="des2">{{ t('ImproveImmediately.Content.Leave2') }}</view>
  691. <view class="dialog-footer">
  692. <u-button @click="closeDia">{{ t('Btn.TemporarilyNot') }}</u-button>
  693. <u-button type="primary" @click="save">{{ t('Btn.Save') }}</u-button>
  694. </view>
  695. </view>
  696. <view class="dia-content" v-if="!dialogCheck1">
  697. <view class="icon">
  698. <cwg-icon :size="60" name="verified" :color="'#4a6cf7'" />
  699. </view>
  700. <view class="des1">{{ t('ApplicationDialog.Des1') }}</view>
  701. <QrCode v-if="text1" :text="text1"></QrCode>
  702. <view class="dialog-footer">
  703. <button @click="closeDia">{{ t('Btn.Cancel') }}</button>
  704. <button type="primary" @click="toHome">{{ t('Btn.Home') }}</button>
  705. </view>
  706. </view>
  707. </uni-popup>
  708. </template>
  709. <script setup lang="ts">
  710. import { ref, onMounted, onUnmounted, watch, computed } from 'vue'
  711. import { useI18n } from 'vue-i18n'
  712. import { onLoad } from '@dcloudio/uni-app'
  713. import { personalApi } from '@/service/personal'
  714. import Config from '@/config/index'
  715. import QrCode from '@/components/QRCode.vue'
  716. import { userToken } from '@/composables/config'
  717. import useRouter from '@/hooks/useRouter'
  718. import { Patterns, Validators } from '@/utils/validators'
  719. import { pinyin } from 'pinyin-pro'
  720. import config from '@/config/index'
  721. import icon_doc from '@/static/icons/crm-document.svg'
  722. import icon_refresh from '@/static/icons/crm-refresh.svg'
  723. import icon_mobile from '@/static/icons/icon_mobile.svg'
  724. import icon_arrowR from '@/static/icons/icon_arrowR.svg'
  725. const router = useRouter()
  726. const { t,local } = useI18n()
  727. const currentStep = ref<number>(3)
  728. const formRef = ref()
  729. const dialogCheck = ref(null)
  730. const dialogCheck1 = ref(false)
  731. const text1 = ref('')
  732. const qrCodeStatus = ref(false)
  733. const addressTipPopup = ref()
  734. // 新增的响应式数据
  735. const divActiveHelf = ref(false)
  736. const divActiveAll = ref(false)
  737. const websock = ref(null)
  738. const isPC = ref(true)
  739. const fileListID1 = ref({ againPath: '', id: null, path: '', status: null, type: null })
  740. const fileListID2 = ref({ againPath: '', id: null, path: '', status: null, type: null })
  741. const fileListAdd1 = ref({ againPath: '', id: null, path: '', status: null, type: null })
  742. const fileListAdd2 = ref({ againPath: '', id: null, path: '', status: null, type: null })
  743. const fileListOthers = ref([])
  744. const actionID1 = ref('')
  745. const actionID2 = ref('')
  746. const actionAdd1 = ref('')
  747. const actionAdd2 = ref('')
  748. const actionOtherAdd = ref('')
  749. const flag = ref(false)
  750. const pictLoading = ref(false)
  751. const pictLoadingImg = ref(false)
  752. const isApprove = ref(false)
  753. const metaInfo = ref({})
  754. const HostWs = ref(Config.HostWs)
  755. const cities = ref([])
  756. const states = ref([])
  757. const countries = ref([])
  758. const uploadImage = ref(0)
  759. const updateUrl = config.Host80
  760. const mobile = ref('')
  761. const notCountry = [
  762. 'AF',
  763. 'AI',
  764. 'AG',
  765. 'BS',
  766. 'BY',
  767. 'BZ',
  768. 'BA',
  769. 'BI',
  770. 'CF',
  771. 'CD',
  772. 'CU',
  773. 'ET',
  774. 'FJ',
  775. 'PS',
  776. 'GN',
  777. 'GW',
  778. 'HT',
  779. 'IR',
  780. 'IQ',
  781. 'LB',
  782. 'LY',
  783. 'ML',
  784. 'MM',
  785. 'NI',
  786. 'KP',
  787. 'PW',
  788. 'RU',
  789. 'SO',
  790. 'SS',
  791. 'SD',
  792. 'SY',
  793. 'UA',
  794. 'US',
  795. 'VE',
  796. 'YE',
  797. 'ZW',
  798. ]
  799. const imageStyle = ref({
  800. width: 200,
  801. height: 150,
  802. border: {
  803. radius: '5px',
  804. },
  805. })
  806. // 验证函数
  807. function validateName(a: any, b?: any, c?: any) {
  808. const reg = /^[A-Z\s]+$/i
  809. if (typeof c === 'function') {
  810. const value = b
  811. const callback = c
  812. const val = String(value ?? '').trim()
  813. if (!val) return callback(new Error(t('card.vaildate.v4')))
  814. if (!reg.test(val)) return callback(new Error(t('card.vaildate.v38')))
  815. if (val.length < 2 || val.length > 23) return callback(new Error(t('card.vaildate.v39')))
  816. const firstName = String(formData.value?.firstName ?? '').trim()
  817. const lastName = String(formData.value?.lastName ?? '').trim()
  818. if (`${firstName} ${lastName}`.length > 23) return callback(new Error(t('card.vaildate.v40')))
  819. return callback()
  820. }
  821. const val = String(a ?? '').trim()
  822. if (!val) return t('card.vaildate.v4')
  823. if (!reg.test(val)) return t('card.vaildate.v38')
  824. if (val.length < 2 || val.length > 23) return t('card.vaildate.v39')
  825. const firstName = String(formData.value?.firstName ?? '').trim()
  826. const lastName = String(formData.value?.lastName ?? '').trim()
  827. if (`${firstName} ${lastName}`.length > 23) return t('card.vaildate.v40')
  828. return true
  829. }
  830. function validateBirthday(a: any, b?: any, c?: any) {
  831. if (typeof c === 'function') {
  832. const value = b
  833. const callback = c
  834. const val = value
  835. if (!val) return callback(new Error(t('card.vaildate.v5')))
  836. const today = new Date()
  837. const birthDate = new Date(val)
  838. let age = today.getFullYear() - birthDate.getFullYear()
  839. const month = today.getMonth() - birthDate.getMonth()
  840. if (month < 0 || (month === 0 && today.getDate() < birthDate.getDate())) age--
  841. if (age < 18) return callback(new Error(t('card.New.n3')))
  842. return callback()
  843. }
  844. const val = a
  845. if (!val) return t('card.vaildate.v5')
  846. const today = new Date()
  847. const birthDate = new Date(val)
  848. let age = today.getFullYear() - birthDate.getFullYear()
  849. const month = today.getMonth() - birthDate.getMonth()
  850. if (month < 0 || (month === 0 && today.getDate() < birthDate.getDate())) age--
  851. return age < 18 ? t('card.New.n3') : true
  852. }
  853. function validateAddress(a: any, b?: any, c?: any) {
  854. if (typeof c === 'function') {
  855. const value = b
  856. const callback = c
  857. const val = String(value ?? '').trim()
  858. if (!val) return callback(new Error(t('card.vaildate.v27')))
  859. if (val.length < 2 || val.length > 40) return callback(new Error(t('card.New.n1')))
  860. if (!Patterns.address.test(val)) return callback(new Error(t('card.New.n1')))
  861. return callback()
  862. }
  863. const val = String(a ?? '').trim()
  864. if (!val) return t('card.vaildate.v27')
  865. if (val.length < 2 || val.length > 40) return t('card.New.n1')
  866. return Patterns.address.test(val) ? true : t('card.New.n1')
  867. }
  868. const rules = {
  869. customType: [Validators.required(t('card.vaildate.v1'))],
  870. firstName: [Validators.required(t('card.vaildate.v3')), Validators.custom(validateName)],
  871. lastName: [Validators.required(t('card.vaildate.v4')), Validators.custom(validateName)],
  872. nationality: [Validators.required(t('card.vaildate.v6'), 'change')],
  873. IdentityType: [Validators.required(t('card.vaildate.v1'))],
  874. identity: [Validators.required(t('card.vaildate.v4'))],
  875. gender: [Validators.required(t('card.vaildate.v9'), 'change')],
  876. birth: [
  877. Validators.required(t('card.vaildate.v5'), 'change'),
  878. Validators.custom(validateBirthday, 'change'),
  879. ],
  880. country: [Validators.required(t('card.vaildate.v1'))],
  881. state: [Validators.required(t('card.vaildate.v1'))],
  882. city: [Validators.required(t('card.vaildate.v1'))],
  883. addressLines1: [Validators.required(t('card.vaildate.v27')), Validators.custom(validateAddress)],
  884. zipCode: [
  885. Validators.required(t('card.vaildate.v8')),
  886. Validators.pattern(Patterns.postcode, t('card.New.n2')),
  887. ],
  888. level: [Validators.required(t('card.vaildate.v1'))],
  889. employmentStatus: [Validators.required(t('card.vaildate.v1'))],
  890. tradingObjectives: [Validators.required(t('card.vaildate.v1'))],
  891. sourceFunding: [Validators.required(t('card.vaildate.v1'))],
  892. grossAnnualIncome: [Validators.required(t('card.vaildate.v1'))],
  893. totalNewWorth: [Validators.required(t('card.vaildate.v1'))],
  894. cardType: [Validators.required(t('card.vaildate.v1'))],
  895. idFrontUrl: [Validators.required(t('card.vaildate.v1'))],
  896. idBackUrl: [Validators.required(t('card.vaildate.v1'))],
  897. addressProofUrl: [Validators.required(t('card.vaildate.v1'))],
  898. }
  899. onLoad((options) => {
  900. currentStep.value = parseInt(options?.currentStep || '1', 10)
  901. })
  902. function goStep(step: number) {
  903. console.log(step,'step')
  904. if ( step == 4){
  905. if (currentUploadCard.value == 1){
  906. if (!formData.value.cardType){
  907. uni.showToast({ title:t('vaildate.CardType.empty'),icon:'error'
  908. })
  909. return
  910. }
  911. if (!fileListID1.value.path || !fileListID2.value.path){
  912. uni.showToast({ title: t('vaildate.IDPhoto.empty'),icon: 'error'
  913. })
  914. return
  915. }
  916. }
  917. }
  918. currentStep.value = step
  919. }
  920. // 选项数据
  921. const customerTypeOptions = [
  922. { value: 1, text: t('ImproveImmediately.Label.CustomerType1') },
  923. { value: 2, text: t('ImproveImmediately.Label.CustomerType2') },
  924. ]
  925. const identityTypes = ref([
  926. { text: t('ImproveImmediately.Label.IDCard'), value: 2 },
  927. { text: t('ImproveImmediately.Label.Passport'), value: 3 },
  928. ])
  929. const genderOptions = [
  930. { value: 1, text: t('PersonalManagement.Label.Men') },
  931. { value: 2, text: t('PersonalManagement.Label.Women') },
  932. ]
  933. const radioList = [
  934. { value: 1, text: t('ImproveImmediately.Label.Yes') },
  935. { value: 0, text: t('ImproveImmediately.Label.No') },
  936. ]
  937. const educationOptions = [
  938. { value: 1, text: t('ImproveImmediately.Label.Education1') },
  939. { value: 2, text: t('ImproveImmediately.Label.Education2') },
  940. { value: 3, text: t('ImproveImmediately.Label.Education3') },
  941. { value: 4, text: t('ImproveImmediately.Label.Education4') },
  942. { value: 5, text: t('ImproveImmediately.Label.Education5') },
  943. ]
  944. const employmentOptions = [
  945. { value: 1, text: t('ImproveImmediately.Label.OnJob1') },
  946. { value: 2, text: t('ImproveImmediately.Label.OnJob2') },
  947. { value: 3, text: t('ImproveImmediately.Label.OnJob3') },
  948. { value: 4, text: t('ImproveImmediately.Label.OnJob4') },
  949. { value: 5, text: t('ImproveImmediately.Label.OnJob5') },
  950. ]
  951. const transactionPurposeOptions = [
  952. { value: 1, text: t('ImproveImmediately.Label.purposeTransaction1') },
  953. { value: 2, text: t('ImproveImmediately.Label.purposeTransaction2') },
  954. { value: 3, text: t('ImproveImmediately.Label.purposeTransaction3') },
  955. { value: 4, text: t('ImproveImmediately.Label.purposeTransaction4') },
  956. ]
  957. const fundSourceOptions = [
  958. { value: 1, text: t('ImproveImmediately.Label.SourceFunds1') },
  959. { value: 2, text: t('ImproveImmediately.Label.SourceFunds2') },
  960. { value: 3, text: t('ImproveImmediately.Label.SourceFunds3') },
  961. { value: 4, text: t('ImproveImmediately.Label.SourceFunds4') },
  962. { value: 5, text: t('ImproveImmediately.Label.SourceFunds5') },
  963. { value: 6, text: t('ImproveImmediately.Label.SourceFunds6') },
  964. ]
  965. const annualIncomeOptions = [
  966. { value: 1, text: t('ImproveImmediately.Label.TotalAnnualRevenue1') },
  967. { value: 2, text: t('ImproveImmediately.Label.TotalAnnualRevenue2') },
  968. { value: 3, text: t('ImproveImmediately.Label.TotalAnnualRevenue3') },
  969. { value: 4, text: t('ImproveImmediately.Label.TotalAnnualRevenue4') },
  970. { value: 5, text: t('ImproveImmediately.Label.TotalAnnualRevenue5') },
  971. ]
  972. const netWorthOptions = [
  973. { value: 1, text: t('ImproveImmediately.Label.TotalNetAssets1') },
  974. { value: 2, text: t('ImproveImmediately.Label.TotalNetAssets2') },
  975. { value: 3, text: t('ImproveImmediately.Label.TotalNetAssets3') },
  976. { value: 4, text: t('ImproveImmediately.Label.TotalNetAssets4') },
  977. { value: 5, text: t('ImproveImmediately.Label.TotalNetAssets5') },
  978. ]
  979. const cardTypeOptions = [
  980. { value: 'ID_CARD', text: 'ID Card' },
  981. { value: 'PASSPORT', text: 'Passport' },
  982. { value: 'DRIVERS', text: 'Driver\'s License' },
  983. { value: 'RESIDENCE_PERMIT', text: 'Residence Permit' },
  984. ]
  985. // 表单数据
  986. const formData = ref({
  987. customType: 1,
  988. companyName: undefined,
  989. lastName: undefined,
  990. firstName: undefined,
  991. middle: undefined,
  992. nationality: undefined,
  993. IdentityType: 2,
  994. identity: undefined,
  995. nameEn: undefined,
  996. gender: undefined,
  997. birth: undefined,
  998. country: undefined,
  999. state: undefined,
  1000. city: undefined,
  1001. addressLines1: undefined,
  1002. addressLines2: undefined,
  1003. zipCode: undefined,
  1004. level: undefined,
  1005. employmentStatus: undefined,
  1006. tradingObjectives: undefined,
  1007. sourceFunding: undefined,
  1008. grossAnnualIncome: undefined,
  1009. totalNewWorth: undefined,
  1010. experienceTradingDerivative: 0,
  1011. experienceTradingForex: 0,
  1012. derivativeProducts: 0,
  1013. experienceQualification: 0,
  1014. cardType: undefined,
  1015. idFrontUrl: undefined,
  1016. idBackUrl: undefined,
  1017. addressProofUrl: undefined,
  1018. otherFiles: undefined,
  1019. addressLines: [],
  1020. })
  1021. // 选项数据
  1022. const countryOptions = ref<Array<{ text: string; value: string }>>([])
  1023. const stateOptions = ref<Array<{ text: string; value: string }>>([])
  1024. const cityOptions = ref<Array<{ text: string; value: string }>>([])
  1025. // 加载状态
  1026. const loadingStates = ref({
  1027. next: false,
  1028. submit: false,
  1029. })
  1030. // 计算属性
  1031. const identityLabel = computed(() => {
  1032. if (formData.value.IdentityType === 2) return t('ImproveImmediately.Label.IDCard')
  1033. if (formData.value.IdentityType === 3) return t('ImproveImmediately.Label.Passport')
  1034. return t('ImproveImmediately.Label.IdentityID')
  1035. })
  1036. // 计算属性:当前选中国籍的 uploadCard 值
  1037. const currentUploadCard = computed(() => {
  1038. if (!formData.value.nationality || !countries.value.length) {
  1039. return 0
  1040. }
  1041. const selectedCountry = countries.value.find(
  1042. (item: any) => item.code === formData.value.nationality,
  1043. )
  1044. return selectedCountry ? (selectedCountry.uploadCard || 0) : 0
  1045. })
  1046. // 计算属性:当前选中国籍的 uploadAddress 值
  1047. const currentUploadAddress = computed(() => {
  1048. if (!formData.value.nationality || !countries.value.length) {
  1049. return 0
  1050. }
  1051. const selectedCountry = countries.value.find(
  1052. (item: any) => item.code === formData.value.nationality,
  1053. )
  1054. return selectedCountry ? (selectedCountry.uploadAddress || 0) : 0
  1055. })
  1056. // 方法
  1057. function changeCountry(value: any) {
  1058. // 处理国家选择变化
  1059. // 清空省份/城市选择//
  1060. formData.value.state = ''
  1061. formData.value.city = ''
  1062. stateOptions.value = []
  1063. cityOptions.value = []
  1064. states.value = []
  1065. cities.value = []
  1066. let item = {}
  1067. countries.value.forEach(element => {
  1068. if (element.code == value) {
  1069. item = element
  1070. return
  1071. }
  1072. })
  1073. getStateList(item.id)
  1074. }
  1075. function handleFileUpdate(value, type) {
  1076. console.log(value, type, 'uplaod')
  1077. if (type == 10){
  1078. uni.showToast({ title: t('card.New1.d5'),icon: 'none' })
  1079. getCustomFileList();
  1080. }
  1081. }
  1082. async function fileOtherDelete(id) {
  1083. uni.showModal({
  1084. title: t('Msg.SystemPrompt'),
  1085. content: t('Msg.Delete'),
  1086. cancelText: t('Btn.Cancel'),
  1087. confirmText: t('Btn.Confirm'),
  1088. success: async (res) => {
  1089. if (res.confirm) {
  1090. // 确认删除
  1091. let data = await personalApi.customFileDelete({ ids: [id] })
  1092. if (data.code == 200) {
  1093. uni.showToast(t('Msg.DeleteSuccess'))
  1094. getCustomFileList()
  1095. } else {
  1096. uni.showToast(res.msg)
  1097. }
  1098. }
  1099. },
  1100. fail: () => {
  1101. },
  1102. })
  1103. }
  1104. function changeState(val) {
  1105. formData.value.city = ''
  1106. cityOptions.value = []
  1107. let item = {}
  1108. states.value.forEach((element) => {
  1109. if (element.name == val || element.enName == val) {
  1110. item = element
  1111. return
  1112. }
  1113. })
  1114. getCityList(item.id)
  1115. }
  1116. function handleChange(value: any) {
  1117. formData.value = { ...formData.value, [value.key]: value.value }
  1118. console.log(value)
  1119. if (value.key === 'country') {
  1120. formData.value.state = ''
  1121. formData.value.city = ''
  1122. stateOptions.value = []
  1123. cityOptions.value = []
  1124. if (value.value) {
  1125. getStateList(value.value)
  1126. }
  1127. } else if (value.key === 'state') {
  1128. formData.value.city = ''
  1129. cityOptions.value = []
  1130. if (value.value) {
  1131. getCityList(value.value)
  1132. }
  1133. }
  1134. }
  1135. function openAddressTip() {
  1136. // 打开地址提示弹窗
  1137. addressTipPopup.value.open()
  1138. }
  1139. function isPdf(url, image) {
  1140. let res = !!url
  1141. if (image) {
  1142. return res && url.substr(-3, 3) == 'pdf' &&
  1143. url.substr(-3, 3) == 'PDF'
  1144. }
  1145. return res && (url.substr(-3, 3) == 'pdf' ||
  1146. url.substr(-3, 3) == 'PDF')
  1147. }
  1148. function cancle() {
  1149. if (!isApprove.value) {
  1150. dialogCheck.value.open()
  1151. dialogCheck1.value = true
  1152. } else {
  1153. router.push({ path: '/pages/customer/index' })
  1154. }
  1155. }
  1156. function closeDia() {
  1157. dialogCheck.value.close()
  1158. }
  1159. function toHome() {
  1160. dialogCheck.value.close()
  1161. router.push({ path: '/pages/customer/index' })
  1162. }
  1163. async function save() {
  1164. await updateInfo(1)
  1165. }
  1166. async function Submit() {
  1167. loadingStates.value.submit = true
  1168. try {
  1169. formData.value.addressLines = []
  1170. if (formData.value.addressLines1) {
  1171. formData.value.addressLines.push(formData.value.addressLines1)
  1172. }
  1173. if (formData.value.addressLines2) {
  1174. formData.value.addressLines.push(formData.value.addressLines2)
  1175. }
  1176. if (!formData.value.addressLines1 && !formData.value.addressLines2) {
  1177. formData.value.addressLines = []
  1178. }
  1179. if (formData.value.customType != 2) {
  1180. formData.value.companyName = ''
  1181. }
  1182. let res = await personalApi.CustomUpdateInfo({
  1183. ...formData.value,
  1184. })
  1185. if (res.code == Config.Code.StatusOK) {
  1186. await getCustomFileList()
  1187. await customApply()
  1188. } else {
  1189. uni.showToast({ title: res.msg, icon: 'none' })
  1190. }
  1191. } catch (error: any) {
  1192. uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
  1193. } finally {
  1194. loadingStates.value.submit = false
  1195. }
  1196. }
  1197. async function updateInfo(save: number) {
  1198. try {
  1199. formData.value.addressLines = []
  1200. if (formData.value.addressLines1) {
  1201. formData.value.addressLines.push(formData.value.addressLines1)
  1202. }
  1203. if (formData.value.addressLines2) {
  1204. formData.value.addressLines.push(formData.value.addressLines2)
  1205. }
  1206. if (!formData.value.addressLines1 && !formData.value.addressLines2) {
  1207. formData.value.addressLines = []
  1208. }
  1209. let res = await personalApi.CustomUpdateInfo({
  1210. ...formData.value,
  1211. })
  1212. if (res.code == Config.Code.StatusOK) {
  1213. if (save) {
  1214. dialogCheck.value.close()
  1215. router.push({ path: '/pages/customer/index' })
  1216. }
  1217. } else {
  1218. uni.showToast({ title: res.msg, icon: 'none' })
  1219. }
  1220. } catch (error: any) {
  1221. uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
  1222. }
  1223. }
  1224. async function customApply() {
  1225. try {
  1226. let res = await personalApi.customApplyReal({})
  1227. if (res.code == Config.Code.StatusOK) {
  1228. isApprove.value = true
  1229. await getLoginInfo()
  1230. dialogCheck.value.open()
  1231. dialogCheck1.value = false
  1232. } else {
  1233. uni.showToast({ title: res.msg, icon: 'none' })
  1234. }
  1235. } catch (error: any) {
  1236. uni.showToast({ title: error.message, icon: 'none' })
  1237. }
  1238. }
  1239. async function getCountryList() {
  1240. try {
  1241. let res = await personalApi.Country({})
  1242. if (res.code == Config.Code.StatusOK) {
  1243. countryOptions.value = res.data.map((item: any) => ({
  1244. text: item.enName,
  1245. value: item.code,
  1246. disabled: notCountry.indexOf(item.code) !== -1,
  1247. }))
  1248. countries.value = res.data
  1249. const country = formData.value.country
  1250. if (country) {
  1251. countries.value.forEach((item) => {
  1252. if (item.code == country) {
  1253. getStateList(item.id)
  1254. }
  1255. })
  1256. }
  1257. }
  1258. } catch (error: any) {
  1259. uni.showToast({ title: error.message, icon: 'none' })
  1260. }
  1261. }
  1262. async function getStateList(pid: string) {
  1263. try {
  1264. let res = await personalApi.Country({ pid })
  1265. if (res.code == Config.Code.StatusOK) {
  1266. stateOptions.value = res.data.map((item: any) => ({
  1267. text: local.value === 'en' ? item.enName : item.name,
  1268. value: local.value === 'en' ? item.enName : item.name,
  1269. }))
  1270. states.value = res.data
  1271. const state = formData.value.state
  1272. if (state) {
  1273. states.value.forEach((item) => {
  1274. if (
  1275. item.name == state ||
  1276. item.enName == state
  1277. ) {
  1278. getCityList(item.id)
  1279. }
  1280. })
  1281. }
  1282. }
  1283. } catch (error: any) {
  1284. }
  1285. }
  1286. async function getCityList(pid: string) {
  1287. try {
  1288. let res = await personalApi.Country({ pid })
  1289. if (res.code == Config.Code.StatusOK) {
  1290. cityOptions.value = res.data.map((item: any) => ({
  1291. text: local.value === 'en' ? item.enName : item.name,
  1292. value: local.value === 'en' ? item.enName : item.name,
  1293. }))
  1294. cities.value = res.data
  1295. }
  1296. } catch (error: any) {
  1297. }
  1298. }
  1299. async function getLoginInfo() {
  1300. try {
  1301. let res = await personalApi.CustomLoginInfo()
  1302. if (res.code == Config.Code.StatusOK) {
  1303. formData.value = res.data.customInfo
  1304. if (formData.value.addressLines != null && formData.value.addressLines.length) {
  1305. formData.value.addressLines1 = formData.value.addressLines[0]
  1306. formData.value.addressLines2 = formData.value.addressLines[1]
  1307. }
  1308. formData.value.customType = formData.value.customType ? formData.value.customType : 1
  1309. formData.value.IdentityType = 2
  1310. await getCountryList()
  1311. } else {
  1312. uni.showToast({ title: t('Msg.SystemError'), icon: 'none' })
  1313. }
  1314. } catch (error: any) {
  1315. }
  1316. }
  1317. // 获取二维码
  1318. async function getMobileInfo() {
  1319. try {
  1320. let res = await personalApi.CustomFileMobileFiles({}, { responseType: 'arraybuffer' })
  1321. // console.log(res);
  1322. mobile.value = 'data:image/png;base64,' + uni.arrayBufferToBase64(res)
  1323. } catch (error: any) {
  1324. // uni.showToast({ title: error.message , icon: 'none' })
  1325. }
  1326. }
  1327. // 获取上传文件信息
  1328. async function getCustomFileList() {
  1329. try {
  1330. let res = await personalApi.CustomFileList()
  1331. if (res.code == Config.Code.StatusOK) {
  1332. let myData = res.data
  1333. fileListOthers.value = []
  1334. myData.forEach((item: any) => {
  1335. if (item.type == 1) {
  1336. fileListID1.value = item
  1337. } else if (item.type == 2) {
  1338. fileListID2.value = item
  1339. } else if (item.type == 3) {
  1340. fileListAdd1.value = item
  1341. } else if (item.type == 4) {
  1342. fileListAdd2.value = item
  1343. } else if (item.type == 10) {
  1344. fileListOthers.value.push(item)
  1345. }
  1346. })
  1347. actionType()
  1348. } else {
  1349. uni.showToast({ title: res.msg, icon: 'none' })
  1350. flag.value = false
  1351. }
  1352. } catch (error: any) {
  1353. uni.showToast({ title: error.message || t('Msg.SystemError'), icon: 'none' })
  1354. }
  1355. }
  1356. // 请求头
  1357. function actionType() {
  1358. if (fileListID1.value.id) {
  1359. actionID1.value = Config.Host80 + '/custom/file/upload/1/' + fileListID1.value.id
  1360. } else {
  1361. actionID1.value = Config.Host80 + '/custom/file/upload/1'
  1362. }
  1363. if (fileListID2.value.id) {
  1364. actionID2.value = Config.Host80 + '/custom/file/upload/2/' + fileListID2.value.id
  1365. } else {
  1366. actionID2.value = Config.Host80 + '/custom/file/upload/2'
  1367. }
  1368. if (fileListAdd1.value.id) {
  1369. actionAdd1.value = Config.Host80 + '/custom/file/upload/3/' + fileListAdd1.value.id
  1370. } else {
  1371. actionAdd1.value = Config.Host80 + '/custom/file/upload/3'
  1372. }
  1373. if (fileListAdd2.value.id) {
  1374. actionAdd2.value = Config.Host80 + '/custom/file/upload/4/' + fileListAdd2.value.id
  1375. } else {
  1376. actionAdd2.value = Config.Host80 + '/custom/file/upload/4'
  1377. }
  1378. actionOtherAdd.value = Config.Host80 + '/custom/file/upload/10'
  1379. }
  1380. // WebSocket
  1381. function initWebSocket() {
  1382. // 初始化WebSocket
  1383. let token = sessionStorage.getItem("access_token")
  1384. if (typeof WebSocket == 'undefined') {
  1385. uni.showToast({ title: t('Msg.socket'), icon: 'none' })
  1386. } else {
  1387. const wsUrl = HostWs.value + '/webSocket?Access-Token=' + token
  1388. websock.value = new WebSocket(wsUrl)
  1389. websock.value.onmessage = websocketonmessage
  1390. websock.value.onopen = websocketonopen
  1391. websock.value.onerror = websocketonerror
  1392. websock.value.onclose = websocketclose
  1393. }
  1394. }
  1395. function websocketonopen() {
  1396. }
  1397. function websocketonerror() {
  1398. initWebSocket()
  1399. }
  1400. function websocketonmessage(e: any) {
  1401. let data = JSON.parse(e.data)
  1402. if (data.newsType == 1) {
  1403. let myData = JSON.parse(e.data)
  1404. if (myData.type == 1) {
  1405. fileListID1.value = myData
  1406. } else if (myData.type == 2) {
  1407. fileListID2.value = myData
  1408. } else if (myData.type == 3) {
  1409. fileListAdd1.value = myData
  1410. } else if (myData.type == 4) {
  1411. fileListAdd2.value = myData
  1412. } else if (myData.type == 10) {
  1413. if (!fileListOthers.value.length) {
  1414. fileListOthers.value.push(myData)
  1415. } else {
  1416. let flag = true
  1417. fileListOthers.value.forEach((item: any) => {
  1418. if (item.id == myData.id) {
  1419. item = myData
  1420. flag = false
  1421. }
  1422. })
  1423. if (flag) {
  1424. fileListOthers.value.push(myData)
  1425. }
  1426. }
  1427. }
  1428. actionType()
  1429. }
  1430. }
  1431. function websocketclose() {
  1432. }
  1433. // 判断是否为PC端
  1434. function IsPC() {
  1435. let userAgentInfo = navigator.userAgent
  1436. let Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
  1437. let flag = true
  1438. for (let v = 0; v < Agents.length; v++) {
  1439. if (userAgentInfo.indexOf(Agents[v]) > 0) {
  1440. flag = false
  1441. break
  1442. }
  1443. }
  1444. return flag
  1445. }
  1446. // div大小改变重载
  1447. function divInit() {
  1448. // 由于elementResizeDetectorMaker在UniApp中可能不可用,这里简化处理
  1449. const width = window.innerWidth
  1450. if (width <= 1100 && width > 800) {
  1451. divActiveHelf.value = true
  1452. divActiveAll.value = false
  1453. } else if (width <= 800) {
  1454. divActiveAll.value = true
  1455. divActiveHelf.value = false
  1456. } else if (1100 < width) {
  1457. divActiveAll.value = false
  1458. divActiveHelf.value = false
  1459. }
  1460. }
  1461. // 监听表单字段变化
  1462. watch(
  1463. () => formData.value.firstName,
  1464. () => {
  1465. if (localStorage.getItem('lang') == 'cn' && formData.value.firstName && formData.value.lastName) {
  1466. formData.value.nameEn = pinyin(`${formData.value.firstName} ${formData.value.lastName}`)
  1467. pinyin
  1468. }
  1469. },
  1470. )
  1471. watch(
  1472. () => formData.value.lastName,
  1473. () => {
  1474. if (localStorage.getItem('lang') == 'cn' && formData.value.firstName && formData.value.lastName) {
  1475. formData.value.nameEn = pinyin(`${formData.value.firstName} ${formData.value.lastName}`
  1476. )
  1477. }
  1478. },
  1479. )
  1480. // 生命周期
  1481. onMounted(async () => {
  1482. // dialogCheck.value.open()
  1483. divInit()
  1484. await getLoginInfo()
  1485. await getMobileInfo()
  1486. await getCustomFileList()
  1487. // WebSocket
  1488. initWebSocket()
  1489. isPC.value = IsPC()
  1490. })
  1491. // 组件销毁时
  1492. onUnmounted(() => {
  1493. if (websock.value) {
  1494. websock.value.close() // 离开路由之后断开WebSocket连接
  1495. }
  1496. })
  1497. </script>
  1498. <style scoped lang="scss">
  1499. @import "@/uni.scss";
  1500. .form-tab {
  1501. height: px2rpx(100);
  1502. }
  1503. .form-section {
  1504. margin: px2rpx(8) 0;
  1505. }
  1506. .section-title {
  1507. color: #1a1a1a;
  1508. font-family: Roboto;
  1509. font-size: px2rpx(22);
  1510. font-weight: 500;
  1511. margin: px2rpx(10) 0;
  1512. }
  1513. :deep(.file-picker__box) {
  1514. width: px2rpx(200) !important;
  1515. height: px2rpx(150) !important;
  1516. }
  1517. :deep(.uni-file-picker) {
  1518. width: 100%;
  1519. height: 100%;
  1520. }
  1521. .avatar-uploader {
  1522. border: 1px dashed;
  1523. width: px2rpx(200);
  1524. height: px2rpx(150);
  1525. display: flex;
  1526. flex-direction: column;
  1527. align-items: center;
  1528. justify-content: center;
  1529. /*float: left;*/
  1530. //overflow: hidden;
  1531. }
  1532. .file-item {
  1533. border: 1px dashed;
  1534. border-radius: px2rpx(5);
  1535. width: px2rpx(200);
  1536. height: px2rpx(150);
  1537. display: flex;
  1538. justify-content: center;
  1539. align-items: center;
  1540. .icon {
  1541. width: px2rpx(24);
  1542. height: px2rpx(24);
  1543. }
  1544. }
  1545. .avatar {
  1546. width: 100%;
  1547. height: 100%;
  1548. }
  1549. .custom-upload-btn {
  1550. width: px2rpx(200);
  1551. height: px2rpx(150);
  1552. display: flex;
  1553. flex-direction: column;
  1554. align-items: center;
  1555. justify-content: center;
  1556. .plus {
  1557. font-size: px2rpx(24);
  1558. color: #9ca3af;
  1559. }
  1560. }
  1561. .refresh {
  1562. width: 100%;
  1563. height: px2rpx(150);
  1564. display: flex;
  1565. justify-content: center;
  1566. align-items: center;
  1567. image {
  1568. width: px2rpx(28);
  1569. height: px2rpx(28);
  1570. }
  1571. }
  1572. .fileOther {
  1573. :deep(.upload-wrapper .uni-file-picker) {
  1574. display: flex;
  1575. align-items: center;
  1576. justify-content: center;
  1577. }
  1578. :deep(.uni-file-picker__lists) {
  1579. display: none !important;
  1580. }
  1581. }
  1582. .fileList {
  1583. width: 100%;
  1584. box-sizing: border-box;
  1585. display: flex;
  1586. flex-direction: column;
  1587. justify-content: center;
  1588. align-items: center;
  1589. }
  1590. #files {
  1591. :deep(.uni-file-picker__lists) {
  1592. display: none !important;
  1593. }
  1594. :deep(.upload-wrapper .uni-file-picker) {
  1595. display: flex;
  1596. align-items: center;
  1597. justify-content: center;
  1598. }
  1599. .list_upload {
  1600. width: px2rpx(150);
  1601. height: px2rpx(60);
  1602. }
  1603. .file-item {
  1604. //border: none;
  1605. box-sizing: border-box;
  1606. width: px2rpx(150);
  1607. height: px2rpx(60);
  1608. border-radius: 0;
  1609. }
  1610. margin-top: px2rpx(20);
  1611. max-width: px2rpx(600);
  1612. border: 1px dashed;
  1613. display: flex;
  1614. .options {
  1615. flex: 1;
  1616. padding: 8px;
  1617. box-sizing: border-box;
  1618. display: flex;
  1619. justify-content: center;
  1620. align-content: center;
  1621. align-items: center;
  1622. uni-button {
  1623. min-width: px2rpx(100);
  1624. max-height: px2rpx(30);
  1625. padding: 0;
  1626. line-height: px2rpx(30);
  1627. span,
  1628. a {
  1629. display: inline-block;
  1630. height: 100%;
  1631. width: 100%;
  1632. color: var(--color-black);
  1633. }
  1634. }
  1635. }
  1636. }
  1637. .con-box {
  1638. background-color: var(--color-white);
  1639. border-radius: 2px;
  1640. padding: 20px;
  1641. .box {
  1642. width: 100%;
  1643. // height: 190px;
  1644. box-sizing: border-box;
  1645. display: flex;
  1646. justify-content: center;
  1647. align-items: center;
  1648. .mobile {
  1649. width: px2rpx(50);
  1650. height: px2rpx(50);
  1651. margin-right: px2rpx(10);
  1652. }
  1653. .arrow {
  1654. width: px2rpx(30);
  1655. height: px2rpx(30);
  1656. margin-right: px2rpx(10);
  1657. }
  1658. .img_mobile {
  1659. width: 120px;
  1660. height: 120px;
  1661. margin: 10px;
  1662. border: 5px solid;
  1663. background-color: var(--color-gray);
  1664. }
  1665. .icon_refresh {
  1666. width: px2rpx(30);
  1667. height: px2rpx(30);
  1668. margin-right: px2rpx(10);
  1669. }
  1670. }
  1671. }
  1672. .experience {
  1673. display: flex;
  1674. margin: px2rpx(10) 0;
  1675. align-items: center;
  1676. }
  1677. .Trad-experience {
  1678. flex: 1;
  1679. color: #1a1a1a;
  1680. font-size: px2rpx(16);
  1681. }
  1682. .Trad-choose {
  1683. display: flex;
  1684. }
  1685. .descending {
  1686. margin: px2rpx(20) 0;
  1687. padding: px2rpx(20);
  1688. background-color: #f5f5f5;
  1689. border-radius: px2rpx(8);
  1690. }
  1691. .title {
  1692. font-weight: 500;
  1693. margin-bottom: px2rpx(10);
  1694. }
  1695. .des {
  1696. margin: px2rpx(5) 0;
  1697. font-size: px2rpx(14);
  1698. color: #666;
  1699. }
  1700. .dian1 {
  1701. font-size: px2rpx(20);
  1702. margin-right: px2rpx(5);
  1703. }
  1704. .dian {
  1705. margin-right: px2rpx(10);
  1706. }
  1707. .btns {
  1708. margin-top: px2rpx(30);
  1709. }
  1710. .cwg-button {
  1711. display: flex;
  1712. flex-direction: column;
  1713. gap: px2rpx(15);
  1714. &.two-btn {
  1715. flex-direction: row;
  1716. justify-content: space-between;
  1717. u-button {
  1718. flex: 1;
  1719. margin: 0 px2rpx(10);
  1720. &:first-child {
  1721. margin-left: 0;
  1722. }
  1723. &:last-child {
  1724. margin-right: 0;
  1725. }
  1726. }
  1727. }
  1728. }
  1729. .btn-primary {
  1730. height: px2rpx(80);
  1731. font-size: px2rpx(18);
  1732. }
  1733. .prev-btn {
  1734. border-color: #4a6cf7;
  1735. color: #4a6cf7;
  1736. }
  1737. .address-tip {
  1738. width: px2rpx(120);
  1739. font-size: px2rpx(14);
  1740. }
  1741. .crm-title-box {
  1742. display: flex;
  1743. align-items: center;
  1744. margin: px2rpx(20) 0;
  1745. .tit {
  1746. font-size: px2rpx(18);
  1747. font-weight: 500;
  1748. color: var(--color-white);
  1749. }
  1750. .icon-tip {
  1751. margin-left: px2rpx(10);
  1752. font-size: px2rpx(16);
  1753. color: var(--color-white);
  1754. cursor: pointer;
  1755. }
  1756. }
  1757. .popup-content {
  1758. padding: px2rpx(20);
  1759. text-align: center;
  1760. }
  1761. .dia-content {
  1762. padding: px2rpx(30);
  1763. text-align: center;
  1764. .icon {
  1765. margin-bottom: px2rpx(20);
  1766. i {
  1767. font-size: px2rpx(60);
  1768. color: #4a6cf7;
  1769. }
  1770. }
  1771. .des1 {
  1772. font-size: px2rpx(18);
  1773. font-weight: 500;
  1774. margin-bottom: px2rpx(10);
  1775. }
  1776. .des2 {
  1777. font-size: px2rpx(14);
  1778. color: #666;
  1779. margin-bottom: px2rpx(30);
  1780. }
  1781. .dialog-footer {
  1782. display: flex;
  1783. justify-content: space-between;
  1784. margin-top: px2rpx(30);
  1785. uni-button {
  1786. flex: 1;
  1787. margin: 0 px2rpx(10);
  1788. &:first-child {
  1789. margin-left: 0;
  1790. }
  1791. &:last-child {
  1792. margin-right: 0;
  1793. }
  1794. }
  1795. }
  1796. }
  1797. .cwg-upload {
  1798. display: flex;
  1799. flex-direction: column;
  1800. align-items: center;
  1801. justify-content: center;
  1802. padding: px2rpx(40);
  1803. border: 1px dashed #ddd;
  1804. border-radius: px2rpx(8);
  1805. cursor: pointer;
  1806. cwg-icon {
  1807. font-size: px2rpx(40);
  1808. margin-bottom: px2rpx(10);
  1809. color: #999;
  1810. }
  1811. .name {
  1812. font-size: px2rpx(16);
  1813. margin-bottom: px2rpx(5);
  1814. }
  1815. .back {
  1816. font-size: px2rpx(12);
  1817. color: #999;
  1818. }
  1819. }
  1820. </style>