transfer.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. <template>
  2. <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
  3. <cwg-header :title="t('Home.page_ib.item9')" />
  4. <view id="custom_IbTransfer" class="transfer-page">
  5. <view class="main-content">
  6. <!-- 步骤1:选择转出账户 -->
  7. <cwg-asset-tabs v-model="activeTab" :tabs="tabsConfig" />
  8. <!-- 步骤2:转账表单 -->
  9. <view class="box box-step2">
  10. <view class="b-card">
  11. <view class="card-top">
  12. <uni-forms ref="formRef" :model="form" :rules="rules" label-width="300" label-position="top"
  13. validate-trigger="submit">
  14. <view class="form-row">
  15. <view class="form-col">
  16. <!-- 转出账户 -->
  17. <uni-forms-item :label="t('Custom.Transfer.TransferAccounts')">
  18. <uni-easyinput v-model="fromInfo" disabled
  19. :placeholder="t('placeholder.input')" @blur="validateAmount" />
  20. </uni-forms-item>
  21. </view>
  22. <view class="form-col">
  23. <!-- 转入账户 -->
  24. <uni-forms-item :label="toLabel" name="to"
  25. :error-message="deposittoErrorMessage">
  26. <cwg-combox v-model:value="form.to" :clearable="false"
  27. :options="depositDisplayList" :placeholder="t('placeholder.choose')" />
  28. </uni-forms-item>
  29. </view>
  30. </view>
  31. <view class="form-row">
  32. <view class="form-col">
  33. <!-- 货币类型 -->
  34. <uni-forms-item :label="t('Custom.Transfer.CurrencyType')" name="currency">
  35. <cwg-combox v-model:value="form.currency" :clearable="false"
  36. :options="currencyOptions" :placeholder="t('placeholder.choose')" />
  37. </uni-forms-item>
  38. </view>
  39. <view class="form-col">
  40. <!-- 转账金额 -->
  41. <uni-forms-item :label="t('Custom.Transfer.Amount')" name="amount"
  42. :error-message="amountErrorMessage">
  43. <uni-easyinput v-model="form.amount" :placeholder="t('placeholder.input')"
  44. @blur="validateAmount" />
  45. </uni-forms-item>
  46. </view>
  47. </view>
  48. <!-- 20%赠金-年中赠金 -->
  49. <view class="form-row" v-if="tableData4TwoFlag">
  50. <view class="form-col-full">
  51. <uni-forms-item class="agree" name="agree5">
  52. <view class="agree-content">
  53. <checkbox :checked="form.agree5" @click="form.agree5 = !form.agree5" />
  54. <view class="agree-text">
  55. <view class="agree-title">{{
  56. t('news_add_field1.activitiesNZTwo.itemDeposit1') }}</view>
  57. </view>
  58. </view>
  59. </uni-forms-item>
  60. <view class="agree-detail">
  61. <text>{{ t('news_add_field1.activitiesNZTwo.itemDeposit2') }}</text>
  62. <text class="clause" @click="dialogClauseNZTwo = true">{{
  63. t('news_add_field1.activitiesNZTwo.itemDeposit3') }}</text>
  64. <text>{{ t('news_add_field1.activitiesNZTwo.itemDeposit4') }}</text>
  65. </view>
  66. </view>
  67. </view>
  68. <!-- 赠送活动 -->
  69. <view class="form-row" v-if="tableDataNewListFlag">
  70. <view class="form-col-full">
  71. <uni-forms-item class="agree" name="agree6">
  72. <view class="agree-content">
  73. <checkbox :checked="form.agree6" @click="form.agree6 = !form.agree6" />
  74. <view class="agree-text">
  75. <view class="agree-title">{{ tableDataNewList.title }}</view>
  76. </view>
  77. </view>
  78. </uni-forms-item>
  79. <view class="agree-detail">
  80. <text>{{ t('news_add_field1.activitiesNewList.item1') }}</text>
  81. <text class="clause" @click="dialogClauseNewList = true">{{
  82. tableDataNewList.title }}</text>
  83. <text>{{ t('news_add_field1.activitiesNewList.item2') }}</text>
  84. </view>
  85. </view>
  86. </view>
  87. <view class="form-row">
  88. <view class="form-col-full">
  89. <button class="s-btn" type="primary" @click="toTransfer" :disabled="submitting">
  90. <span v-if="locale === 'es'">Enviar solicitud</span>
  91. <span v-else>{{ t('Btn.Submit') }}</span>
  92. </button>
  93. </view>
  94. </view>
  95. </uni-forms>
  96. </view>
  97. </view>
  98. </view>
  99. </view>
  100. <!-- 失败弹窗 -->
  101. <cwg-error-popup v-model:visible="dialogError" @confirm="closeDia" />
  102. <!-- 成功弹窗 -->
  103. <cwg-success-popup v-model:visible="dialogSuccess" @confirm="closeDia" />
  104. <!-- 等待弹窗 -->
  105. <cwg-wait-popup v-model:visible="dialogCheckWait" :showFooters="false" />
  106. <!-- 不参加活动弹出框 -->
  107. <cwg-dont-active-popup v-model:visible="dialogDontActive" :showFooters="true" @confirm="tosubmitConfirm" />
  108. <!-- 功能关闭弹出 -->
  109. <cwg-function-disabled-popup v-model:visible="InfoStatus5" :showFooters="false" @confirm="toHome" />
  110. <!-- 赠金协议20年中 -->
  111. <BonusAgreementPopup v-model:visible="dialogClauseNZTwo" :title="t('news_add_field1.activitiesNZTwo.item6')"
  112. :type="nzTwo" :tableData4Two="tableData4Two" />
  113. <!-- 赠送活动协议 -->
  114. <BonusAgreementPopup v-model:visible="dialogClauseNewList" :title="tableDataNewList.title"
  115. :content="tableDataNewList.content" :type="newList" />
  116. </view>
  117. </cwg-page-wrapper>
  118. </template>
  119. <script setup>
  120. import { ref, reactive, computed, onMounted, watch } from 'vue'
  121. import { useI18n } from 'vue-i18n'
  122. import { onLoad } from '@dcloudio/uni-app'
  123. import { getCurrentInstance } from 'vue'
  124. import { ibApi } from '@/service/ib'
  125. import { activityApi } from '@/service/activity'
  126. import Config from '@/config/index'
  127. import useUserStore from '@/stores/use-user-store'
  128. import BonusAgreementPopup from './components/BonusAgreementPopup.vue'
  129. const userStore = useUserStore()
  130. const ibInfo = computed(() => {
  131. return userStore?.userInfo?.ibInfo || {}
  132. })
  133. const { Code } = Config
  134. const { t, locale } = useI18n()
  135. const activeTab = ref(1)
  136. const tabsConfig = computed(() => [
  137. { text: t('Ib.Transfer.CommissionTransfer'), value: 1, type: 'commission' },
  138. { text: t('Ib.Transfer.CommissionIssue'), value: 2, type: 'commissionIssue' },
  139. { text: t('Ib.Transfer.IbAccountTransfer'), value: 3, type: 'ib' },
  140. ])
  141. const toLabel = computed(() => activeTab.value == '1' || activeTab.value == '2' ? t('Label.IntoAccount') : t('Ib.Transfer.IbAccountTransfer'))
  142. // 获取全局实例(用于访问 Session、$pigeon 等)
  143. const { proxy } = getCurrentInstance()
  144. const $pigeon = proxy?.$pigeon
  145. // 响应式数据
  146. const loginValue = ref('')
  147. const flag = ref(false)
  148. const responseMessage = ref('') // 弹窗响应信息
  149. const giveLoginJoin = ref('')
  150. const step2 = ref(false)
  151. const amountLimits = reactive({
  152. minAmount: '',
  153. maxAmount: '',
  154. })
  155. const form = reactive({
  156. currency: 'USD',
  157. depositLogin: null,
  158. to: null,
  159. amount: '',
  160. agree5: false,
  161. agree6: false,
  162. })
  163. const dialogSuccess = computed(() => dialogCheck.value && dialogVisible.value)
  164. const dialogError = computed(() => dialogCheck.value && !dialogVisible.value)
  165. const dialogCheck = ref(false)
  166. const dialogVisible = ref(false)
  167. const dialogCheckWait = ref(false)
  168. const InfoStatus5 = ref(false)
  169. const dialogClauseNZTwo = ref(false)
  170. const tableData4TwoFlag = ref(false)
  171. const tableData4Two = ref({})
  172. const dialogClauseNewList = ref(false)
  173. const tableDataNewListFlag = ref(false)
  174. const tableDataNewList = ref({})
  175. const dialogDontActive = ref(false)
  176. const submitting = ref(false)
  177. // 错误信息
  178. const depositErrorMessage = ref('')
  179. const depositLogin1ErrorMessage = ref('')
  180. const amountErrorMessage = ref('')
  181. // 表单验证规则
  182. const rules = {
  183. withdrawLogin: {
  184. rules: [
  185. {
  186. required: true,
  187. errorMessage: t('vaildate.select.empty')
  188. },
  189. ],
  190. },
  191. to: {
  192. rules: [
  193. {
  194. required: true,
  195. errorMessage: t('vaildate.select.empty')
  196. },
  197. ],
  198. },
  199. amount: {
  200. rules: [
  201. {
  202. required: true,
  203. errorMessage: t('vaildate.amount.format'),
  204. },
  205. {
  206. validateFunction: (rule, value, data, callback) => {
  207. if (!value) {
  208. callback(t('vaildate.amount.format'))
  209. } else if (
  210. amountLimits.minAmount &&
  211. amountLimits.maxAmount &&
  212. (parseFloat(amountLimits.minAmount) > parseFloat(value) ||
  213. parseFloat(amountLimits.maxAmount) < parseFloat(value))
  214. ) {
  215. callback(t('vaildate.amount.amount') +
  216. amountLimits.minAmount +
  217. '-' +
  218. amountLimits.maxAmount)
  219. } else if (!/^[0-9]+([.]{1}[0-9]{1,2})?$/.test(value)) {
  220. callback(t('vaildate.amount.format'))
  221. }
  222. return true
  223. }
  224. },
  225. ],
  226. }
  227. }
  228. function validateAmount() {
  229. const amount = form.amount
  230. if (!amount) {
  231. amountErrorMessage.value = t('vaildate.amount.format')
  232. return false
  233. }
  234. const numValue = parseFloat(amount)
  235. if (isNaN(numValue)) {
  236. amountErrorMessage.value = t('vaildate.amount.format')
  237. return false
  238. }
  239. if (amountLimits.minAmount && numValue < parseFloat(amountLimits.minAmount)) {
  240. amountErrorMessage.value = t('vaildate.amount.amount') + amountLimits.minAmount + '-' + amountLimits.maxAmount
  241. return false
  242. }
  243. if (amountLimits.maxAmount && numValue > parseFloat(amountLimits.maxAmount)) {
  244. amountErrorMessage.value = t('vaildate.amount.amount') + amountLimits.minAmount + '-' + amountLimits.maxAmount
  245. return false
  246. }
  247. if (!/^[0-9]+([.]{1}[0-9]{1,2})?$/.test(amount)) {
  248. amountErrorMessage.value = t('vaildate.amount.format')
  249. return false
  250. }
  251. amountErrorMessage.value = ''
  252. return true
  253. }
  254. // 模板引用
  255. const formRef = ref(null)
  256. // 计算属性
  257. const getInfoStatus5 = computed(() => {
  258. if (ibInfo.value?.closeFunctions) {
  259. return ibInfo.value.closeFunctions.indexOf('5') !== -1
  260. }
  261. return false
  262. })
  263. // 转入账户列表
  264. const depositDisplayList = computed(() => {
  265. if (activeTab.value != 3) {
  266. return toInfo.value.map(item => ({
  267. text: [item.login, item.platform, item.cId, item.balance, item.groupTypeName].filter(field => field !== null && field !== undefined && field !== '').join('-'),
  268. value: item.login
  269. }))
  270. } else {
  271. return agentInfo.value.map(item => ({
  272. text: `${item.ibNo} - ${item.name}`,
  273. value: item.id
  274. }))
  275. }
  276. })
  277. const fromInfo = ref('')
  278. const toInfo = ref([])
  279. const agentInfo = ref([])
  280. //转出账户信息
  281. const ransferInfo = async function () {
  282. let res = await ibApi.agentBalanceTransferFrom({});
  283. if (res.code == Code.StatusOK) {
  284. fromInfo.value =
  285. res.data.ibNo +
  286. " - " +
  287. t("Custom.Deposit.AvailableBalance") +
  288. ": $" +
  289. (res.data.balance ? res.data.balance : 0);
  290. } else {
  291. $pigeon.MessageError(res.msg);
  292. }
  293. }
  294. //转入账户信息
  295. const ransferToInfo = async function () {
  296. let res;
  297. // 佣金内转使用新接口 /account/dropdown
  298. if (activeTab.value == 1) {
  299. res = await ibApi.CustomDropdown({ platform: "" });
  300. } else {
  301. // 佣金下发和其他情况使用原接口
  302. res = await ibApi.agentTransferToList({});
  303. }
  304. if (res.code == Code.StatusOK) {
  305. toInfo.value = res.data || [];
  306. toInfo.value.forEach((item) => {
  307. if (item.closeFunctions && item.closeFunctions.length > 0) {
  308. const targetValues = ["7", "5", "9"];
  309. const hasTargetValue = item.closeFunctions.some(func => targetValues.includes(func));
  310. if (hasTargetValue) {
  311. item.status = true;
  312. }
  313. }
  314. })
  315. } else {
  316. $pigeon.MessageError(res.msg);
  317. }
  318. }
  319. //获取代理账户信息
  320. const getAgentInfo = async function () {
  321. let res = await ibApi.ibTreeForTransfer({});
  322. if (res.code == Code.StatusOK) {
  323. agentInfo.value = res.data || [];
  324. } else {
  325. $pigeon.MessageError(res.msg);
  326. }
  327. }
  328. const currencyOptions = ref([{ value: 'USD', text: 'USD' }])
  329. function toHome() {
  330. uni.navigateTo({ url: '/pages/ib/index' })
  331. InfoStatus5.value = false
  332. }
  333. function closeDia() {
  334. formRef.value?.resetFields?.()
  335. step2.value = false
  336. loginValue.value = ''
  337. dialogCheck.value = false
  338. dialogVisible.value = false
  339. tableData4TwoFlag.value = false
  340. tableDataNewListFlag.value = false
  341. form.to = ''
  342. form.amount = ''
  343. form.withdrawLogin = ''
  344. form.agree5 = false
  345. form.agree6 = false
  346. }
  347. // 内转
  348. async function toTransfer() {
  349. if (submitting.value) return
  350. try {
  351. const valid = await formRef.value?.validate()
  352. if (!valid) {
  353. console.log('表单验证失败')
  354. return
  355. }
  356. openDontActive()
  357. } catch (error) {
  358. console.error('验证失败:', error)
  359. }
  360. }
  361. // 打开不参加活动弹窗
  362. function openDontActive() {
  363. tosubmitConfirm()
  364. }
  365. function tosubmitConfirm() {
  366. dialogDontActive.value = false
  367. transferConfig()
  368. }
  369. async function transferConfig() {
  370. if (submitting.value) return
  371. submitting.value = true
  372. try {
  373. if (flag.value) {
  374. return
  375. }
  376. flag.value = true
  377. form.activityTwoPercentGive = form.agree5 ? 1 : 0
  378. form.activityGive = form.agree6 ? 1 : 0
  379. dialogCheckWait.value = true
  380. let api
  381. if (activeTab.value != 3) {
  382. api = ibApi.agentBalanceTransfer
  383. } else {
  384. api = ibApi.agentBalanceCommissionAdd
  385. }
  386. const res = await api({ ...form })
  387. dialogCheckWait.value = false
  388. if (res.code == Code.StatusOK) {
  389. dialogCheck.value = true
  390. dialogVisible.value = true
  391. flag.value = false
  392. } else {
  393. responseMessage.value = res.msg
  394. dialogCheck.value = true
  395. dialogVisible.value = false
  396. flag.value = false
  397. }
  398. } catch (error) {
  399. console.error('转账失败:', error)
  400. responseMessage.value = error.msg || t('Msg.Fail')
  401. dialogCheck.value = true
  402. dialogVisible.value = false
  403. } finally {
  404. submitting.value = false
  405. flag.value = false
  406. if (dialogCheckWait.value) dialogCheckWait.value = false
  407. }
  408. }
  409. async function Activity24nianzhongTwoInfo() {
  410. const res = await activityApi.Activity23nianzhongTwoInfo({})
  411. if (res.code == Code.StatusOK) {
  412. tableData4Two.value = res.data
  413. } else {
  414. $pigeon?.MessageError(res.msg)
  415. }
  416. }
  417. // 活动相关方法
  418. function togetActivity() {
  419. get23nianzhongTwoLogin()
  420. getActivityExtensionGiveLogin()
  421. getActivityExtensionGiveLoginJoin()
  422. }
  423. async function get23nianzhongTwoLogin() {
  424. const res = await activityApi.Activity23nianzhongTwoLogin({
  425. login: form.to,
  426. })
  427. if (res.code == Code.StatusOK) {
  428. tableData4Two.value = res.data
  429. if (tableData4Two.value.show == 1) {
  430. tableData4TwoFlag.value = true
  431. } else if (tableData4Two.value.show == 0) {
  432. tableData4TwoFlag.value = false
  433. }
  434. } else {
  435. $pigeon?.MessageError(res.msg)
  436. }
  437. }
  438. async function getActivityExtensionGiveLogin() {
  439. const res = await activityApi.ActivityExtensionGiveLogin({
  440. login: form.to,
  441. })
  442. if (res.code == Code.StatusOK) {
  443. tableDataNewList.value = res.data
  444. if (tableDataNewList.value.show == 1) {
  445. tableDataNewListFlag.value = true
  446. } else if (tableDataNewList.value.show == 0) {
  447. tableDataNewListFlag.value = false
  448. }
  449. } else {
  450. $pigeon?.MessageError(res.msg)
  451. }
  452. }
  453. async function getActivityExtensionGiveLoginJoin() {
  454. const res = await activityApi.ActivityExtensionGiveLoginJoin({
  455. login: form.to,
  456. })
  457. if (res.code == Code.StatusOK) {
  458. giveLoginJoin.value = res.data
  459. } else {
  460. $pigeon?.MessageError(res.msg)
  461. giveLoginJoin.value = ''
  462. }
  463. }
  464. // 监听 activeTab 变化
  465. watch(activeTab, (newVal) => {
  466. if (newVal) {
  467. console.log(newVal, 1212);
  468. if (newVal == 3) {
  469. getAgentInfo()
  470. } else {
  471. ransferToInfo()
  472. }
  473. form.to = ''
  474. form.amount = ''
  475. }
  476. })
  477. //
  478. watch(loginValue, (newVal) => {
  479. if (newVal) {
  480. step2.value = true
  481. form.withdrawLogin = newVal
  482. }
  483. })
  484. watch(() => form.to, (newVal) => {
  485. if (activeTab.value == 3) {
  486. getAgentInfo()
  487. } else {
  488. togetActivity()
  489. }
  490. })
  491. // 监听 agree6 变化
  492. watch(() => form.agree6, (newVal) => {
  493. if (newVal && giveLoginJoin.value?.flag === false) {
  494. let tips = ''
  495. if (giveLoginJoin.value.promptType == 1) {
  496. tips = t('surplusList.item10')
  497. } else {
  498. tips = t('surplusList.item11')
  499. }
  500. return
  501. // 活动相关方法,后续需要在调整
  502. if (giveLoginJoin.value.activityCategory == 1) {
  503. $pigeon?.MessageConfirm(
  504. tips,
  505. t('Msg.SystemPrompt'),
  506. t('surplusList.item12'),
  507. t('Home.msg.item3'),
  508. () => {
  509. $pigeon?.MessageConfirm(
  510. t('surplusList.item13'),
  511. t('Msg.SystemPrompt'),
  512. t('Btn.Confirm'),
  513. t('Btn.Cancel'),
  514. async () => {
  515. try {
  516. const res = await activityApi.ActivityGiveCancel({
  517. login: loginValue.value,
  518. })
  519. if (res.code == Code.StatusOK) {
  520. $pigeon?.MessageOK(res.msg || t('Msg.Success'))
  521. } else {
  522. $pigeon?.MessageError(res.msg)
  523. }
  524. } catch (error) {
  525. $pigeon?.MessageError(t('Msg.Fail'))
  526. }
  527. },
  528. () => {
  529. form.agree6 = false
  530. }
  531. )
  532. },
  533. () => {
  534. form.agree6 = false
  535. }
  536. )
  537. } else {
  538. $pigeon?.MessageConfirm(
  539. tips,
  540. t('Msg.SystemPrompt'),
  541. t('Btn.Confirm'),
  542. t('Btn.Cancel'),
  543. () => { },
  544. () => {
  545. form.agree6 = false
  546. }
  547. )
  548. }
  549. }
  550. })
  551. onMounted(() => {
  552. if (!getInfoStatus5.value) {
  553. // InfoStatus5.value = true
  554. dialogDontActive.value = true
  555. }
  556. ransferInfo();
  557. ransferToInfo();
  558. // Activity24nianzhongTwoInfo()
  559. })
  560. onLoad((options) => {
  561. if (options?.login) {
  562. loginValue.value = options.login
  563. step2.value = true
  564. form.withdrawLogin = options.login
  565. }
  566. })
  567. </script>
  568. <style lang="scss" scoped>
  569. @import "@/uni.scss";
  570. .transfer-page {
  571. width: 100%;
  572. padding-bottom: px2rpx(20);
  573. .main-content {
  574. text-align: left;
  575. .box {
  576. padding-top: px2rpx(5);
  577. color: #303133;
  578. .b-card {
  579. background-color: #fff;
  580. margin-bottom: px2rpx(10);
  581. border-radius: px2rpx(6);
  582. box-shadow: 0 px2rpx(1) px2rpx(6) 0 rgba(0, 0, 0, 0.05);
  583. &:hover {
  584. box-shadow: 0 px2rpx(2) px2rpx(8) 0 rgba(0, 0, 0, 0.1);
  585. }
  586. .card-top {
  587. padding: px2rpx(15) px2rpx(20);
  588. box-sizing: border-box;
  589. .card-row {
  590. margin-bottom: px2rpx(12);
  591. &:last-child {
  592. margin-bottom: 0;
  593. }
  594. }
  595. .tit {
  596. font-size: px2rpx(16);
  597. margin-bottom: px2rpx(12);
  598. font-weight: 600;
  599. .iconfont {
  600. font-size: px2rpx(18);
  601. margin-right: px2rpx(8);
  602. color: #409eff;
  603. }
  604. }
  605. .title-wrapper {
  606. display: flex;
  607. justify-content: space-between;
  608. align-items: center;
  609. }
  610. }
  611. }
  612. }
  613. .box-step2 {
  614. .form-row {
  615. display: flex;
  616. flex-wrap: wrap;
  617. margin-bottom: px2rpx(12);
  618. gap: px2rpx(12);
  619. &:last-child {
  620. margin-bottom: 0;
  621. }
  622. .form-col {
  623. flex: 1;
  624. min-width: px2rpx(140);
  625. @media screen and (max-width: 991px) {
  626. flex: 0 0 100%;
  627. width: 100%;
  628. }
  629. }
  630. .form-col-full {
  631. width: 100%;
  632. padding: 0 px2rpx(5);
  633. }
  634. }
  635. .tips {
  636. line-height: 1.8;
  637. font-size: px2rpx(12);
  638. color: #909399;
  639. background-color: #f9f9f9;
  640. padding: px2rpx(12);
  641. border-radius: px2rpx(4);
  642. border-left: px2rpx(2) solid #409eff;
  643. .title {
  644. font-weight: 600;
  645. margin-bottom: px2rpx(6);
  646. color: #606266;
  647. }
  648. }
  649. }
  650. }
  651. .picker-select {
  652. background-color: #f5f7fa;
  653. border: 1px solid #dcdfe6;
  654. border-radius: px2rpx(4);
  655. padding: px2rpx(12) px2rpx(14);
  656. font-size: px2rpx(14);
  657. color: #606266;
  658. line-height: 1.4;
  659. width: 100%;
  660. box-sizing: border-box;
  661. &:hover {
  662. border-color: #409eff;
  663. }
  664. &.picker-disabled {
  665. background-color: #f5f7fa;
  666. color: #c0c4cc;
  667. cursor: not-allowed;
  668. }
  669. }
  670. .disabled-input {
  671. background-color: #f5f7fa;
  672. border: 1px solid #dcdfe6;
  673. border-radius: px2rpx(4);
  674. padding: px2rpx(12) px2rpx(14);
  675. font-size: px2rpx(14);
  676. color: #606266;
  677. width: 100%;
  678. box-sizing: border-box;
  679. }
  680. .m-input {
  681. background-color: #f5f7fa;
  682. border: 1px solid #dcdfe6;
  683. border-radius: px2rpx(4);
  684. padding: px2rpx(12) px2rpx(14);
  685. font-size: px2rpx(14);
  686. width: 100%;
  687. box-sizing: border-box;
  688. &:focus {
  689. border-color: #409eff;
  690. outline: none;
  691. box-shadow: 0 0 0 px2rpx(1) rgba(64, 158, 255, 0.2);
  692. }
  693. }
  694. .s-btn {
  695. width: 100%;
  696. padding: px2rpx(12) px2rpx(20);
  697. border-radius: px2rpx(4);
  698. margin: px2rpx(10) 0;
  699. background-color: #409eff;
  700. color: #fff;
  701. border: none;
  702. font-size: px2rpx(15);
  703. font-weight: 500;
  704. cursor: pointer;
  705. &:hover {
  706. background-color: #66b1ff;
  707. transform: translateY(px2rpx(-1));
  708. box-shadow: 0 px2rpx(2) px2rpx(6) 0 rgba(64, 158, 255, 0.3);
  709. }
  710. &:active {
  711. background-color: #3a8ee6;
  712. transform: translateY(0);
  713. }
  714. &[disabled] {
  715. opacity: 0.6;
  716. cursor: not-allowed;
  717. }
  718. }
  719. }
  720. // 动画
  721. @keyframes popupFadeIn {
  722. from {
  723. opacity: 0;
  724. transform: scale(0.9);
  725. }
  726. to {
  727. opacity: 1;
  728. transform: scale(1);
  729. }
  730. }
  731. @keyframes fadeIn {
  732. from {
  733. opacity: 0;
  734. transform: translateY(px2rpx(10));
  735. }
  736. to {
  737. opacity: 1;
  738. transform: translateY(0);
  739. }
  740. }
  741. @keyframes pulse {
  742. 0% {
  743. transform: scale(1);
  744. }
  745. 50% {
  746. transform: scale(1.05);
  747. }
  748. 100% {
  749. transform: scale(1);
  750. }
  751. }
  752. @keyframes spin {
  753. from {
  754. transform: rotate(0deg);
  755. }
  756. to {
  757. transform: rotate(360deg);
  758. }
  759. }
  760. // 表单错误信息样式
  761. .uni-forms-item__error {
  762. font-size: px2rpx(12);
  763. color: #f56c6c;
  764. margin-top: px2rpx(4);
  765. }
  766. // 适配不同屏幕尺寸(媒体查询中的 750rpx 保持不变)
  767. @media (max-width: 750rpx) {
  768. .transfer-page {
  769. .main-content {
  770. padding: px2rpx(8);
  771. .box {
  772. .b-card {
  773. .card-top {
  774. padding: px2rpx(12) px2rpx(16);
  775. .tit {
  776. font-size: px2rpx(14);
  777. .iconfont {
  778. font-size: px2rpx(16);
  779. }
  780. }
  781. }
  782. }
  783. }
  784. }
  785. .s-btn {
  786. font-size: px2rpx(14);
  787. padding: px2rpx(10) px2rpx(16);
  788. }
  789. }
  790. }
  791. </style>