payment.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. <template>
  2. <Theme>
  3. <view class="wrap">
  4. <Navbar
  5. title="支付方式"
  6. fixed
  7. border
  8. autoBack
  9. :leftShow="isIosPay"
  10. @leftClick="leftClick"
  11. >
  12. <template #right v-if="!isIosPay">
  13. <navMenu :options="{ icon: 'icon-home', text: '主页' }" />
  14. </template>
  15. </Navbar>
  16. <view class="content">
  17. <view class="logo-container">
  18. <image
  19. class="logo"
  20. src="@/static/login/login_logo.png"
  21. mode="aspectFit"
  22. ></image>
  23. </view>
  24. <view class="cont">
  25. <view class="payable_price">
  26. {{ symbol.symbol }}
  27. <text>{{ Moneyhtml(payInfo.totalAmt) }}</text>
  28. </view>
  29. <view class="logistics_step" v-if="type == 'order'">
  30. <trans _t="请在" />
  31. <text class="step_time">{{
  32. useGlobal().$format(payInfo.enddate || "")
  33. }}</text>
  34. <trans _t="取消付款提示" />
  35. </view>
  36. <view class="wallet_pay" v-if="!isAPPIOS">
  37. <template v-if="type != 'recharge'">
  38. <view class="wallet_title">
  39. <trans _t="用余额支付" />
  40. <view class="tag">
  41. <trans _t="推荐" />
  42. </view>
  43. </view>
  44. </template>
  45. <view class="wallet_content">
  46. <view class="wallet_top" v-if="type != 'recharge'">
  47. <up-radio-group v-model="radioValue" activeColor="var(--black)">
  48. <up-radio name="wallet">
  49. <template #label>
  50. <view style="display: flex; align-items: center">
  51. <view class="wallet_img">
  52. <image
  53. src="../../static/shop/balance.png"
  54. class="_img"
  55. ></image>
  56. </view>
  57. <view class="payment_text">
  58. <view class="payment_title">
  59. <trans _t="钱包" />
  60. </view>
  61. <view class="wallet_amount"
  62. >{{ symbol.symbol }}&nbsp;{{
  63. Moneyhtml(totalAmt)
  64. }}</view
  65. >
  66. </view>
  67. </view>
  68. </template>
  69. </up-radio>
  70. </up-radio-group>
  71. </view>
  72. <view class="wallet_bottom" v-if="differenceMoney < 0">
  73. <view class="bottom_left">
  74. <trans _t="余额不足需充值" />
  75. <text class="money">¥{{ Math.abs(differenceMoney) }}</text>
  76. </view>
  77. <view class="bottom_right" @click="toRecharge">
  78. <trans _t="充值" />
  79. </view>
  80. </view>
  81. </view>
  82. <view
  83. class="wallet_content"
  84. v-for="(item, index) in bankList"
  85. :key="index"
  86. >
  87. <view class="wallet_top">
  88. <up-radio-group v-model="radioValue" activeColor="var(--black)">
  89. <up-radio :name="item.name">
  90. <template #label>
  91. <view style="display: flex; align-items: center">
  92. <view class="wallet_img">
  93. <image
  94. :src="`../../static/shop/${item.icon}`"
  95. class="_img"
  96. ></image>
  97. </view>
  98. <view class="payment_text">
  99. <view class="payment_title">
  100. <trans :_t="item.title" />
  101. </view>
  102. </view>
  103. </view>
  104. </template>
  105. </up-radio>
  106. </up-radio-group>
  107. </view>
  108. </view>
  109. <!-- <DropInPay :oid="oid" ref="dropInPayRef"></DropInPay> -->
  110. </view>
  111. <view class="order-status" v-if="isAPPIOS">
  112. <trans _t="订单处理中" />
  113. </view>
  114. <couponModel
  115. :item="couponList"
  116. @change="changeId"
  117. v-if="type == 'package'"
  118. class="coupon"
  119. />
  120. </view>
  121. <view class="footer">
  122. <view class="tips">
  123. <trans _t="您将在安全的环境下付款给" />VAVABUY
  124. </view>
  125. <view class="handling_fee">
  126. <trans _t="手续费" />&nbsp;:&nbsp;{{ symbol.symbol }}&nbsp;0
  127. </view>
  128. <view class="amount">
  129. <text>{{ symbol.symbol }}&nbsp;</text>
  130. <text>{{ Moneyhtml(payInfo.totalAmt) }}</text>
  131. </view>
  132. <view class="footer_btn" @click="openPassword" v-if="!isAPPIOS">
  133. <trans _t="支付" />
  134. <text>{{ symbol.symbol }}</text>
  135. <text>{{ Moneyhtml(payInfo.totalAmt) }}</text>
  136. </view>
  137. </view>
  138. </view>
  139. <successModel ref="successModels" @open="handleSuccessModelOpen">
  140. <template #footer v-if="type == 'service' || isIosPay">
  141. <view></view>
  142. </template>
  143. </successModel>
  144. </view>
  145. <PasswordModal ref="passwordModal" @complete="completePassword" />
  146. <!-- #ifdef H5 -->
  147. <SplitCardPay
  148. ref="splitCardPayModalRef"
  149. :paramsObj="paramsObj"
  150. @on-success="handleAairwallexSuccess"
  151. />
  152. <GooglePayModal
  153. ref="googlePayRef"
  154. :paramsObj="paramsObj"
  155. @success="handleAairwallexSuccess"
  156. />
  157. <ApplePayModal
  158. ref="applePayModalRef"
  159. :paramsObj="paramsObj"
  160. @on-success="handleAairwallexSuccess"
  161. />
  162. <!-- #endif -->
  163. <!-- #ifdef APP-PLUS -->
  164. <cardPaymentApp
  165. ref="cardpaymentAppRef"
  166. :paramsObj="paramsObj"
  167. @on-success="handleAairwallexSuccess"
  168. />
  169. <googlePaymentApp ref="googlepaymentAppRef" :paramsObj="paramsObj" />
  170. <!-- #endif -->
  171. </Theme>
  172. </template>
  173. <script setup>
  174. import Navbar from "@/components/navbar";
  175. import navMenu from "@/components/nav_menu";
  176. import { onLoad, onUnload } from "@dcloudio/uni-app";
  177. import { ref, nextTick, computed, onMounted, onUnmounted } from "vue";
  178. import {
  179. SHOP_PAY_INFO,
  180. SHOP_SUBMIT_PAY,
  181. SHOP_PACKAGES_PAY,
  182. SHOP_GET_CANCOUPON,
  183. SHOP_PAY_STATUS,
  184. } from "@/api";
  185. import { useSystemStore, useUserStore, useTabbarStore } from "@/store";
  186. import { useGlobal, Toast, Moneyhtml, query, systemInfo } from "@/utils";
  187. import PasswordModal from "@/components/passwordModal";
  188. // #ifdef H5
  189. import SplitCardPay from "@/components/paymentModal/splitCardPay";
  190. import GooglePayModal from "@/components/paymentModal/googlePay";
  191. import ApplePayModal from "@/components/paymentModal/applePay";
  192. // #endif
  193. // #ifdef APP-PLUS
  194. import cardPaymentApp from "@/components/paymentModal/cardPayment_app";
  195. import googlePaymentApp from "@/components/paymentModal/googlePayment_app";
  196. // #endif
  197. // import DropInPay from "@/components/paymentModal/dropInPay"
  198. import successModel from "./components/successModel";
  199. import couponModel from "./components/couponModel";
  200. const systemInfoName = systemInfo();
  201. const useSystem = useSystemStore();
  202. const useUser = useUserStore();
  203. const useTabbar = useTabbarStore();
  204. const oid = ref("");
  205. const payInfo = ref({});
  206. const radioValue = ref("wallet");
  207. const successModels = ref(null);
  208. const cardpaymentAppRef = ref(null);
  209. const googlepaymentAppRef = ref(null);
  210. const symbol = computed(() => useSystem.getSymbol);
  211. const userInfo = computed(() => useUser.getuserInfo);
  212. const differenceMoney = computed(() => {
  213. let infoPrice = Number(userInfo.value.money);
  214. let payPrice = Number(payInfo.value.totalAmt);
  215. if (infoPrice > payPrice || infoPrice == payPrice) {
  216. return 0;
  217. } else {
  218. return infoPrice - payPrice;
  219. }
  220. });
  221. const totalAmt = computed(() => {
  222. if (payInfo.value.payList?.length) {
  223. return payInfo.value.payList[0].moeny;
  224. }
  225. return 0;
  226. });
  227. const bankList = [
  228. {
  229. name: "airwallex",
  230. title: "银行卡",
  231. icon: "bank_card.png",
  232. },
  233. // #ifndef APP-PLUS
  234. {
  235. name: "google",
  236. title: "Google支付",
  237. icon: "google.png",
  238. },
  239. {
  240. name: "ABA",
  241. title: "ABA KHQR",
  242. icon: "KHQR.png",
  243. },
  244. // #endif
  245. ];
  246. if (useGlobal().$adjustPosition) {
  247. const applePayConf = {
  248. name: "apple",
  249. title: "Apple支付",
  250. icon: "applepay.png",
  251. };
  252. const i = bankList.findIndex((item) => item.name == applePayConf.name);
  253. i < 0 && bankList.push(applePayConf);
  254. }
  255. const isAPPIOS = ref(false);
  256. const issubnum = ref(0);
  257. const isPage = ref("");
  258. const type = ref("");
  259. const couponList = ref([]);
  260. const checkDate = ref(null);
  261. const passwordModal = ref(null);
  262. const cardPayModalRef = ref(null);
  263. const splitCardPayModalRef = ref(null);
  264. const applePayModalRef = ref(null);
  265. const googlePayRef = ref(null);
  266. const paramsObj = ref(null);
  267. const isIosPay = ref(false);
  268. const isIosPayParams = ref({});
  269. const lunxunTimeout = ref(null);
  270. // const dropInPayRef = ref(null);
  271. const openPassword = () => {
  272. const isShipping = type.value === "package";
  273. paramsObj.value = {
  274. [isShipping ? "id" : "oid"]: oid.value,
  275. type: type.value,
  276. };
  277. if (isShipping && payInfo.value.couponId) {
  278. paramsObj.value.couponId = payInfo.value.couponId;
  279. }
  280. // #ifdef APP-PLUS
  281. if (isAPPIOS.value) {
  282. if (systemInfoName.osName == "ios") {
  283. let queryParams = "isIosPay=true";
  284. for (let key in isIosPayParams.value) {
  285. queryParams = `${queryParams}${
  286. queryParams.length > 0 ? "&" : ""
  287. }${key}=${isIosPayParams.value[key]}`;
  288. }
  289. lunxunTimeout.value = setInterval(() => {
  290. checkPayStatusByLunxun();
  291. }, 1000 * 5);
  292. plus.runtime.openURL(
  293. "https://vavabuy.net/#/pages/shop/payment?" + queryParams
  294. );
  295. } else {
  296. cardpaymentAppRef.value && cardpaymentAppRef.value.open(paramsObj.value);
  297. }
  298. return;
  299. }
  300. // #endif
  301. if (radioValue.value == "wallet") {
  302. if (isIosPay.value) {
  303. passwordModal.value && passwordModal.value.open();
  304. } else {
  305. if (userInfo.value.setpaypass) {
  306. passwordModal.value && passwordModal.value.open();
  307. } else {
  308. uni.navigateTo({ url: "/pages/setting/account-safety" });
  309. }
  310. }
  311. return;
  312. }
  313. // if (radioValue.value == 'airwallex') return cardPayModalRef.value && cardPayModalRef.value.open();
  314. // #ifdef H5
  315. if (radioValue.value == "airwallex")
  316. return splitCardPayModalRef.value && splitCardPayModalRef.value.open();
  317. if (radioValue.value == "google")
  318. return googlePayRef.value && googlePayRef.value.open();
  319. if (radioValue.value == "apple")
  320. return applePayModalRef.value && applePayModalRef.value.open();
  321. // #endif
  322. // #ifdef APP-PLUS
  323. // if (radioValue.value == 'airwallex') return cardpaymentAppRef.value && cardpaymentAppRef.value.open(paramsObj.value);
  324. if (radioValue.value == "airwallex") {
  325. if (systemInfoName.osName == "ios") {
  326. let queryParams = "isIosPay=true";
  327. for (let key in isIosPayParams.value) {
  328. queryParams = `${queryParams}${
  329. queryParams.length > 0 ? "&" : ""
  330. }${key}=${isIosPayParams.value[key]}`;
  331. }
  332. console.log("queryParams", queryParams);
  333. lunxunTimeout.value = setInterval(() => {
  334. checkPayStatusByLunxun();
  335. }, 1000 * 5);
  336. plus.runtime.openURL(
  337. "https://vavabuy.net/#/pages/shop/payment?" + queryParams
  338. );
  339. } else {
  340. cardpaymentAppRef.value && cardpaymentAppRef.value.open(paramsObj.value);
  341. }
  342. return;
  343. }
  344. if (radioValue.value == "google")
  345. return googlepaymentAppRef.value && googlepaymentAppRef.value.open();
  346. // #endif
  347. };
  348. const completePassword = (password) => {
  349. paySubmit(password);
  350. };
  351. const paySubmit = async (password) => {
  352. try {
  353. const isShipping = type.value === "package";
  354. const params = {
  355. type: type.value,
  356. payType: radioValue.value,
  357. paypass: password,
  358. [isShipping ? "id" : "oid"]: oid.value,
  359. };
  360. if (isShipping && payInfo.value.couponId) {
  361. params.couponId = payInfo.value.couponId;
  362. }
  363. const res = await SHOP_PACKAGES_PAY(params);
  364. // useUser.getUserInfo();
  365. passwordModal.value && passwordModal.value.close();
  366. useTabbar.getPageCur("shop");
  367. successModels.value && successModels.value.open();
  368. // setTimeout(() => {
  369. // uni.$emit("on-open");
  370. // uni.navigateBack();
  371. // }, 1000);
  372. } catch (error) {
  373. Toast(error.msg);
  374. }
  375. };
  376. const checkPayStatusByLunxun = () => {
  377. const params = {
  378. oid: oid.value,
  379. type: type.value,
  380. };
  381. SHOP_PAY_STATUS(params)
  382. .then((result) => {
  383. console.log("轮询 result", JSON.stringify(result));
  384. useTabbar.getPageCur("shop");
  385. successModels.value && successModels.value.open();
  386. removePayStatusLunxun();
  387. })
  388. .catch((err) => {
  389. console.log("轮询 err", JSON.stringify(err));
  390. });
  391. };
  392. const removePayStatusLunxun = () => {
  393. clearInterval(lunxunTimeout.value);
  394. lunxunTimeout.value = null;
  395. };
  396. // #ifdef H5
  397. const handleAairwallexSuccess = (dataInfo) => {
  398. switch (radioValue.value) {
  399. case "airwallex":
  400. // cardPayModalRef.value && cardPayModalRef.value.close();
  401. splitCardPayModalRef.value && splitCardPayModalRef.value.close();
  402. break;
  403. case "google":
  404. googlePayRef.value && googlePayRef.value.close();
  405. break;
  406. case "apple":
  407. applePayModalRef.value && applePayModalRef.value.close();
  408. break;
  409. default:
  410. break;
  411. }
  412. useTabbar.getPageCur("shop");
  413. successModels.value && successModels.value.open();
  414. };
  415. // #endif
  416. // #ifdef APP-PLUS
  417. const handleAairwallexSuccess = (dataInfo) => {
  418. console.log("----- on-success dataInfo ----", dataInfo);
  419. switch (radioValue.value) {
  420. case "airwallex":
  421. cardpaymentAppRef.value && cardpaymentAppRef.value.close();
  422. break;
  423. case "google":
  424. googlepaymentAppRef.value && googlepaymentAppRef.value.open();
  425. break;
  426. case "apple":
  427. break;
  428. default:
  429. break;
  430. }
  431. useTabbar.getPageCur("shop");
  432. successModels.value && successModels.value.open();
  433. };
  434. // #endif
  435. const toRecharge = () => {
  436. uni.navigateTo({ url: "/pages/bank/recharge" });
  437. };
  438. const leftClick = () => {
  439. if (isPage.value == "order") {
  440. uni.switchTab({ url: "/pages/order/index" });
  441. useTabbar.getPageCur("shop");
  442. } else {
  443. uni.navigateBack();
  444. }
  445. };
  446. onLoad((options) => {
  447. oid.value = options.oid;
  448. isPage.value = !!options.page ? options.page : "";
  449. type.value = !!options.type ? options.type : "";
  450. isIosPay.value =
  451. options.isIosPay == true || options.isIosPay == "true" ? true : false;
  452. isIosPayParams.value = {
  453. oid: options.oid,
  454. page: !!options.page ? options.page : "",
  455. type: !!options.type ? options.type : "",
  456. money: !!options.money ? options.money : "",
  457. };
  458. if (type.value == "recharge") {
  459. radioValue.value = "airwallex";
  460. }
  461. nextTick(() => {
  462. getPayInfo();
  463. });
  464. });
  465. onUnload(() => {
  466. removePayStatusLunxun();
  467. });
  468. onUnmounted(() => {
  469. removePayStatusLunxun();
  470. });
  471. function handleSuccessModelOpen() {
  472. console.log(isIosPay.value, "isIosPay.value");
  473. if (isIosPay.value) {
  474. setTimeout(() => {
  475. uni.navigateBack({
  476. success: () => {
  477. uni.$emit("on-service-open");
  478. },
  479. });
  480. }, 1000);
  481. }
  482. }
  483. const getPayInfo = async () => {
  484. try {
  485. const res = await SHOP_PAY_INFO({
  486. oid: oid.value,
  487. sid: oid.value,
  488. type: type.value,
  489. couponId: payInfo.value.couponId,
  490. });
  491. payInfo.value = res.data;
  492. couponList.value = res.data.coupons || [];
  493. } catch (error) {}
  494. };
  495. const getCoupon = async (money) => {
  496. try {
  497. const res = await SHOP_GET_CANCOUPON(money);
  498. couponList.value = res.data || [];
  499. } catch (error) {}
  500. };
  501. const changeId = (id, data) => {
  502. if (id) {
  503. payInfo.value.couponId = id;
  504. checkDate.value = data;
  505. } else {
  506. delete payInfo.value.couponId;
  507. checkDate.value = null;
  508. }
  509. getPayInfo();
  510. };
  511. onMounted(() => {
  512. // #ifdef APP-PLUS
  513. if (useGlobal().$adjustPosition) {
  514. isAPPIOS.value = true;
  515. nextTick(() => {
  516. openPassword();
  517. });
  518. }
  519. // #endif
  520. });
  521. </script>
  522. <style lang="less" scoped>
  523. @import url("@/style.less");
  524. .wrap {
  525. max-height: 100vh;
  526. background-color: var(--bg);
  527. .flex();
  528. flex-direction: column;
  529. overflow: hidden;
  530. .content {
  531. position: relative;
  532. flex-grow: 1;
  533. .flex();
  534. flex-direction: column;
  535. height: calc(100dvh - 44px);
  536. overflow: hidden scroll;
  537. z-index: 1;
  538. .logo-container {
  539. position: fixed;
  540. top: 50%;
  541. left: 50%;
  542. transform: translate(-50%, -50%);
  543. z-index: 1;
  544. opacity: 0.3;
  545. pointer-events: none;
  546. .logo {
  547. width: 570rpx;
  548. height: 496rpx;
  549. }
  550. }
  551. .cont {
  552. flex-grow: 1;
  553. overflow: hidden scroll;
  554. .coupon {
  555. margin: 0 30rpx;
  556. }
  557. .order-status {
  558. text-align: center;
  559. .size(36rpx);
  560. color: var(--black);
  561. }
  562. .payable_price {
  563. color: var(--text);
  564. .size(48rpx);
  565. font-weight: 700;
  566. line-height: 60rpx;
  567. padding-top: 24rpx;
  568. text-align: center;
  569. }
  570. .logistics_step {
  571. color: var(--text-01);
  572. .size(28rpx);
  573. line-height: 40rpx;
  574. padding: 32rpx 24rpx 0;
  575. .step_time {
  576. margin: 0 8rpx;
  577. display: inline-block;
  578. color: var(--text);
  579. font-weight: 700;
  580. }
  581. }
  582. .wallet_pay {
  583. margin: 24rpx;
  584. padding: 24rpx;
  585. border-radius: 16rpx;
  586. background-color: var(--light);
  587. .wallet_title {
  588. .ver();
  589. .size(36rpx);
  590. font-weight: 700;
  591. height: 60rpx;
  592. color: var(--text);
  593. .tag {
  594. background-color: var(--danger);
  595. border-radius: 8rpx;
  596. color: var(--light);
  597. .size(24rpx);
  598. font-weight: 500;
  599. line-height: 40rpx;
  600. margin-left: 8rpx;
  601. padding: 0 8rpx;
  602. }
  603. }
  604. .wallet_content {
  605. margin-top: 24rpx;
  606. .wallet_top {
  607. /deep/ .u-radio-group {
  608. flex: none;
  609. .u-radio__icon-wrap {
  610. margin-right: 0;
  611. }
  612. }
  613. .ver();
  614. .wallet_img {
  615. width: 72rpx;
  616. height: 72rpx;
  617. margin: 0 24rpx;
  618. ._img {
  619. width: inherit;
  620. height: inherit;
  621. }
  622. }
  623. .payment_text {
  624. .ver(flex-end);
  625. color: var(--text);
  626. .size();
  627. font-weight: 500;
  628. .wallet_amount {
  629. margin-left: 8rpx;
  630. font-weight: 700;
  631. }
  632. }
  633. }
  634. .wallet_bottom {
  635. margin-top: 16rpx;
  636. padding: 16rpx 24rpx;
  637. background-color: var(--bg);
  638. border-radius: 8rpx;
  639. .flex_position(space-between);
  640. .bottom_left {
  641. color: var(--text-02);
  642. .size(24rpx);
  643. margin-right: 16rpx;
  644. .money {
  645. color: var(--primary);
  646. }
  647. }
  648. .bottom_right {
  649. height: 64rpx;
  650. background-color: var(--black);
  651. color: var(--light);
  652. border-radius: 16rpx;
  653. padding: 16rpx 30rpx;
  654. .flex_center();
  655. .size(24rpx);
  656. line-height: 1;
  657. }
  658. }
  659. }
  660. }
  661. }
  662. .footer {
  663. padding: 0 24rpx 24rpx;
  664. background-color: var(--bg);
  665. .tips {
  666. color: var(--black);
  667. .size(28rpx);
  668. font-weight: 600;
  669. line-height: 60rpx;
  670. text-align: center;
  671. }
  672. .handling_fee {
  673. color: var(--text-01);
  674. .size(28rpx);
  675. line-height: 60rpx;
  676. text-align: center;
  677. }
  678. .amount {
  679. color: var(--red);
  680. .size(48rpx);
  681. font-weight: 700;
  682. line-height: 80rpx;
  683. text-align: center;
  684. }
  685. &_btn {
  686. background-color: var(--black);
  687. color: var(--light);
  688. padding: 16rpx 30rpx;
  689. height: 96rpx;
  690. .flex_center();
  691. border-radius: 16rpx;
  692. font-weight: 700;
  693. .size(28rpx);
  694. column-gap: 8rpx;
  695. }
  696. }
  697. }
  698. }
  699. </style>