trading-management.vue 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526
  1. <template>
  2. <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
  3. <view class="content-container">
  4. <!-- 动态字段列表 -->
  5. <view class="content-title">
  6. <cwg-header :title="t('Documentary.TundManagement.item11')" />
  7. <view class="content-title-btns">
  8. <view class="btn-primary btn-primary1" @click="getCustomLoginDownLogin()">
  9. <cwg-icon icon="crm-plus" :size="16" color="#fff" />
  10. <text v-t="'Documentary.TundManagement.item12'" />
  11. </view>
  12. </view>
  13. </view>
  14. <uni-loading v-if="accountDataLoading" />
  15. <template v-else>
  16. <view class="field-container" v-if="accountData.length > 0">
  17. <view class="account-l-con" v-for="(item, index) in accountData" :key="index">
  18. <view class="tit">
  19. <view>
  20. <i class="el-icon-success green-icon"></i><text class="tit-tit"
  21. v-t="'Documentary.TundManagement.item13'"></text>
  22. - {{ item.dealLogin || "--" }}
  23. </view>
  24. <view class="caozuo">
  25. <cwg-icon class="cwg-cursor" @click="dialogFllowDele(item)" name="crm-trash-can"
  26. color="#fff" />
  27. <cwg-icon class="cwg-cursor" @click="dialogFllowUpdate(item)" name="cog-outline"
  28. color="#fff" />
  29. </view>
  30. </view>
  31. <view class="account-grid">
  32. <view class="account-grid-item">
  33. <view class="sub" v-t="'Label.TradingAccount'"></view>
  34. <view class="num">{{ item.dealLogin || "--" }}</view>
  35. </view>
  36. <view class="account-grid-item">
  37. <view class="sub" v-t="'Label.PlatformType'"></view>
  38. <view class="num">{{ item.dealPlatform || "--" }}</view>
  39. </view>
  40. <view class="account-grid-item">
  41. <view class="sub" v-t="'Label.AccountType'"></view>
  42. <view class="num">
  43. <text>{{ groupTypeName(item.dealLoginType) }}</text>
  44. </view>
  45. </view>
  46. <view class="account-grid-item">
  47. <view class="sub" v-t="'Label.Leverage'"></view>
  48. <view class="num">
  49. <text v-if="item.dealLeverage">1:{{ item.dealLeverage }}</text>
  50. <text v-else>{{ "--" }}</text>
  51. </view>
  52. </view>
  53. <view class="account-grid-item">
  54. <view class="sub" v-t="'Label.Balance'"></view>
  55. <view class="num">
  56. {{ numberFormat(item.dealBalance || 0) }}
  57. </view>
  58. </view>
  59. <view class="account-grid-item">
  60. <view class="sub" v-t="'Label.Equity'"></view>
  61. <view class="num">{{ numberFormat(item.dealEquity || 0) }}</view>
  62. </view>
  63. <view class="account-grid-item">
  64. <view class="sub" v-t="'Documentary.TundManagement.item14'"></view>
  65. <view class="num">{{ item.settlementCycle || "--" }}</view>
  66. </view>
  67. <view class="account-grid-item">
  68. <view class="sub" v-t="'Documentary.TundManagement.item15'"></view>
  69. <view class="num">
  70. <text v-if="item.distributionType == 1"
  71. v-t="'Documentary.TundManagement.item59'"></text>
  72. </view>
  73. </view>
  74. <view class="account-grid-item">
  75. <view class="sub" v-t="'Documentary.TundManagement.item16'"></view>
  76. <view class="num">{{ item.distributionRatio || "0" }}%</view>
  77. </view>
  78. </view>
  79. </view>
  80. </view>
  81. <cwg-empty-state v-if="accountData.length == 0" />
  82. </template>
  83. </view>
  84. <!-- 删除信号源 -->
  85. <cwg-popup v-model:visible="dialogFllowDelete" type="center" :mask-click="false" :show-footers="true"
  86. :title="t('Documentary.TundManagement.item28')">
  87. <view class="dia-content">
  88. <view class="fllow-title delete-title">
  89. <text class="title">{{ t('Documentary.TundManagement.item29') }}</text>
  90. </view>
  91. <view class="delete-grid">
  92. <view class="delete-row">
  93. <view class="delete-item">
  94. <text class="delete-label">{{ t('Documentary.tradingCenter.item29') }}</text>
  95. <text class="delete-value">{{ dialogFllowDataDelete.dealLogin || '--' }}</text>
  96. </view>
  97. <view class="delete-item">
  98. <text class="delete-label">{{ t('Documentary.console.item3') }}</text>
  99. <text class="delete-value">{{ dialogFllowDataDelete.dealPlatform || '--' }}</text>
  100. </view>
  101. </view>
  102. <view class="delete-row">
  103. <view class="delete-item">
  104. <text class="delete-label">{{ t('Documentary.console.item7') }}</text>
  105. <text class="delete-value">{{ numberFormat(dialogFllowDataDelete.dealBalance || 0) }}</text>
  106. </view>
  107. <view class="delete-item">
  108. <text class="delete-label">{{ t('Label.AccountType') }}</text>
  109. <text class="delete-value">
  110. <text> {{ groupTypeName(dialogFllowDataDelete.dealLoginType) }}</text>
  111. </text>
  112. </view>
  113. </view>
  114. <view class="delete-row">
  115. <view class="delete-item">
  116. <text class="delete-label">{{ t('Documentary.console.item6') }}</text>
  117. <text class="delete-value">{{ numberFormat(dialogFllowDataDelete.dealEquity) }}</text>
  118. </view>
  119. <view class="delete-item">
  120. <text class="delete-label">{{ t('Documentary.tradingCenter.item30') }}</text>
  121. <text class="delete-value">
  122. <text v-if="dialogFllowDataDelete.distributionType == 1"
  123. v-t="'Documentary.TundManagement.item59'"></text>
  124. </text>
  125. </view>
  126. </view>
  127. <view class="delete-row">
  128. <view class="delete-item">
  129. <text class="delete-label">{{ t('Label.Credit') }}</text>
  130. <text class="delete-value">{{ numberFormat(dialogFllowDataDelete.dealCredit || 0) }}</text>
  131. </view>
  132. <view class="delete-item">
  133. <text class="delete-label">{{ t('Documentary.tradingCenter.item31') }}</text>
  134. <text class="delete-value">{{ dialogFllowDataDelete.distributionRatio || '0' }}%</text>
  135. </view>
  136. </view>
  137. <view class="delete-row">
  138. <view class="delete-item">
  139. <text class="delete-label">{{ t('Label.Leverage') }}</text>
  140. <text class="delete-value">1:{{ dialogFllowDataDelete.dealLeverage || '0' }}</text>
  141. </view>
  142. <view class="delete-item">
  143. <text class="delete-label">{{ t('Documentary.tradingCenter.item32') }}</text>
  144. <text class="delete-value">{{ dialogFllowDataDelete.settlementCycle || '--' }}</text>
  145. </view>
  146. </view>
  147. </view>
  148. <view class="delete-tip">
  149. <text v-t="'Documentary.TundManagement.item30'"></text>
  150. </view>
  151. </view>
  152. <template #footer>
  153. <button @click="FllowDeleCancel">{{ t('Btn.Cancel') }}</button>
  154. <button type="primary" @click="FllowDele">{{ t('Btn.Confirm') }}</button>
  155. </template>
  156. </cwg-popup>
  157. <!-- 信号源设置 -->
  158. <cwg-popup v-model:visible="dialogFllow" type="center" :mask-click="false" :show-footers="true"
  159. :title="t('Documentary.TundManagement.item31')" width="650px">
  160. <uni-forms ref="formRef" :model="dialogFllowData" :rules="rules" label-position="top">
  161. <!-- 名片信息 -->
  162. <view class="dia-content">
  163. <!-- 名片信息 -->
  164. <view class="fllow-title">
  165. <text class="title">{{ t('Documentary.tradingCenter.item126') }}</text>
  166. </view>
  167. <view class="form-item">
  168. <uni-forms-item name="nickname" :label="t('Documentary.console.item20')">
  169. <uni-easyinput v-model="dialogFllowData.nickname" :placeholder="t('placeholder.input')"
  170. @blur="validateAmount" />
  171. </uni-forms-item>
  172. </view>
  173. <view class="form-row">
  174. <view class="form-col">
  175. <view class="form-item">
  176. <uni-forms-item name="personalSignature" :label="t('Documentary.console.item21')">
  177. <uni-easyinput v-model="dialogFllowData.personalSignature"
  178. :placeholder="t('placeholder.input')" type="textarea"
  179. @input="filterChineseEnglishOnlyForApply('personalSignature', $event, 1)" />
  180. </uni-forms-item>
  181. </view>
  182. </view>
  183. <view class="form-col">
  184. <view class="form-item">
  185. <uni-forms-item name="traderStrategy" :label="t('Documentary.console.item22')">
  186. <uni-easyinput v-model="dialogFllowData.traderStrategy"
  187. :placeholder="t('placeholder.input')" type="textarea"
  188. @input="filterChineseEnglishOnlyForApply('traderStrategy', $event, 1)" />
  189. </uni-forms-item>
  190. </view>
  191. </view>
  192. </view>
  193. <view class="tip-red">
  194. <text v-t="'Documentary.console.item37'"></text>
  195. </view>
  196. <!-- 账户信息 -->
  197. <view class="fllow-title">
  198. <text class="title">{{ t('Documentary.TundManagement.item29') }}</text>
  199. </view>
  200. <view class="delete-grid">
  201. <view class="delete-row">
  202. <view class="delete-item">
  203. <text class="delete-label">{{ t('Documentary.console.item3') }}</text>
  204. <text class="delete-value">{{ dialogFllowData.dealPlatform || '--' }}</text>
  205. </view>
  206. <view class="delete-item">
  207. <text class="delete-label">{{ t('Documentary.tradingCenter.item29') }}</text>
  208. <text class="delete-value">{{ dialogFllowData.dealLogin || '--' }}</text>
  209. </view>
  210. </view>
  211. <view class="delete-row">
  212. <view class="delete-item">
  213. <text class="delete-label">{{ t('Label.AccountType') }}</text>
  214. <text class="delete-value">
  215. <text> {{ groupTypeName(dialogFllowData.dealLoginType) }}</text>
  216. </text>
  217. </view>
  218. <view class="delete-item">
  219. <text class="delete-label">{{ t('Label.Leverage') }}</text>
  220. <text class="delete-value">1:{{ dialogFllowData.dealLeverage || '0' }}</text>
  221. </view>
  222. </view>
  223. </view>
  224. <!-- 展示设置 -->
  225. <view class="fllow-title">
  226. <text class="title">{{ t('Documentary.TundManagement.item32') }}</text>
  227. </view>
  228. <view class="form-row">
  229. <view class="form-col">
  230. <view class="form-item">
  231. <uni-forms-item name="historyShow" :label="t('Documentary.TundManagement.item34')">
  232. <cwg-combox v-model:value="dialogFllowData.historyShow" :clearable="false"
  233. :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
  234. :placeholder="t('placeholder.choose')" />
  235. </uni-forms-item>
  236. </view>
  237. </view>
  238. <view class="form-col">
  239. <view class="form-item">
  240. <uni-forms-item name="historyTime" :label="t('Documentary.TundManagement.item35')">
  241. <uni-datetime-picker v-model="dialogFllowData.historyTime" type="date"
  242. :placeholder="t('placeholder.input')" @change="handleDateChange" />
  243. <!-- <uni-date-picker type="date" v-model="dialogFllowData.historyTime" /> -->
  244. </uni-forms-item>
  245. </view>
  246. </view>
  247. </view>
  248. <view class="form-item">
  249. <uni-forms-item name="introduceShow" :label="t('Documentary.TundManagement.item36')">
  250. <cwg-combox v-model:value="dialogFllowData.historyShow" :clearable="false"
  251. :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
  252. :placeholder="t('placeholder.choose')" />
  253. </uni-forms-item>
  254. </view>
  255. <!-- 分润设置 -->
  256. <view class="fllow-title">
  257. <text class="title">{{ t('Documentary.TundManagement.item33') }}</text>
  258. </view>
  259. <!-- 已有订阅 → 只读 -->
  260. <view v-if="dialogFllowData.followCount" class="delete-grid">
  261. <view class="delete-row">
  262. <view class="delete-item">
  263. <text class="delete-label">{{ t('Documentary.TundManagement.item38') }}</text>
  264. <text class="delete-value">{{ dialogFllowData.distributionType || '--' }}</text>
  265. </view>
  266. <view class="delete-item">
  267. <text class="delete-label">{{ t('Documentary.tradingCenter.item32') }}</text>
  268. <text class="delete-value">{{ dialogFllowData.settlementCycle || '--' }}</text>
  269. </view>
  270. </view>
  271. <view class="delete-row">
  272. <view class="delete-item">
  273. <text class="delete-label">{{ t('Documentary.TundManagement.item39') }}</text>
  274. <text class="delete-value">{{ dialogFllowData.distributionRatio || '--' }}</text>
  275. </view>
  276. <view class="delete-item">
  277. <text class="delete-label">{{ t('Documentary.tradingCenter.item32') }}</text>
  278. <text class="delete-value">{{ dialogFllowData.settlementCycle || '--' }}</text>
  279. </view>
  280. </view>
  281. </view>
  282. <!-- 无订阅 → 可编辑 -->
  283. <view v-else class="form-row">
  284. <view class="form-col">
  285. <view class="form-item">
  286. <uni-forms-item name="distributionType" :label="t('Documentary.TundManagement.item38')">
  287. <cwg-combox v-model:value="dialogFllowData.distributionType" :clearable="false"
  288. :options="[{ text: t('Documentary.TundManagement.item59'), value: 1 }]"
  289. :placeholder="t('placeholder.choose')" />
  290. </uni-forms-item>
  291. </view>
  292. </view>
  293. <view class="form-col">
  294. <view class="form-item">
  295. <uni-forms-item name="distributionRatio"
  296. :label="t('Documentary.TundManagement.item39') + '(%)'">
  297. <uni-easyinput v-model="dialogFllowData.distributionRatio"
  298. :placeholder="t('placeholder.input')" />
  299. </uni-forms-item>
  300. </view>
  301. </view>
  302. <view class="form-col">
  303. <view class="form-item">
  304. <uni-forms-item name="settlementCycle" :label="t('Documentary.tradingCenter.item32')">
  305. <cwg-combox v-model:value="dialogFllowData.settlementCycle" :clearable="false"
  306. :options="[{ text: 7, value: 7 }, { text: 15, value: 15 }, { text: 30, value: 30 }]"
  307. :placeholder="t('placeholder.choose')" />
  308. </uni-forms-item>
  309. </view>
  310. </view>
  311. </view>
  312. </view>
  313. </uni-forms>
  314. <template #footer>
  315. <button @click="FllowUpdateCancel">{{ t('Btn.Cancel') }}</button>
  316. <button type="primary" @click="FllowUpdate">{{ t('Btn.Confirm') }}</button>
  317. </template>
  318. </cwg-popup>
  319. <!--申请成为信号源-->
  320. <cwg-popup v-model:visible="dialogFllowApply" type="center" :mask-click="false" :show-footers="true"
  321. :title="t('Documentary.TundManagement.item41')" width="650px">
  322. <uni-forms ref="applyRef" :model="dialogFllowDataApply" :rules="rules" label-position="top"
  323. label-width="200px">
  324. <!-- 名片信息 -->
  325. <view class="dia-content">
  326. <!-- 名片信息 -->
  327. <view class="fllow-title">
  328. <text class="title">{{ t('Documentary.tradingCenter.item126') }}</text>
  329. </view>
  330. <view class="form-item">
  331. <uni-forms-item name="nickname" :label="t('Documentary.console.item20')">
  332. <uni-easyinput v-model="dialogFllowDataApply.nickname" :placeholder="t('placeholder.input')"
  333. @blur="validateAmount" />
  334. </uni-forms-item>
  335. </view>
  336. <view class="form-row">
  337. <view class="form-col">
  338. <view class="form-item">
  339. <uni-forms-item name="personalSignature" :label="t('Documentary.console.item21')">
  340. <uni-easyinput v-model="dialogFllowDataApply.personalSignature"
  341. :placeholder="t('placeholder.input')" type="textarea"
  342. @input="filterChineseEnglishOnlyForApply('personalSignature', $event, 2)" />
  343. </uni-forms-item>
  344. </view>
  345. </view>
  346. <view class="form-col">
  347. <view class="form-item">
  348. <uni-forms-item name="traderStrategy" :label="t('Documentary.console.item22')">
  349. <uni-easyinput v-model="dialogFllowDataApply.traderStrategy"
  350. :placeholder="t('placeholder.input')" type="textarea"
  351. @input="filterChineseEnglishOnlyForApply('traderStrategy', $event, 2)" />
  352. </uni-forms-item>
  353. </view>
  354. </view>
  355. </view>
  356. <view class="tip-red">
  357. <text v-t="'Documentary.console.item37'"></text>
  358. </view>
  359. <!-- 账户信息 -->
  360. <view class="fllow-title">
  361. <text class="title">{{ t('Documentary.TundManagement.item29') }}{{ fundRequirementText }}</text>
  362. </view>
  363. <view class="form-row">
  364. <view class="form-col">
  365. <view class="form-item">
  366. <uni-forms-item name="dealLogin" :label="t('Label.TradingAccount')">
  367. <cwg-combox v-model:value="dialogFllowDataApply.dealLogin" :clearable="false"
  368. :options="loginOptions" :placeholder="t('placeholder.choose')"
  369. @change="selectLoginDeal" />
  370. </uni-forms-item>
  371. </view>
  372. </view>
  373. <view class="form-col">
  374. <view class="form-item">
  375. <uni-forms-item name="platform" :label="t('Label.PlatformType')">
  376. <cwg-combox v-model:value="dialogFllowDataApply.platform" :clearable="false"
  377. :options="[{ text: 'MT4', value: 'MT4' }, { text: 'MT5', value: 'MT5' }]"
  378. :placeholder="t('placeholder.choose')" :disabled="true" />
  379. </uni-forms-item>
  380. </view>
  381. </view>
  382. </view>
  383. <view class="form-row">
  384. <view class="form-col">
  385. <view class="form-item">
  386. <uni-forms-item name="loginType" :label="t('Label.AccountType')">
  387. <cwg-combox v-model:value="dialogFllowDataApply.loginType" :clearable="false"
  388. :options="[
  389. { text: t('AccountType.ClassicAccount'), value: 1 },
  390. { text: t('AccountType.SeniorAccount'), value: 2 },
  391. { text: t('AccountType.SpeedAccount'), value: 5 },
  392. { text: t('AccountType.SpeedAccount'), value: 6 },
  393. { text: t('AccountType.StandardAccount'), value: 7 },
  394. { text: t('AccountType.CentAccount'), value: 8 }
  395. ]" :placeholder="t('placeholder.choose')" :disabled="true" />
  396. </uni-forms-item>
  397. </view>
  398. </view>
  399. <view class="form-col">
  400. <view class="form-item">
  401. <uni-forms-item name="leverage" :label="t('Label.Leverage')">
  402. <uni-easyinput v-model="dialogFllowDataApply.leverage"
  403. :placeholder="t('placeholder.input')" :disabled="true" />
  404. </uni-forms-item>
  405. </view>
  406. </view>
  407. </view>
  408. <!-- 展示设置 -->
  409. <view class="fllow-title">
  410. <text class="title">{{ t('Documentary.TundManagement.item32') }}</text>
  411. </view>
  412. <view class="form-row">
  413. <view class="form-col">
  414. <view class="form-item">
  415. <uni-forms-item name="historyShow" :label="t('Documentary.TundManagement.item34')">
  416. <cwg-combox v-model:value="dialogFllowDataApply.historyShow" :clearable="false"
  417. :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
  418. :placeholder="t('placeholder.choose')" />
  419. </uni-forms-item>
  420. </view>
  421. </view>
  422. <view class="form-col">
  423. <view class="form-item">
  424. <uni-forms-item name="historyTime" :label="t('Documentary.TundManagement.item35')">
  425. <uni-datetime-picker v-model="dialogFllowDataApply.historyTime" type="date"
  426. :placeholder="t('Documentary.TundManagement.item37')" />
  427. </uni-forms-item>
  428. </view>
  429. </view>
  430. </view>
  431. <view class="form-item">
  432. <uni-forms-item name="introduceShow" :label="t('Documentary.TundManagement.item36')">
  433. <cwg-combox v-model:value="dialogFllowDataApply.introduceShow" :clearable="false"
  434. :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
  435. :placeholder="t('placeholder.choose')" />
  436. </uni-forms-item>
  437. </view>
  438. <!-- 分润设置 -->
  439. <view class="fllow-title">
  440. <text class="title">{{ t('Documentary.TundManagement.item33') }}</text>
  441. </view>
  442. <view class="form-row">
  443. <view class="form-col">
  444. <view class="form-item">
  445. <uni-forms-item name="distributionType" :label="t('Documentary.TundManagement.item38')">
  446. <cwg-combox v-model:value="dialogFllowDataApply.distributionType" :clearable="false"
  447. :options="[{ text: t('Documentary.TundManagement.item59'), value: 1 }]"
  448. :placeholder="t('placeholder.choose')" />
  449. </uni-forms-item>
  450. </view>
  451. </view>
  452. <view class="form-col">
  453. <view class="form-item">
  454. <uni-forms-item name="distributionRatio"
  455. :label="t('Documentary.TundManagement.item39') + '(%)'">
  456. <uni-easyinput v-model="dialogFllowDataApply.distributionRatio"
  457. :placeholder="t('placeholder.input')" />
  458. </uni-forms-item>
  459. </view>
  460. </view>
  461. <view class="form-col">
  462. <view class="form-item">
  463. <uni-forms-item name="settlementCycle" :label="t('Documentary.tradingCenter.item32')">
  464. <cwg-combox v-model:value="dialogFllowDataApply.settlementCycle" :clearable="false"
  465. :options="[{ text: 7, value: 7 }, { text: 15, value: 15 }, { text: 30, value: 30 }]"
  466. :placeholder="t('placeholder.choose')" />
  467. </uni-forms-item>
  468. </view>
  469. </view>
  470. </view>
  471. <view class="form-item agree">
  472. <uni-forms-item name="agree">
  473. <checkbox-group :value="dialogFllowDataApply.agree ? ['1'] : []" @change="onAgreeChange">
  474. <label class="checkbox-agree">
  475. <checkbox value="1" :checked="dialogFllowDataApply.agree" />
  476. <text class="agree-text">
  477. {{ t('Documentary.TundManagement.item42') }}
  478. <cwg-link style="text-decoration: underline;" class="a"
  479. :url="isZh ? 'pdf/CopyTradeUserAgreementcn.pdf' : 'pdf/CopyTradeUserAgreement.pdf'"
  480. target="_blank" title="Documentary.TundManagement.item43" />
  481. {{ t('Documentary.TundManagement.item42_2') }}
  482. </text>
  483. </label>
  484. </checkbox-group>
  485. </uni-forms-item>
  486. </view>
  487. </view>
  488. </uni-forms>
  489. <template #footer>
  490. <button @click="ApplyFllowCancel">{{ t('Btn.Cancel') }}</button>
  491. <button type="primary" @click="ApplyFllow">{{ t('Btn.Confirm') }}</button>
  492. </template>
  493. </cwg-popup>
  494. </cwg-page-wrapper>
  495. </template>
  496. <script setup lang="ts">
  497. import { computed, ref, nextTick, onMounted, reactive, watch } from 'vue';
  498. import { isAfterJuly28 } from '@/utils/dateUtils'
  499. import { useI18n } from 'vue-i18n';
  500. const { t, locale } = useI18n();
  501. import { documentaryApi } from '@/service/documentary';
  502. import useUserStore from "@/stores/use-user-store";
  503. const userStore = useUserStore();
  504. const userInfo = computed(() => userStore.userInfo);
  505. import { useFilters } from '@/composables/useFilters'
  506. const { numberFormat, numberDecimal } = useFilters()
  507. const isZh = computed(() => ['cn', 'zh', 'zhHant'].includes(locale.value));
  508. const formRef = ref(null)
  509. const rules = {
  510. password: {
  511. rules: [
  512. {
  513. required: true,
  514. validateFunction: (rule, value, data, callback) => {
  515. if (Config.Pattern.Password.test(value)) {
  516. callback()
  517. } else {
  518. callback(t('vaildate.password.format'))
  519. }
  520. return true
  521. }
  522. }
  523. ]
  524. },
  525. agree: {
  526. rules: [
  527. {
  528. validateFunction: (rule, value, data, callback) => {
  529. if (value) {
  530. callback()
  531. } else {
  532. callback(t('vaildate.agree.empty'))
  533. }
  534. return true
  535. }
  536. }
  537. ]
  538. },
  539. platform: {
  540. rules: [
  541. {
  542. required: true,
  543. errorMessage: t('vaildate.select.empty')
  544. }
  545. ]
  546. },
  547. currency: {
  548. rules: [
  549. {
  550. required: true,
  551. errorMessage: t('vaildate.select.empty')
  552. }
  553. ]
  554. },
  555. leverage: {
  556. rules: [
  557. {
  558. required: true,
  559. errorMessage: t('vaildate.select.empty')
  560. }
  561. ]
  562. },
  563. loginType: {
  564. rules: [
  565. {
  566. required: true,
  567. errorMessage: t('vaildate.select.empty')
  568. }
  569. ]
  570. },
  571. dealLogin: {
  572. rules: [
  573. {
  574. required: true,
  575. errorMessage: t('vaildate.select.empty')
  576. }
  577. ]
  578. },
  579. distributionType: {
  580. rules: [
  581. {
  582. required: true,
  583. errorMessage: t('vaildate.select.empty')
  584. }
  585. ]
  586. },
  587. distributionRatio: {
  588. rules: [
  589. {
  590. required: true,
  591. errorMessage: t('vaildate.input.empty')
  592. },
  593. {
  594. validateFunction: (rule, value, data, callback) => {
  595. if (value >= 0 && value <= 50) {
  596. callback()
  597. } else {
  598. callback('0-50')
  599. }
  600. return true
  601. }
  602. }
  603. ]
  604. },
  605. settlementCycle: {
  606. rules: [
  607. {
  608. required: true,
  609. errorMessage: t('vaildate.input.empty')
  610. }
  611. ]
  612. },
  613. historyShow: {
  614. rules: [
  615. {
  616. required: true,
  617. errorMessage: t('vaildate.select.empty')
  618. }
  619. ]
  620. },
  621. historyTime: {
  622. rules: [
  623. {
  624. required: true,
  625. errorMessage: t('vaildate.select.empty')
  626. }
  627. ]
  628. },
  629. introduceShow: {
  630. rules: [
  631. {
  632. required: true,
  633. errorMessage: t('vaildate.select.empty')
  634. }
  635. ]
  636. },
  637. protectAmount: {
  638. rules: [
  639. {
  640. required: true,
  641. errorMessage: t('vaildate.input.empty')
  642. }
  643. ]
  644. },
  645. protectRatio: {
  646. rules: [
  647. {
  648. required: true,
  649. errorMessage: t('vaildate.input.empty')
  650. }
  651. ]
  652. },
  653. nickname: {
  654. rules: [
  655. {
  656. required: true,
  657. errorMessage: t('vaildate.input.empty')
  658. },
  659. {
  660. validateFunction: (rule, value, data, callback) => {
  661. if (value && /^[0-9a-zA-Z]{1,24}$/.test(value)) {
  662. callback()
  663. } else {
  664. callback(t('Msg.nickname'))
  665. }
  666. return true
  667. }
  668. }
  669. ]
  670. },
  671. personalSignature: {
  672. rules: [
  673. {
  674. required: true,
  675. errorMessage: t('vaildate.input.empty')
  676. },
  677. {
  678. validateFunction: (rule, value, data, callback) => {
  679. if (!value || /^[\u4e00-\u9fa5a-zA-Z\s]*$/.test(value)) {
  680. callback()
  681. } else {
  682. callback(t('Documentary.console.item38'))
  683. }
  684. return true
  685. }
  686. }
  687. ]
  688. },
  689. traderStrategy: {
  690. rules: [
  691. {
  692. required: true,
  693. errorMessage: t('vaildate.input.empty')
  694. },
  695. {
  696. validateFunction: (rule, value, data, callback) => {
  697. if (!value || /^[\u4e00-\u9fa5a-zA-Z\s]*$/.test(value)) {
  698. callback()
  699. } else {
  700. callback(t('Documentary.console.item38'))
  701. }
  702. return true
  703. }
  704. }
  705. ]
  706. },
  707. followType: {
  708. rules: [
  709. {
  710. required: true,
  711. errorMessage: t('vaildate.select.empty')
  712. }
  713. ]
  714. },
  715. volume: {
  716. rules: [
  717. {
  718. required: true,
  719. errorMessage: t('vaildate.input.empty')
  720. }
  721. ]
  722. },
  723. ratio: {
  724. rules: [
  725. {
  726. required: true,
  727. errorMessage: t('vaildate.input.empty')
  728. }
  729. ]
  730. }
  731. }
  732. const filterChineseEnglishOnlyForApply = (field, value, type) => {
  733. // 只保留中文、英文和空格
  734. const filtered = value.replace(/[^\u4e00-\u9fa5a-zA-Z\s]/g, '');
  735. // 去掉前后空格,如果没有正文内容(全是空格)就设置为空字符串
  736. const trimmed = filtered.trim();
  737. if (type == 1) {
  738. nextTick(() => {
  739. dialogFllowData.value[field] = trimmed;
  740. })
  741. } else {
  742. nextTick(() => {
  743. dialogFllowDataApply[field] = trimmed;
  744. })
  745. }
  746. }
  747. //获取客户跟单账户的下拉列表
  748. const isSubscribeLoading = ref(false)
  749. const SubscribeDownData = ref([])
  750. const getSubscribeLoginDown = async () => {
  751. isSubscribeLoading.value = true
  752. let res = await documentaryApi.followDealSubscribeLoginList({
  753. platform: "",
  754. page: null,
  755. });
  756. if (res.code == 200) {
  757. SubscribeDownData.value = res.data?.map(item => ({
  758. text: t('Documentary.console.item28') + '-' + item.dealLogin || '--',
  759. value: item.dealLogin
  760. })) || []
  761. } else {
  762. uni.showToast({
  763. title: res.msg,
  764. icon: 'none'
  765. })
  766. }
  767. isSubscribeLoading.value = false
  768. }
  769. const onAgreeChange = (e) => {
  770. dialogFllowDataApply.agree = e.detail.value.length > 0
  771. }
  772. // 单位类型
  773. function groupCurrency(type) {
  774. const map = { GBP: ': £', USD: ': $', EUR: ': €', USC: ': ¢' }
  775. return map[type] || ': $'
  776. }
  777. // 账户类型
  778. function groupTypeName(type) {
  779. const typeMap = {
  780. '1': t('AccountType.ClassicAccount'),
  781. '2': t('AccountType.SeniorAccount'),
  782. '3': isAfterJuly28() ? '--' : t('AccountType.AgencyAccount'),
  783. '5': t('AccountType.SpeedAccount'),
  784. '6': t('AccountType.SpeedAccount'),
  785. '7': t('AccountType.StandardAccount'),
  786. '8': t('AccountType.CentAccount')
  787. }
  788. return typeMap[type] || ''
  789. }
  790. const loginOptions = computed(() => loginOptionsLogin.value.map(item => ({
  791. text: `${item.login} - ${groupTypeName(item.type)} - ${t('Custom.Deposit.AvailableBalance')}${groupCurrency(item.currency)}${item.balance}`,
  792. value: item.login,
  793. disable: item.balance < 200
  794. })))
  795. const selectLoginDeal = () => {
  796. loginOptionsLogin.value.forEach((item) => {
  797. if (item.login == dialogFllowDataApply.dealLogin) {
  798. dialogFllowDataApply.leverage = "1:" + item.leverage;
  799. dialogFllowDataApply.loginType = item.type;
  800. dialogFllowDataApply.platform = item.platform;
  801. }
  802. });
  803. }
  804. const applyRef = ref(null)
  805. const dialogFllowDataApply = reactive({
  806. dealLogin: '',
  807. leverage: '',
  808. loginType: '',
  809. platform: '',
  810. currency: '',
  811. leverageStatus: '',
  812. withdrawStatus: '',
  813. depositStatus: '',
  814. accountStatus: '',
  815. status: '',
  816. note: '',
  817. followType: '',
  818. volume: '',
  819. ratio: '',
  820. traderStrategy: '',
  821. personalSignature: '',
  822. nickname: '',
  823. protectAmount: '',
  824. protectRatio: '',
  825. introduceShow: '',
  826. historyShow: '',
  827. historyTime: '',
  828. settlementCycle: '',
  829. distributionType: '',
  830. distributionRatio: '',
  831. withdrawCurrency: '',
  832. withdrawAmount: '',
  833. depositCurrency: '',
  834. depositAmount: '',
  835. withdrawLogin: '',
  836. depositLogin: '',
  837. addTime: '',
  838. title: '',
  839. })
  840. const loginOptionsLogin = ref([])
  841. const dialogFllowApply = ref(false)
  842. //获取申请信号源交易账户下拉
  843. const getCustomLoginDownLogin = async () => {
  844. if (flag.value) {
  845. return;
  846. } else {
  847. flag.value = true;
  848. }
  849. let res = await documentaryApi.CustomDropdownData({
  850. platform: "",
  851. });
  852. if (res.code == 200) {
  853. loginOptionsLogin.value = res.data;
  854. dialogFllowApply.value = true;
  855. } else {
  856. uni.showToast({
  857. title: res.msg,
  858. icon: 'none'
  859. });
  860. }
  861. flag.value = false;
  862. }
  863. watch(() => dialogFllowDataApply.dealLogin, (newVal, oldVal) => {
  864. if (newVal !== oldVal) {
  865. selectLoginDeal();
  866. }
  867. })
  868. //申请信号源
  869. const ApplyFllow = async () => {
  870. try {
  871. await applyRef.value.validate()
  872. if (flag.value) {
  873. return;
  874. } else {
  875. flag.value = true;
  876. }
  877. let res = await documentaryApi.followDealApply({
  878. ...dialogFllowDataApply,
  879. });
  880. if (res.code == 200) {
  881. uni.showToast({
  882. title: t("Msg.Success"),
  883. icon: 'none'
  884. });
  885. ApplyFllowCancel();
  886. getDealLogin();
  887. flag.value = false;
  888. } else {
  889. uni.showToast({
  890. title: res.msg,
  891. icon: 'none'
  892. });
  893. flag.value = false;
  894. }
  895. } catch (error) {
  896. return false;
  897. } finally {
  898. flag.value = false;
  899. }
  900. }
  901. const ApplyFllowCancel = () => {
  902. applyRef.value &&
  903. applyRef.value.clearValidate();
  904. dialogFllowApply.value = false;
  905. }
  906. //获取客户信号源账户
  907. const accountDataLoading = ref(false)
  908. const accountData = ref([])
  909. const accountPager = ref({
  910. current: 1,
  911. row: 10,
  912. rowTotal: 0,
  913. pageTotal: 0
  914. })
  915. const getDealLogin = async () => {
  916. accountDataLoading.value = true;
  917. let res = await documentaryApi.followDealList({
  918. platform: null,
  919. status: 2,
  920. page: {
  921. current: accountPager.value.current,
  922. row: accountPager.value.row,
  923. },
  924. });
  925. if (res.code == 200) {
  926. accountData.value = res.data || []
  927. accountPager.value.rowTotal = res.page.rowTotal;
  928. accountPager.value.pageTotal = res.page.pageTotal;
  929. } else {
  930. uni.showToast({
  931. title: res.msg,
  932. icon: 'none'
  933. });
  934. }
  935. accountDataLoading.value = false;
  936. }
  937. //修改信号源
  938. const dialogFllowData = ref({})
  939. const dialogFllow = ref(false)
  940. const dialogFllowDataDelete = ref({})
  941. const dialogFllowDelete = ref(false)
  942. const flag = ref(false)
  943. const dialogFllowUpdate = (item) => {
  944. dialogFllowData.value = item;
  945. dialogFllow.value = true;
  946. }
  947. const FllowUpdate = async () => {
  948. try {
  949. await formRef.value.validate()
  950. if (flag.value) {
  951. return;
  952. } else {
  953. flag.value = true;
  954. }
  955. let res = await documentaryApi.followDealUpdate({
  956. ...dialogFllowData.value,
  957. });
  958. if (res.code == 200) {
  959. uni.showToast({
  960. title: t("Msg.Success"),
  961. icon: 'none'
  962. });
  963. FllowUpdateCancel();
  964. tableRef.value.refreshTable()
  965. getDealLogin();
  966. getSubscribeLoginDown()
  967. flag.value = false;
  968. } else {
  969. uni.showToast({
  970. title: res.msg,
  971. icon: 'none'
  972. });
  973. flag.value = false;
  974. }
  975. } catch (error) {
  976. flag.value = false;
  977. }
  978. }
  979. const FllowUpdateCancel = () => {
  980. formRef.value && formRef.value.clearValidate();
  981. dialogFllow.value = false;
  982. }
  983. //删除信号源
  984. const dialogFllowDele = (item) => {
  985. dialogFllowDataDelete.value = item;
  986. dialogFllowDelete.value = true;
  987. }
  988. const FllowDele = async () => {
  989. if (flag.value) {
  990. return;
  991. } else {
  992. flag.value = true;
  993. }
  994. let res = await documentaryApi.followDealDelete({
  995. ids: [dialogFllowDataDelete.value.id],
  996. });
  997. if (res.code == 200) {
  998. uni.showToast({
  999. title: t("Msg.Success"),
  1000. icon: 'none'
  1001. });
  1002. FllowDeleCancel();
  1003. tableRef.value.refreshTable()
  1004. getDealLogin();
  1005. getSubscribeLoginDown()
  1006. flag.value = false;
  1007. } else {
  1008. uni.showToast({
  1009. title: res.msg,
  1010. icon: 'none'
  1011. });
  1012. flag.value = false;
  1013. }
  1014. }
  1015. const FllowDeleCancel = () => {
  1016. dialogFllowDelete.value = false;
  1017. }
  1018. const listApi = ref(null)
  1019. onMounted(() => {
  1020. getDealLogin()
  1021. getSubscribeLoginDown()
  1022. listApi.value = documentaryApi.followDealSubscribeDealList
  1023. })
  1024. </script>
  1025. <style scoped lang="scss">
  1026. @import "@/uni.scss";
  1027. .content-container {
  1028. .field-container {
  1029. display: grid;
  1030. grid-template-columns: repeat(3, 1fr);
  1031. gap: px2rpx(16);
  1032. min-width: 0;
  1033. overflow: hidden;
  1034. @media (max-width: 991px) {
  1035. grid-template-columns: 1fr;
  1036. }
  1037. .account-l-con {
  1038. background-color: transparent;
  1039. border-radius: px2rpx(8);
  1040. padding: px2rpx(20);
  1041. margin-bottom: px2rpx(16);
  1042. transition: all 0.3s ease;
  1043. box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  1044. width: 100%;
  1045. border: 1px solid var(--bs-border-color);
  1046. box-sizing: border-box;
  1047. &:hover {
  1048. box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  1049. transform: translateY(-2px);
  1050. }
  1051. .tit {
  1052. display: flex;
  1053. justify-content: space-between;
  1054. align-items: center;
  1055. margin-bottom: px2rpx(20);
  1056. padding-bottom: px2rpx(12);
  1057. border-bottom: 1px solid var(--bs-border-color);
  1058. view:first-child {
  1059. display: flex;
  1060. align-items: center;
  1061. gap: px2rpx(8);
  1062. .green-icon {
  1063. color: #28a745;
  1064. font-size: px2rpx(16);
  1065. }
  1066. .tit-tit {
  1067. font-size: px2rpx(16);
  1068. font-weight: 600;
  1069. color: var(--bs-emphasis-color);
  1070. }
  1071. text:last-child {
  1072. font-size: px2rpx(14);
  1073. font-weight: 500;
  1074. color: var(--bs-body-color);
  1075. }
  1076. }
  1077. .caozuo {
  1078. display: flex;
  1079. gap: px2rpx(12);
  1080. i {
  1081. font-size: px2rpx(18);
  1082. color: var(--bs-body-color);
  1083. transition: all 0.2s ease;
  1084. &:hover {
  1085. color: #eb3f57;
  1086. cursor: pointer;
  1087. }
  1088. &:active {
  1089. transform: scale(0.9);
  1090. }
  1091. }
  1092. }
  1093. }
  1094. .account-grid {
  1095. display: grid;
  1096. grid-template-columns: repeat(3, 1fr);
  1097. gap: px2rpx(16);
  1098. width: 100%;
  1099. box-sizing: border-box;
  1100. @media (max-width: 480px) {
  1101. grid-template-columns: repeat(3, 1fr);
  1102. }
  1103. .account-grid-item {
  1104. /* 🔥 核心修复 3:去掉强制最小宽度,避免超宽 */
  1105. /* min-width: px2rpx(200); */
  1106. margin-bottom: px2rpx(16);
  1107. .sub {
  1108. font-size: px2rpx(12);
  1109. font-weight: 500;
  1110. color: var(--bs-body-color);
  1111. margin-bottom: px2rpx(4);
  1112. text-transform: uppercase;
  1113. letter-spacing: px2rpx(0.5);
  1114. white-space: nowrap;
  1115. overflow: hidden;
  1116. text-overflow: ellipsis;
  1117. }
  1118. .num {
  1119. font-size: px2rpx(14);
  1120. font-weight: 400;
  1121. color: var(--bs-emphasis-color);
  1122. line-height: 1.4;
  1123. white-space: nowrap;
  1124. overflow: hidden;
  1125. text-overflow: ellipsis;
  1126. }
  1127. }
  1128. }
  1129. }
  1130. }
  1131. }
  1132. .avatar {
  1133. width: px2rpx(60);
  1134. height: px2rpx(60);
  1135. border-radius: 4px;
  1136. }
  1137. .content-title {
  1138. display: flex;
  1139. justify-content: space-between;
  1140. align-items: center;
  1141. .content-title-btns {
  1142. display: flex;
  1143. align-items: center;
  1144. justify-content: center;
  1145. gap: px2rpx(12);
  1146. margin-bottom: px2rpx(24);
  1147. .btn-primary {
  1148. min-width: px2rpx(120);
  1149. background-color: var(--color-error);
  1150. color: #fff;
  1151. padding: 0 px2rpx(12);
  1152. border: none;
  1153. font-size: px2rpx(14);
  1154. text-align: center;
  1155. cursor: pointer;
  1156. display: flex;
  1157. align-items: center;
  1158. justify-content: center;
  1159. gap: px2rpx(8);
  1160. }
  1161. .btn-primary1 {
  1162. background-color: #cf1322;
  1163. ;
  1164. }
  1165. .btn-primary2 {
  1166. background-color: var(--color-secondary-focus);
  1167. }
  1168. }
  1169. }
  1170. .operation-btn {
  1171. :deep(text) {
  1172. display: flex;
  1173. align-items: center;
  1174. justify-content: center;
  1175. gap: px2rpx(4);
  1176. cursor: pointer;
  1177. background-color: var(--color-slate-150);
  1178. padding: px2rpx(8) 0;
  1179. }
  1180. }
  1181. .operation-btn.disabled {
  1182. cursor: not-allowed;
  1183. opacity: 0.5;
  1184. }
  1185. .search-bar {
  1186. display: flex;
  1187. align-items: center;
  1188. justify-content: flex-start;
  1189. flex-wrap: wrap;
  1190. gap: px2rpx(16);
  1191. margin: px2rpx(16) 0;
  1192. .cwg-combox,
  1193. .uni-easyinput,
  1194. .uni-date {
  1195. width: px2rpx(240) !important;
  1196. flex: none;
  1197. }
  1198. }
  1199. .dia-content {
  1200. padding: px2rpx(20);
  1201. .uni-forms-item {
  1202. width: 100%;
  1203. }
  1204. .grid-layout {
  1205. display: grid;
  1206. grid-template-columns: 1fr 1fr;
  1207. gap: px2rpx(20);
  1208. margin: px2rpx(24) 0;
  1209. padding: px2rpx(20);
  1210. background-color: transparent;
  1211. border-radius: px2rpx(8);
  1212. box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  1213. }
  1214. .fllow-title {
  1215. display: flex;
  1216. align-items: center;
  1217. justify-content: space-between;
  1218. border-bottom: 1px solid #eee;
  1219. padding-bottom: 10px;
  1220. margin-bottom: 10px;
  1221. .title {
  1222. font-weight: bold;
  1223. color: var(--bs-heading-color);
  1224. padding-left: 8px;
  1225. border-left: 4px solid #eb3f57;
  1226. font-size: 16px;
  1227. }
  1228. }
  1229. .delete-grid {
  1230. margin: px2rpx(16) 0;
  1231. }
  1232. .delete-row {
  1233. display: grid;
  1234. grid-template-columns: 1fr 1fr;
  1235. gap: px2rpx(12);
  1236. @media screen and (max-width: 768px) {
  1237. grid-template-columns: 1fr;
  1238. }
  1239. }
  1240. .delete-item {
  1241. flex: 1;
  1242. display: flex;
  1243. justify-content: space-between;
  1244. align-items: center;
  1245. padding: px2rpx(12) 0;
  1246. border-bottom: 1px dashed #e9ecef;
  1247. &:first-child {
  1248. padding-right: px2rpx(16);
  1249. }
  1250. &:last-child {
  1251. padding-left: px2rpx(16);
  1252. }
  1253. }
  1254. .delete-label {
  1255. font-size: px2rpx(14);
  1256. color: var(--bs-body-color);
  1257. }
  1258. .delete-value {
  1259. font-size: px2rpx(14);
  1260. color: var(--bs-emphasis-color);
  1261. font-weight: 400;
  1262. }
  1263. .delete-tip {
  1264. margin-top: px2rpx(16);
  1265. font-size: px2rpx(14);
  1266. color: var(--bs-body-color);
  1267. line-height: 1.5;
  1268. padding-top: px2rpx(16);
  1269. }
  1270. .tip-star {
  1271. color: #dc3545;
  1272. margin-right: px2rpx(4);
  1273. }
  1274. .agree {
  1275. margin-top: px2rpx(20);
  1276. }
  1277. .checkbox-agree {
  1278. display: flex;
  1279. align-items: flex-start;
  1280. gap: px2rpx(8);
  1281. .agree-text {
  1282. font-size: px2rpx(14);
  1283. color: var(--bs-body-color);
  1284. line-height: 1.5;
  1285. width: 100%;
  1286. white-space: wrap;
  1287. .a {
  1288. color: #007bff;
  1289. text-decoration: underline;
  1290. margin: 0 px2rpx(4);
  1291. &:hover {
  1292. color: #0056b3;
  1293. }
  1294. }
  1295. }
  1296. }
  1297. .fllow-content {
  1298. margin-bottom: px2rpx(16);
  1299. .tit {
  1300. font-size: px2rpx(14);
  1301. font-weight: 500;
  1302. color: var(--bs-body-color);
  1303. margin-bottom: px2rpx(6);
  1304. text-transform: uppercase;
  1305. letter-spacing: px2rpx(0.5);
  1306. }
  1307. .con {
  1308. font-size: px2rpx(16);
  1309. font-weight: 400;
  1310. color: var(--bs-emphasis-color);
  1311. line-height: 1.4;
  1312. }
  1313. }
  1314. .form-row {
  1315. display: grid;
  1316. grid-template-columns: 1fr 1fr;
  1317. gap: px2rpx(20);
  1318. margin-top: px2rpx(16);
  1319. @media screen and (max-width: 768px) {
  1320. grid-template-columns: 1fr;
  1321. }
  1322. }
  1323. .form-item {
  1324. display: flex;
  1325. flex-direction: column;
  1326. align-items: flex-start;
  1327. text {
  1328. font-size: px2rpx(14);
  1329. font-weight: 500;
  1330. color: var(--bs-body-color);
  1331. margin-bottom: px2rpx(8);
  1332. white-space: nowrap;
  1333. }
  1334. input,
  1335. select,
  1336. textarea {
  1337. width: 100%;
  1338. padding: px2rpx(10);
  1339. border: 1px solid #ced4da;
  1340. border-radius: px2rpx(4);
  1341. font-size: px2rpx(14);
  1342. transition: all 0.2s ease;
  1343. &:focus {
  1344. outline: none;
  1345. border-color: #4dabf7;
  1346. box-shadow: 0 0 0 2px rgba(77, 171, 247, 0.2);
  1347. }
  1348. }
  1349. textarea {
  1350. resize: vertical;
  1351. min-height: px2rpx(100);
  1352. }
  1353. }
  1354. .tip-red {
  1355. color: #dc3545;
  1356. font-size: px2rpx(14);
  1357. margin: px2rpx(12) 0 px2rpx(24) 0;
  1358. }
  1359. .tip-text {
  1360. margin-top: px2rpx(24);
  1361. font-size: px2rpx(14);
  1362. color: var(--bs-body-color);
  1363. line-height: 1.5;
  1364. padding: px2rpx(16);
  1365. background-color: #e7f3ff;
  1366. border-radius: px2rpx(4);
  1367. border-left: 4px solid #4dabf7;
  1368. }
  1369. }
  1370. /* 弹窗按钮样式 */
  1371. :deep(.cwg-popup__footer) {
  1372. display: flex;
  1373. gap: px2rpx(20);
  1374. padding: px2rpx(20);
  1375. border-top: 1px solid #e9ecef;
  1376. button {
  1377. flex: 1;
  1378. padding: px2rpx(12) 0;
  1379. border-radius: px2rpx(4);
  1380. font-size: px2rpx(14);
  1381. font-weight: 500;
  1382. transition: all 0.2s ease;
  1383. &:first-child {
  1384. background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;
  1385. color: #495057;
  1386. border: 1px solid #ced4da;
  1387. &:hover {
  1388. background-color: transparent;
  1389. border-color: #adb5bd;
  1390. }
  1391. &:active {
  1392. transform: scale(0.98);
  1393. }
  1394. }
  1395. &:last-child {
  1396. background-color: #dc3545;
  1397. color: white;
  1398. border: 1px solid #dc3545;
  1399. &:hover {
  1400. background-color: #c82333;
  1401. border-color: #bd2130;
  1402. }
  1403. &:active {
  1404. transform: scale(0.98);
  1405. }
  1406. }
  1407. }
  1408. }
  1409. </style>