index.vue 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415
  1. <template>
  2. <view>
  3. <view class="order-submission">
  4. <view
  5. class="allAddress"
  6. :style="store_self_mention ? '' : 'padding-top:10rpx;'"
  7. >
  8. <view class="nav acea-row">
  9. <view
  10. class="item font-color"
  11. :class="shippingType == 0 ? 'on' : 'on2'"
  12. @tap="addressType(0)"
  13. v-if="store_self_mention"
  14. ></view>
  15. <!-- <view class="item font-color" :class="shippingType == 1 ? 'on' : 'on2'" @tap="addressType(1)"
  16. v-if="store_self_mention"></view> -->
  17. </view>
  18. <view
  19. class="address acea-row row-between-wrapper"
  20. @tap="onAddress"
  21. v-if="shippingType == 0"
  22. :style="
  23. store_self_mention
  24. ? ''
  25. : 'border-top-left-radius: 14rpx;border-top-right-radius: 14rpx;'
  26. "
  27. >
  28. <view class="addressCon" v-if="addressInfo.realName">
  29. <view class="name"
  30. >{{ addressInfo.realName }}
  31. <text class="phone">{{ addressInfo.phone }}</text>
  32. </view>
  33. <view class="acea-row">
  34. <text class="default font-color" v-if="addressInfo.isDefault"
  35. >[默认]</text
  36. >
  37. <text class="line2"
  38. >{{ addressInfo.province }}{{ addressInfo.city
  39. }}{{ addressInfo.district }}{{ addressInfo.detail }}</text
  40. >
  41. </view>
  42. </view>
  43. <view class="addressCon" v-else>
  44. <view class="setaddress">设置收货地址</view>
  45. </view>
  46. <view class="iconfont icon-jiantou"></view>
  47. </view>
  48. <view
  49. class="address acea-row row-between-wrapper"
  50. v-else
  51. @tap="showStoreList"
  52. >
  53. <block v-if="storeList.length > 0">
  54. <view class="addressCon">
  55. <view class="name"
  56. >{{ system_store.name }}
  57. <text class="phone">{{ system_store.phone }}</text>
  58. </view>
  59. <view class="line1">
  60. {{ system_store.address
  61. }}{{ ", " + system_store.detailedAddress }}
  62. </view>
  63. </view>
  64. <view class="iconfont icon-jiantou"></view>
  65. </block>
  66. <block v-else>
  67. <view>暂无门店信息</view>
  68. </block>
  69. </view>
  70. <view class="line">
  71. <image src="/static/images/line.jpg"></image>
  72. </view>
  73. </view>
  74. <view class="pad30">
  75. <orderGoods
  76. :mallType="orderInfoVo.mallType"
  77. :cartInfo="cartInfo"
  78. :orderProNum="orderProNum"
  79. ></orderGoods>
  80. <view class="wrapper borRadius14">
  81. <view
  82. class="item acea-row row-between-wrapper"
  83. @tap="couponTap"
  84. v-if="orderInfoVo.mallType === 0"
  85. >
  86. <view>优惠券</view>
  87. <view class="discount"
  88. >{{ couponTitle }}
  89. <text class="iconfont icon-jiantou"></text>
  90. </view>
  91. </view>
  92. <view class="item acea-row row-between-wrapper">
  93. <view>快递费用</view>
  94. <block v-if="orderInfoVo.mallType === 0">
  95. <view
  96. class="discount"
  97. v-if="
  98. parseFloat(orderInfoVo.freightFee) > 0 &&
  99. orderInfoVo.mallType === 0
  100. "
  101. >
  102. +¥{{ orderInfoVo.freightFee }}
  103. </view>
  104. <view class="discount" v-else>免运费</view>
  105. </block>
  106. <view class="discount" v-else>邮费到付</view>
  107. </view>
  108. <view class="item" v-if="textareaStatus">
  109. <view>备注信息</view>
  110. <textarea
  111. v-if="coupon.coupon === false"
  112. placeholder-class="placeholder"
  113. @input="bindHideKeyboard"
  114. value=""
  115. name="mark"
  116. placeholder="请添加备注(150字以内)"
  117. ></textarea>
  118. </view>
  119. </view>
  120. <!-- 是否使用余料支付 -->
  121. <view class="wrapper borRadius14">
  122. <view class="item">
  123. <view class="zf-box" v-if="orderInfoVo.mallType == 0">
  124. <view>余料支付方式</view>
  125. </view>
  126. <view class="swicth-box" v-if="orderInfoVo.mallType == 0">
  127. <view class="lable-box">
  128. <view class="iconfont icon-touzijintiao1"></view>
  129. <view class="lable-icon">
  130. <view class="lable">余料支付</view>
  131. <view class="value">
  132. 可用余料:
  133. {{ metalTypeMap[metalType].name }}
  134. :{{ metalTypeMap[metalType].balance || 0 }}g
  135. </view>
  136. </view>
  137. </view>
  138. <!-- <switch
  139. color="#FFCC33"
  140. style="transform: scale(0.7)"
  141. @change="useGoldPay"
  142. ></switch> -->
  143. </view>
  144. <view class="zf-box">
  145. <view>工费支付方式</view>
  146. </view>
  147. <view class="list">
  148. <view
  149. v-for="(item, index) in avaliablePayments"
  150. class="payItem acea-row row-middle"
  151. :class="active == index ? 'on' : ''"
  152. @tap="payItem(index)"
  153. :key="index"
  154. >
  155. <view class="name acea-row row-center-wrapper">
  156. <view
  157. class="iconfont animated"
  158. :class="
  159. item.icon +
  160. ' ' +
  161. (animated == true && active == index ? 'bounceIn' : '')
  162. "
  163. >
  164. </view>
  165. {{ item.name }}
  166. </view>
  167. <view class="tip">{{ item.title }}</view>
  168. </view>
  169. </view>
  170. </view>
  171. </view>
  172. <view class="moneyList borRadius14">
  173. <view class="item acea-row row-between-wrapper">
  174. <view>商品总价:</view>
  175. <view v-if="orderInfoVo.mallType === 0" class="money">
  176. ¥{{ orderInfoVo.payFee || 0 }}
  177. </view>
  178. <view v-else class="money">
  179. 贝币: {{ Number(orderInfoVo.proTotalFee) || 0 }}
  180. </view>
  181. </view>
  182. <view
  183. class="item acea-row row-between-wrapper"
  184. v-if="orderInfoVo.couponFee > 0"
  185. >
  186. <view>优惠券抵扣:</view>
  187. <view class="money">-¥{{ orderInfoVo.couponFee }}</view>
  188. </view>
  189. <!-- <view
  190. class="item acea-row row-between-wrapper"
  191. v-if="orderInfoVo.deductionPrice > 0"
  192. >
  193. <view>积分抵扣:</view>
  194. <view class="money">-¥{{ orderInfoVo.deductionPrice }}</view>
  195. </view> -->
  196. <view
  197. class="item acea-row row-between-wrapper"
  198. v-if="orderInfoVo.mallType === 0"
  199. >
  200. <view>工费:</view>
  201. <view class="money">+¥{{ orderInfoVo.totalLaborCost }}</view>
  202. </view>
  203. <view
  204. class="item acea-row row-between-wrapper"
  205. v-if="
  206. orderInfoVo.mallType === 0 && orderInfoVo?.totalAdditionalAmount
  207. "
  208. >
  209. <view>附加费:</view>
  210. <view class="money"
  211. >+¥{{ orderInfoVo.totalAdditionalAmount }}</view
  212. >
  213. </view>
  214. <view
  215. class="item acea-row row-between-wrapper"
  216. v-if="orderInfoVo.freightFee > 0"
  217. >
  218. <view>运费:</view>
  219. <view class="money">+¥{{ orderInfoVo.freightFee }}</view>
  220. </view>
  221. <view
  222. v-if="
  223. orderInfoVo.mallType === 0 &&
  224. Number(orderInfoVo.vipLevelDis) !== 0
  225. "
  226. class="item acea-row row-between-wrapper"
  227. >
  228. <view>会员折扣:</view>
  229. <view class="money">-¥{{ orderInfoVo.vipLevelDis }}</view>
  230. </view>
  231. </view>
  232. <view style="height: 120rpx"></view>
  233. </view>
  234. <view class="footer acea-row row-between-wrapper">
  235. <view>
  236. 合计:
  237. <text class="font-color" v-if="orderInfoVo.mallType === 0">
  238. ¥{{ orderInfoVo.payFee || 0 }}
  239. </text>
  240. <text class="font-color" v-else>
  241. {{ Number(orderInfoVo.proTotalFee) || 0 }}
  242. </text>
  243. </view>
  244. <view class="settlement" style="z-index: 100" @tap="SubOrder">
  245. 立即结算
  246. </view>
  247. </view>
  248. </view>
  249. <couponListWindow
  250. :coupon="coupon"
  251. @close="closeCouponPopup"
  252. :showPopup="showCouponPopup"
  253. :openType="openType"
  254. @ChangCoupons="ChangCoupons"
  255. :orderShow="orderShow"
  256. ></couponListWindow>
  257. <addressWindow
  258. ref="addressWindowRef"
  259. @changeTextareaStatus="changeTextareaStatus"
  260. :address="address"
  261. :pagesUrl="pagesUrl"
  262. @OnDefaultAddress="OnDefaultAddress"
  263. @OnChangeAddress="OnChangeAddress"
  264. @changeClose="changeClose"
  265. />
  266. <!-- 余额不足modal -->
  267. <up-modal
  268. :showCancelButton="true"
  269. :show="showModal"
  270. title="余额不足"
  271. confirmText="去充值"
  272. @cancel="showModal = false"
  273. @confirm="modalConfirm"
  274. ></up-modal>
  275. </view>
  276. </template>
  277. <script setup>
  278. // 导入UniApp页面加载生命周期函数
  279. import { onLoad } from "@dcloudio/uni-app";
  280. // 导入Vue3响应式API(ref创建响应式变量、computed计算属性等)
  281. import { ref, computed, watch, onMounted, nextTick } from "vue";
  282. // 导入应用状态管理(全局状态,如登录状态、用户信息等)
  283. import { useAppStore } from "@/stores/app.js";
  284. // 导入提示框工具(封装的toast提示函数)
  285. import { useToast } from "@/hooks/useToast.js";
  286. // 导入支付相关工具(封装的支付逻辑,如提交支付、验证支付渠道等)
  287. import { usePayment } from "@/hooks/usePayment.js";
  288. // 导入订单相关API接口(优惠券、创建订单、计算价格等接口)
  289. import {
  290. getCouponsOrderPrice, // 获取可用优惠券接口
  291. orderCreate, // 创建订单接口
  292. postOrderComputed, // 计算订单价格接口
  293. wechatOrderPay, // 微信支付接口
  294. wechatQueryPayResult, // 微信支付结果查询接口
  295. loadPreOrderApi, // 加载预订单接口
  296. alipayPaymentResult, // 支付宝支付结果查询接口
  297. } from "@/api/order.js";
  298. // 导入用户地址详情API接口
  299. import { getAddressDetail } from "@/api/user.js";
  300. // 导入门店列表API接口
  301. import { storeListApi } from "@/api/store.js";
  302. // 导入工具类(封装的通用工具函数)
  303. import util from "@/utils/util";
  304. // 导入优惠券弹窗组件
  305. import couponListWindow from "@/components/couponListWindow";
  306. // 导入地址选择组件
  307. import addressWindow from "@/components/addressWindow";
  308. // 导入订单商品列表组件
  309. import orderGoods from "@/components/orderGoods";
  310. // 导入登录工具(未登录时跳转登录页)
  311. import { toLogin } from "@/libs/login.js";
  312. import useRealGoldPrice from "@/hooks/useRealGoldPrice";
  313. const { realGoldprice, fetchGoldPrice } = useRealGoldPrice("RTJ_Au");
  314. // 初始化应用状态管理实例(用于获取全局状态)
  315. const appStore = useAppStore();
  316. // 初始化提示框工具(获取toast方法)
  317. const { Toast } = useToast();
  318. // 初始化支付工具(获取支付相关方法)
  319. const { submitPayment, paymentConfig, getAvailableChannels } = usePayment();
  320. // 响应式变量:订单页面标识(用于优惠券组件,控制不显示tab切换)
  321. const orderShow = ref("orderShow");
  322. // 响应式变量:控制备注输入框是否显示
  323. const textareaStatus = ref(true);
  324. // 响应式变量:支付方式列表(包含支付宝、微信、余额等支付方式配置)
  325. const payments = ref([
  326. // {
  327. // name: "支付宝支付", // 支付方式名称
  328. // icon: "icon-zhifubao", // 图标类名
  329. // value: "alipay", // 支付标识值
  330. // title: "支付宝快捷支付", // 支付说明
  331. // payType: "alipay", // 支付类型
  332. // payStatus: 0, // 支付状态(1-可用,0-不可用)
  333. // payChannel: "appAliPay",
  334. // },
  335. // {
  336. // name: "微信支付",
  337. // icon: "icon-wechat",
  338. // value: "weixin",
  339. // title: "微信快捷支付",
  340. // payType: "weixin",
  341. // payStatus: 0,
  342. // payChannel: "weixinApp",
  343. // },
  344. {
  345. name: "余额支付",
  346. icon: "icon-balance",
  347. value: "yue",
  348. title: "可用余额:",
  349. payType: "yue",
  350. payStatus: 1,
  351. payChannel: "weixinh5",
  352. },
  353. // {
  354. // name: "贝币支付",
  355. // icon: "icon-balance",
  356. // value: "yue",
  357. // title: "可用贝币:",
  358. // payType: "yue",
  359. // payStatus: 0,
  360. // payChannel: "weixinh5",
  361. // },
  362. ]);
  363. // 计算属性:过滤出可用的支付方式(只保留payStatus为1的项)
  364. const avaliablePayments = computed(() => {
  365. console.log(payments.value)
  366. return payments.value.filter((item) => item.payStatus === 1);
  367. });
  368. console.log(avaliablePayments)
  369. // 响应式变量:当前选中的支付方式(默认余额支付)
  370. const payType = ref("alipay");
  371. // 响应式变量:优惠券打开方式(1表示"使用"场景)
  372. const openType = ref(1);
  373. // 响应式变量:当前选中的支付方式索引(用于UI高亮)
  374. const active = ref(0);
  375. // 响应式变量:优惠券相关配置(控制弹窗显示、列表数据等)
  376. const coupon = ref({
  377. coupon: false, // 是否显示优惠券弹窗
  378. list: [], // 优惠券列表数据
  379. statusTile: "立即使用", // 按钮文字
  380. });
  381. // 响应式变量:地址相关配置(控制弹窗显示、选中地址ID等)
  382. const address = ref({
  383. address: false,
  384. addressId: 0,
  385. }); // 地址组件
  386. const addressInfo = ref({}); // 地址信息
  387. const addressId = ref(0); // 地址id
  388. const couponId = ref(0); // 优惠券id
  389. const userInfo = ref({}); // 用户信息
  390. const mark = ref(""); // 备注信息
  391. const couponTitle = ref("请选择"); // 优惠券
  392. const useIntegral = ref(false); // 是否使用积分
  393. const status = ref(0);
  394. // 响应式变量:是否有地址(用于判断是否需要提示用户添加地址)
  395. const is_address = ref(false);
  396. // 响应式变量:支付页面刷新标识(修复支付页面隐藏后刷新问题)
  397. const toPay = ref(false);
  398. // 响应式变量:配送方式(0-快递配送,1-到店自提)
  399. const shippingType = ref(0);
  400. // 响应式变量:选中的门店信息(自提时使用)
  401. const system_store = ref({});
  402. const contacts = ref("");
  403. // 响应式变量:联系人电话(自提时可能需要)
  404. const contactsTel = ref("");
  405. const storeList = ref([]);
  406. // 响应式变量:是否支持门店自提(1-支持,0-不支持)
  407. const store_self_mention = ref(0);
  408. // 响应式变量:购物车商品信息(订单中的商品列表)
  409. const cartInfo = ref([]);
  410. const animated = ref(false);
  411. // 响应式变量:订单总价
  412. const totalPrice = ref(0);
  413. const pagesUrl = ref("");
  414. // const usableCoupon = ref({});
  415. const payChannel = ref("");
  416. // 响应式变量:订单信息详情(包含商品总价、运费、折扣等)
  417. const orderInfoVo = ref({});
  418. // 响应式变量:地址列表数据(用于地址选择组件)
  419. const addressList = ref([]);
  420. // 响应式变量:订单商品总数
  421. const orderProNum = ref(0);
  422. const preOrderNo = ref(""); // 预下单订单号
  423. const addressWindowRef = ref(null); // 地址组件引用
  424. const showCouponPopup = ref(false); // 显示优惠券弹窗
  425. const showModal = ref(false);
  426. const userSelectPayTypeItem = ref(payments.value[0]);
  427. // 监听 isLogin
  428. watch(
  429. () => appStore.isLogin, // 监听的数据源:全局登录状态
  430. (newV) => {
  431. // newV是登录状态的新值(true/false)
  432. if (newV) {
  433. // 若已登录
  434. getloadPreOrder(); // 加载预订单信息
  435. this.getaddressInfo(); // 获取地址信息(this指向当前组件实例)
  436. }
  437. },
  438. { deep: true } // 深度监听(确保复杂数据类型变化也能触发)
  439. );
  440. // 商品总价
  441. // 页面加载时触发的生命周期函数
  442. onLoad((options) => {
  443. // options是页面跳转时传递的参数
  444. console.log(appStore.userInfo); // 打印用户信息(调试用)
  445. // #ifdef APP
  446. // 支付宝沙箱模式(测试环境用,正式环境注释)
  447. // var EnvUtils = plus.android.importClass("com.alipay.sdk.app.EnvUtils");
  448. // EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
  449. // #endif
  450. // #ifdef H5
  451. payChannel.value = "weixinh5"; // H5环境支付渠道为微信H5支付
  452. // #endif
  453. // #ifdef APP
  454. payChannel.value = "appAliPay"; // APP环境支付渠道为支付宝APP支付
  455. // #endif
  456. // 从参数中获取预订单号(若没有则默认为0)
  457. preOrderNo.value = options.preOrderNo || 0;
  458. // 从参数中获取地址ID(若没有则默认为0)
  459. addressId.value = options.addressId || 0;
  460. // 从参数中获取是否有地址的标识
  461. is_address.value = options.is_address ? true : false;
  462. // 若已登录,则加载预订单信息;否则跳转到登录页
  463. if (appStore.isLogin) {
  464. getloadPreOrder(); // 加载预订单
  465. } else {
  466. toLogin(); // 跳登录
  467. }
  468. });
  469. // 组件挂载后触发的生命周期函数(DOM渲染完成后)
  470. onMounted(() => {
  471. textareaStatus.value = true; // 默认显示备注输入框
  472. // 若已登录且非支付页面,则获取地址信息(注释掉的逻辑,预留)
  473. if (appStore.isLogin && !toPay.value) {
  474. //this.getaddressInfo();
  475. }
  476. // 监听全局事件"handClick"(用于接收门店选择结果)
  477. uni.$on("handClick", (res) => {
  478. if (res) {
  479. // 若有结果
  480. system_store.value = res.address; // 更新选中的门店信息
  481. }
  482. // 清除监听(避免重复触发)
  483. uni.$off("handClick");
  484. });
  485. });
  486. // 是否选择余料支付
  487. const useGoldPay = (e) => {
  488. computedPrice();
  489. };
  490. const metalTypeMap = {
  491. 1: { name: "黄金", balance: 0 },
  492. 2: { name: "铂金", balance: 0 },
  493. 3: { name: "白银", balance: 0 },
  494. };
  495. const metalType = ref(1);
  496. // 加载预订单信息(核心函数:初始化订单数据)
  497. const getloadPreOrder = () => {
  498. console.log("preOrderNo.value", preOrderNo.value);
  499. // 调用加载预订单API,传入预订单号
  500. loadPreOrderApi(preOrderNo.value)
  501. .then((res) => {
  502. metalTypeMap[1].balance = res.data.auBalance || 0;
  503. metalTypeMap[2].balance = res.data.ptBalance || 0;
  504. metalTypeMap[3].balance = res.data.agBalance || 0;
  505. metalType.value = res.data.metalType;
  506. // 接口成功回调
  507. let orderInfoVoData = res.data.orderInfoVo; // 订单基本信息
  508. orderInfoVo.value = orderInfoVoData; // 保存订单信息
  509. cartInfo.value = orderInfoVoData.orderDetailList; // 保存商品列表
  510. orderProNum.value = orderInfoVoData.orderProNum; // 保存商品总数
  511. // 设置地址ID(优先用参数传入的,没有则用订单默认的)
  512. address.value.addressId = addressId.value
  513. ? addressId.value
  514. : orderInfoVoData.addressId;
  515. // 判断是否支持门店自提(根据接口返回和全局状态)
  516. store_self_mention.value =
  517. res.data.storeSelfMention == "true" && // 接口返回支持自提
  518. appStore.productTypeComputed === "normal" // 全局状态为普通商品
  519. ? true
  520. : false;
  521. // 根据商城类型设置是否使用积分(mallType=1时默认使用)
  522. useIntegral.value = orderInfoVo.value.mallType === 1;
  523. // 根据商城类型设置默认支付方式(mallType=1时用贝币支付)
  524. payType.value = orderInfoVo.value.mallType === 1 ? "yue" : "alipay";
  525. // 动态更新支付方式状态(根据接口返回的配置)
  526. payments.value.forEach((item) => {
  527. if (item.name === "余额支付") {
  528. // 余额支付:显示可用余额,状态由接口返回的yuePayStatus决定
  529. item.title = "可用余额: " + orderInfoVoData.userBalance;
  530. item.payStatus = parseInt(res.data.yuePayStatus) === 1 ? 1 : 2;
  531. } else if (item.payType === "weixin") {
  532. // 微信支付:状态由接口返回的payWeixinOpen决定
  533. item.payStatus = parseInt(res.data.payWeixinOpen) === 1 ? 1 : 0;
  534. }
  535. // 贝币支付:仅在mallType=1时可用
  536. if (orderInfoVo.value.mallType === 1) {
  537. item.title = "可用贝币: " + orderInfoVoData.userIntegral;
  538. item.payStatus = item.name === "贝币支付" ? 1 : 0;
  539. } else {
  540. item.payStatus = item.name === "贝币支付" ? 0 : 1;
  541. }
  542. });
  543. if (addressId.value) {
  544. computedPrice();
  545. }
  546. // 调用子页面方法授权后执行获取地址列表
  547. nextTick(() => {
  548. addressWindowRef.value.fetchAddressList();
  549. });
  550. })
  551. .catch((err) => {
  552. // 接口失败回调
  553. console.error(err); // 打印错误
  554. uni.navigateTo({ url: "/pages/order_list/index" }); // 跳转到订单列表
  555. Toast({ title: err }); // 提示错误信息
  556. });
  557. };
  558. // 授权回调事件(用户授权后触发,预留)
  559. const onLoadFun = () => {
  560. //this.getaddressInfo(); // 获取地址信息(注释掉的逻辑)
  561. // 调用子组件方法获取地址列表(注释掉的逻辑)
  562. // this.$scope.selectComponent('#address-window').getAddressList();
  563. };
  564. // 获取门店列表数据(自提时使用)
  565. const getList = () => {
  566. // 从本地存储获取用户经纬度(用于附近门店查询)
  567. let longitude = uni.getStorageSync("user_longitude");
  568. let latitude = uni.getStorageSync("user_latitude");
  569. // 构造请求参数
  570. let data = {
  571. latitude: latitude, // 纬度
  572. longitude: longitude, // 经度
  573. page: 1, // 页码
  574. limit: 10, // 每页条数
  575. };
  576. // 调用门店列表API
  577. storeListApi(data)
  578. .then((res) => {
  579. // 成功回调
  580. let list = res.data.list || []; // 门店列表
  581. storeList.value = list; // 保存门店列表
  582. system_store.value = list[0]; // 默认选中第一个门店
  583. })
  584. .catch((err) => {
  585. // 失败回调
  586. Toast({ title: err }); // 提示错误
  587. });
  588. };
  589. // 关闭地址弹窗
  590. const changeClose = () => {
  591. address.value.address = false; // 隐藏地址弹窗
  592. };
  593. // 跳转门店列表页面(自提时选择门店)
  594. const showStoreList = () => {
  595. // 若有门店列表数据,则跳转到门店详情页
  596. if (storeList.value.length > 0) {
  597. uni.navigateTo({
  598. url: "/pages/users/goods_details_store/index",
  599. });
  600. }
  601. };
  602. // 计算订单价格
  603. function computedPrice() {
  604. let shippingTypeValue = shippingType.value;
  605. postOrderComputed({
  606. mallType: orderInfoVo.value.mallType, // 商城类型
  607. addressId: address.value.addressId, // 地址ID
  608. useIntegral: useIntegral.value ? true : false, // 是否用积分
  609. couponId: couponId.value, // 优惠券ID
  610. shippingType: parseInt(shippingTypeValue) + 1, // 配送方式(后端要求+1)
  611. preOrderNo: preOrderNo.value, // 预订单号
  612. goldNum: appStore.userInfo.goldBalance, // 余料数量
  613. })
  614. .then((res) => {
  615. // 成功回调
  616. let data = res.data; // 计算后的价格数据
  617. // 更新订单费用信息
  618. orderInfoVo.value.couponFee = data.couponFee; // 优惠券抵扣
  619. orderInfoVo.value.userIntegral = data.surplusIntegral; // 剩余积分
  620. orderInfoVo.value.deductionPrice = data.deductionPrice; // 积分抵扣金额
  621. orderInfoVo.value.freightFee = data.freightFee; // 运费
  622. orderInfoVo.value.payFee = data.payFee; // 实付金额
  623. orderInfoVo.value.proTotalFee = data.proTotalFee; // 商品总价
  624. orderInfoVo.value.useIntegral = data.useIntegral; // 是否使用积分
  625. orderInfoVo.value.usedIntegral = data.usedIntegral; // 已用积分
  626. orderInfoVo.value.surplusIntegral = data.surplusIntegral; // 剩余积分
  627. })
  628. .catch((err) => {
  629. // 失败回调
  630. Toast({ title: err }); // 提示错误
  631. });
  632. }
  633. // 切换配送方式(快递/自提)
  634. const addressType = (e) => {
  635. let index = e; // 0-快递,1-自提
  636. shippingType.value = parseInt(index); // 更新配送方式
  637. // 若为普通商城类型,重新计算价格
  638. if (orderInfoVo.value.mallType === 0) {
  639. computedPrice();
  640. }
  641. // if (index == 1) getList();
  642. };
  643. // 配送方式选择器变化事件(预留,用于下拉选择器)
  644. const bindPickerChange = (e) => {
  645. let value = e.detail.value; // 选择的索引
  646. shippingType.value = value; // 更新配送方式
  647. computedPrice(); // 重新计算价格
  648. };
  649. // 关闭优惠券弹窗
  650. const closeCouponPopup = () => {
  651. showCouponPopup.value = false; // 隐藏优惠券弹窗
  652. };
  653. // 改变备注框状态(优惠券选择后调用)
  654. const changeTextareaStatus = () => {
  655. // 重置所有优惠券的选中状态
  656. for (let i = 0, len = coupon.value.list.length; i < len; i++) {
  657. coupon.value.list[i].use_title = "";
  658. coupon.value.list[i].is_use = 0;
  659. }
  660. textareaStatus.value = true; // 显示备注框
  661. status.value = 0; // 重置状态
  662. coupon.value.list = coupon.value.list; // 触发响应式更新
  663. };
  664. // 选择优惠券后的处理事件
  665. const ChangCoupons = (e) => {
  666. // this.usableCoupon = e
  667. // this.coupon.coupon = false
  668. let index = e,
  669. list = coupon.value.list,
  670. couponTitleValue = "请选择",
  671. couponIdValue = 0;
  672. console.log("list", list);
  673. for (let i = 0, len = list.length; i < len; i++) {
  674. if (i != index) {
  675. list[i].use_title = "";
  676. list[i].isUse = 0;
  677. }
  678. }
  679. // 切换当前优惠券的选中状态
  680. if (list[index].isUse) {
  681. // 若已选中,则取消选择
  682. list[index].use_title = "";
  683. list[index].isUse = 0;
  684. } else {
  685. // 若未选中,则选中
  686. list[index].use_title = "不使用"; // 显示"不使用"按钮
  687. list[index].isUse = 1; // 标记为选中
  688. couponTitleValue = list[index].name; // 更新标题为优惠券名称
  689. couponIdValue = list[index].id; // 更新选中的优惠券ID
  690. }
  691. // 更新优惠券相关状态
  692. couponTitle.value = couponTitleValue;
  693. couponId.value = couponIdValue;
  694. coupon.value.coupon = false;
  695. // coupon.value.list = list;
  696. computedPrice();
  697. };
  698. // 首次进入页面时展示默认地址
  699. const OnDefaultAddress = (e) => {
  700. addressInfo.value = e; // 保存默认地址详情
  701. address.value.addressId = e.id; // 更新选中地址ID
  702. };
  703. // 选择地址后触发的事件
  704. const OnChangeAddress = (e) => {
  705. console.log("OnChangeAddress", e);
  706. addressInfo.value = e;
  707. address.value.addressId = e.id;
  708. textareaStatus.value = true;
  709. //orderInfoVo.value.addressId = e;
  710. address.value.address = false;
  711. //this.getaddressInfo();
  712. if (orderInfoVo.value.mallType === 0) {
  713. computedPrice();
  714. }
  715. };
  716. // 备注输入事件(实时保存输入内容)
  717. const bindHideKeyboard = (e) => {
  718. mark.value = e.detail.value; // 保存输入的备注信息
  719. };
  720. // 获取当前订单可用的优惠券列表
  721. const getCouponList = () => {
  722. // 调用获取优惠券API,传入预订单号
  723. getCouponsOrderPrice(preOrderNo.value).then((res) => {
  724. coupon.value.list = res.data; // 保存优惠券列表
  725. openType.value = 1; // 设置打开方式为"使用"
  726. });
  727. };
  728. // 获取默认地址或指定地址详情
  729. const getaddressInfo = () => {
  730. if (addressId.value) {
  731. // 若有指定地址ID,获取该地址详情
  732. getAddressDetail(addressId.value).then((res) => {
  733. if (res.data) {
  734. // 若地址存在
  735. res.data.isDefault = parseInt(res.data.isDefault); // 转换默认地址标识为数字
  736. addressInfo.value = res.data || {}; // 保存地址详情
  737. addressId.value = res.data.id || 0; // 更新地址ID
  738. address.value.addressId = res.data.id || 0; // 更新选中地址ID
  739. }
  740. });
  741. } else {
  742. // 若没有指定地址ID,获取默认地址
  743. getAddressDefault().then((res) => {
  744. // 注意:原代码中未导入getAddressDefault,可能是遗漏
  745. if (res.data) {
  746. // 若默认地址存在
  747. res.data.isDefault = parseInt(res.data.isDefault);
  748. addressInfo.value = res.data || {};
  749. addressId.value = res.data.id || 0;
  750. address.value.addressId = res.data.id || 0;
  751. }
  752. });
  753. }
  754. };
  755. // 选择支付方式
  756. const payItem = (e) => {
  757. let activeValue = e;
  758. active.value = activeValue;
  759. animated.value = true;
  760. payType.value = payments.value[activeValue].value;
  761. userSelectPayTypeItem.value = payments.value[activeValue];
  762. computedPrice();
  763. setTimeout(() => {
  764. car();
  765. }, 500);
  766. };
  767. // 打开优惠券弹窗
  768. const couponTap = () => {
  769. // coupon.value.coupon = true;
  770. showCouponPopup.value = true;
  771. if (!coupon.value.list.length) getCouponList();
  772. // getCouponList();
  773. };
  774. // 关闭支付方式选择动画
  775. const car = () => {
  776. animated.value = false; // 关闭动画
  777. };
  778. // 打开地址选择弹窗
  779. const onAddress = () => {
  780. textareaStatus.value = false; // 隐藏备注框
  781. address.value.address = true; // 显示地址弹窗
  782. // 设置地址页面跳转链接(携带预订单号)
  783. pagesUrl.value =
  784. "/pages/users/user_address_list/index?preOrderNo=" + preOrderNo.value;
  785. };
  786. // 联系人输入事件(保存联系人)
  787. const realName = (e) => {
  788. contacts.value = e.detail.value;
  789. };
  790. // 联系人电话输入事件(保存电话)
  791. const phone = (e) => {
  792. contactsTel.value = e.detail.value;
  793. };
  794. // 创建订单并发起支付
  795. const payment = (data) => {
  796. // 调用创建订单API
  797. orderCreate(data)
  798. .then((res) => {
  799. // 订单创建成功
  800. // 调用支付流程,传入订单号和成功提示
  801. getOrderPay(res.data.orderNo, "支付成功");
  802. })
  803. .catch((err) => {
  804. // 订单创建失败
  805. console.error("payment error", err); // 打印错误
  806. uni.hideLoading(); // 隐藏加载中
  807. Toast({ title: err }); // 提示错误
  808. });
  809. };
  810. // 处理支付流程(根据支付类型发起支付并处理结果)
  811. const getOrderPay = async (orderNo, message) => {
  812. // 支付结果页地址(携带订单号)
  813. const goPages = "/pages/order_pay_status/index?order_id=" + orderNo;
  814. try {
  815. // 调用微信支付配置API(获取支付参数)
  816. const res = await wechatOrderPay({
  817. mallType: orderInfoVo.value.mallType,
  818. orderNo: orderNo,
  819. // payChannel: payChannel.value,
  820. payChannel: userSelectPayTypeItem.value.payChannel,
  821. payType: payType.value,
  822. scene: appStore.productTypeComputed === "normal" ? 0 : 1177, // 下单时小程序的场景值
  823. });
  824. console.log("res-------------", res.data);
  825. let jsConfig = res.data.prepayWithRequestPaymentResponse;
  826. switch (res.data.payType) {
  827. case "alipay":
  828. // 发起支付宝支付
  829. const result = await submitPayment({
  830. type: res.data.payType, // 支付类型
  831. orderInfo: res.data.alipayRequest, // 支付宝支付参数
  832. });
  833. console.log("result", result); // 打印支付结果
  834. // 失败提示信息(默认"支付失败")
  835. let failMsg = result?.message || paymentConfig.PAYMENT_STATUS.FAIL;
  836. // 根据支付结果处理
  837. if (result.status === paymentConfig.PAYMENT_STATUS.SUCCESS) {
  838. // 支付成功:查询后端支付状态
  839. const params = {
  840. orderNo: orderNo,
  841. payType: "alipay",
  842. };
  843. console.log("进入成功判断", params);
  844. const res = await alipayPaymentResult(params); // 调用查询接口
  845. console.log("alipayPaymentResult", res);
  846. // 提示成功并跳转到结果页
  847. return Toast(
  848. { title: paymentConfig.PAYMENT_STATUS.SUCCESS, icon: "success" },
  849. { tab: 4, url: goPages }
  850. );
  851. } else if (result.status === paymentConfig.PAYMENT_STATUS.FAIL) {
  852. // 支付失败:提示并跳转
  853. return Toast(
  854. { title: paymentConfig.PAYMENT_STATUS.FAIL },
  855. { tab: 5, url: `${goPages}&msg=${failMsg}` }
  856. );
  857. } else if (result.status === paymentConfig.PAYMENT_STATUS.CANCEL) {
  858. // 支付取消:提示并跳转
  859. return Toast(
  860. { title: paymentConfig.PAYMENT_STATUS.CANCEL },
  861. {
  862. tab: 5,
  863. url: `${goPages}&msg=${paymentConfig.PAYMENT_STATUS.CANCEL}`,
  864. }
  865. );
  866. }
  867. break;
  868. case "yue":
  869. // 余额支付:直接提示成功并跳转
  870. console.log("余额支付");
  871. return Toast(
  872. { title: message },
  873. { tab: 5, url: goPages + "&status=1" }
  874. );
  875. break;
  876. case "weixinApp":
  877. const wxPayResult = await submitPayment({
  878. type: res.data.payType,
  879. orderInfo: res.data.prepayWithRequestPaymentResponse,
  880. });
  881. let wxPayFailMsg =
  882. wxPayResult?.message || paymentConfig.PAYMENT_STATUS.FAIL;
  883. if (wxPayResult.status === paymentConfig.PAYMENT_STATUS.SUCCESS) {
  884. // 查询后端支付状态接口
  885. let params = {
  886. orderNo: orderNo,
  887. payType: "weixinApp",
  888. };
  889. let res = await alipayPaymentResult(params);
  890. return Toast(
  891. { title: paymentConfig.PAYMENT_STATUS.SUCCESS, icon: "success" },
  892. { tab: 4, url: goPages }
  893. );
  894. } else if (wxPayResult.status === paymentConfig.PAYMENT_STATUS.FAIL) {
  895. return Toast(
  896. { title: paymentConfig.PAYMENT_STATUS.FAIL },
  897. { tab: 5, url: `${goPages}&msg=${wxPayFailMsg}` }
  898. );
  899. } else if (wxPayResult.status === paymentConfig.PAYMENT_STATUS.CANCEL) {
  900. return Toast(
  901. { title: paymentConfig.PAYMENT_STATUS.CANCEL },
  902. {
  903. tab: 5,
  904. url: `${goPages}&msg=${paymentConfig.PAYMENT_STATUS.CANCEL}`,
  905. }
  906. );
  907. }
  908. break;
  909. }
  910. uni.hideLoading(); // 隐藏加载中
  911. } catch (error) {
  912. // 支付过程出错
  913. console.error("getOrderPay error", error, typeof error);
  914. let msg = "";
  915. // 处理错误信息
  916. if (typeof error === "string") {
  917. msg = error;
  918. } else if (typeof error === "object" && error.message) {
  919. msg = error.message;
  920. } else {
  921. msg = "支付失败,请稍后再试";
  922. }
  923. uni.hideLoading(); // 隐藏加载中
  924. // 跳转到结果页并携带错误信息
  925. uni.navigateTo({
  926. url: `/pages/order_pay_status/index?order_id=${orderNo}&msg=${msg}`,
  927. });
  928. return Toast({ title: msg }); // 提示错误
  929. }
  930. };
  931. function modalConfirm() {
  932. showModal.value = false;
  933. uni.navigateTo({
  934. url: "/pages/users/vault/recharge",
  935. });
  936. }
  937. const SubOrder = async (e) => {
  938. console.log("SubOrder", payType.value);
  939. // if (payType.value == "alipay") {
  940. // return Toast({ title: "暂不支持支付宝支付,请使用余额支付" });
  941. // }
  942. let data = {}; // 订单提交数据
  943. // 验证:必须选择支付方式
  944. if (!payType.value) return Toast({ title: "请选择支付方式" });
  945. // 验证:快递配送时必须选择地址
  946. if (!address.value.addressId && !shippingType.value) {
  947. return Toast({ title: "请选择收货地址" });
  948. }
  949. try {
  950. const channels = await getAvailableChannels();
  951. if (payType.value === "alipay" && !channels.includes("alipay")) {
  952. return Toast({ title: "设备不支持支付宝支付" });
  953. } else if (payType.value === "weixin" && !channels.includes("wxpay")) {
  954. return Toast({ title: "设备不支持微信支付" });
  955. }
  956. } catch (error) {
  957. console.error("获取支付渠道失败", error);
  958. return Toast({ title: "获取支付渠道失败" });
  959. }
  960. // 构造订单提交数据
  961. data = {
  962. mallType: orderInfoVo.value.mallType,
  963. realName: contacts.value,
  964. phone: contactsTel.value,
  965. addressId: address.value.addressId,
  966. couponId: couponId.value,
  967. payType: payType.value,
  968. useIntegral: useIntegral.value,
  969. preOrderNo: preOrderNo.value,
  970. mark: mark.value,
  971. // storeId: system_store.value.id || 0,
  972. shippingType: util.$h.Add(shippingType.value, 1),
  973. // payChannel: payChannel.value || "weixinh5",
  974. payChannel: userSelectPayTypeItem.value.payChannel,
  975. };
  976. console.log(" data.payType", data.payType);
  977. // 验证:贝币支付时余额是否充足
  978. if (
  979. orderInfoVo.value.mallType === 1 &&
  980. Number(orderInfoVo.value.proTotalFee) > orderInfoVo.value.userIntegral
  981. ) {
  982. return Toast({ title: "贝币余额不足!" });
  983. }
  984. // 验证:余额支付时余额是否充足
  985. else if (
  986. data.payType == "yue" &&
  987. parseFloat(appStore.$userInfo.nowMoney) <
  988. parseFloat(orderInfoVo.value.payFee)
  989. ) {
  990. // 余额不足
  991. showModal.value = true;
  992. return;
  993. }
  994. uni.showLoading({
  995. title: "订单支付中",
  996. });
  997. // 发起支付
  998. payment(data);
  999. };
  1000. </script>
  1001. <style lang="scss" scoped>
  1002. .order-submission {
  1003. .line {
  1004. width: 100%;
  1005. height: 3rpx;
  1006. image {
  1007. width: 100%;
  1008. height: 100%;
  1009. display: block;
  1010. }
  1011. }
  1012. .allAddress {
  1013. width: 100%;
  1014. // background-image: linear-gradient(to bottom, #f0cb88 0%, transparent 100%);
  1015. background: $uni-bg-primary;
  1016. padding: 100rpx 30rpx 0 30rpx;
  1017. .nav {
  1018. width: 690rpx;
  1019. margin: 0 auto;
  1020. .item {
  1021. width: 334rpx;
  1022. &.on {
  1023. position: relative;
  1024. width: 230rpx;
  1025. &::before {
  1026. position: absolute;
  1027. bottom: 0;
  1028. content: "快递配送";
  1029. font-size: 28rpx;
  1030. display: block;
  1031. height: 0;
  1032. width: 336rpx;
  1033. border-width: 0 20rpx 80rpx 0;
  1034. border-style: none solid solid;
  1035. border-color: transparent transparent #fff;
  1036. z-index: 2;
  1037. border-radius: 14rpx 36rpx 0 0;
  1038. text-align: center;
  1039. line-height: 80rpx;
  1040. }
  1041. }
  1042. &:nth-of-type(2).on::before {
  1043. content: "到店自提";
  1044. border-width: 0 0 80rpx 20rpx;
  1045. border-radius: 36rpx 14rpx 0 0;
  1046. }
  1047. &.on2 {
  1048. position: relative;
  1049. &::before {
  1050. position: absolute;
  1051. bottom: 0;
  1052. content: "到店自提";
  1053. font-size: 28rpx;
  1054. display: block;
  1055. height: 0;
  1056. width: 401rpx;
  1057. border-width: 0 0 60rpx 60rpx;
  1058. border-style: none solid solid;
  1059. border-color: transparent transparent #f7c1bd;
  1060. border-radius: 36rpx 14rpx 0 0;
  1061. text-align: center;
  1062. line-height: 60rpx;
  1063. }
  1064. }
  1065. &:nth-of-type(1).on2::before {
  1066. content: "快递配送";
  1067. border-width: 0 60rpx 60rpx 0;
  1068. border-radius: 14rpx 36rpx 0 0;
  1069. }
  1070. }
  1071. }
  1072. .address {
  1073. width: 690rpx;
  1074. max-height: 180rpx;
  1075. margin: 0 auto;
  1076. padding: 28rpx;
  1077. background-color: #fff;
  1078. box-sizing: border-box;
  1079. .addressCon {
  1080. width: 596rpx;
  1081. font-size: 26rpx;
  1082. color: #666;
  1083. .name {
  1084. font-size: 30rpx;
  1085. color: #282828;
  1086. font-weight: bold;
  1087. margin-bottom: 10rpx;
  1088. .phone {
  1089. margin-left: 50rpx;
  1090. }
  1091. }
  1092. .default {
  1093. margin-right: 12rpx;
  1094. }
  1095. .setaddress {
  1096. color: #333;
  1097. font-size: 28rpx;
  1098. }
  1099. }
  1100. .iconfont {
  1101. font-size: 35rpx;
  1102. color: #707070;
  1103. }
  1104. }
  1105. .line {
  1106. width: 100%;
  1107. margin: 0 auto;
  1108. }
  1109. }
  1110. .wrapper {
  1111. background-color: #fff;
  1112. margin-top: 15rpx;
  1113. .item {
  1114. padding: 27rpx 24rpx;
  1115. font-size: 30rpx;
  1116. color: #333333;
  1117. border-bottom: 1px solid #f5f5f5;
  1118. .zf-box {
  1119. display: flex;
  1120. justify-content: space-between;
  1121. align-items: center;
  1122. }
  1123. .swicth-box {
  1124. display: flex;
  1125. justify-content: space-between;
  1126. align-items: center;
  1127. border: 2rpx solid #eee;
  1128. height: 86rpx;
  1129. font-size: 28rpx;
  1130. padding: 0 0 0 12%;
  1131. box-sizing: border-box;
  1132. margin: 20rpx 0;
  1133. border-radius: 14rpx;
  1134. .lable-box {
  1135. display: flex;
  1136. align-items: center;
  1137. .iconfont {
  1138. width: 44rpx;
  1139. height: 44rpx;
  1140. border-radius: 50%;
  1141. text-align: center;
  1142. line-height: 44rpx;
  1143. background-color: #fe960f;
  1144. color: #fff;
  1145. font-size: 30rpx;
  1146. margin-right: 15rpx;
  1147. &.icon-touzijintiao1 {
  1148. background-color: #f0cb88;
  1149. }
  1150. }
  1151. .lable-icon {
  1152. display: flex;
  1153. flex-direction: column;
  1154. justify-content: center;
  1155. }
  1156. .value {
  1157. font-size: 20rpx;
  1158. color: #fe960f;
  1159. }
  1160. }
  1161. }
  1162. .discount {
  1163. font-size: 30rpx;
  1164. color: #333;
  1165. .iconfont {
  1166. color: #515151;
  1167. font-size: 30rpx;
  1168. margin-left: 15rpx;
  1169. }
  1170. .num {
  1171. font-size: 32rpx;
  1172. margin-right: 20rpx;
  1173. }
  1174. .placeholder {
  1175. color: #ccc;
  1176. }
  1177. }
  1178. .shipping {
  1179. font-size: 30rpx;
  1180. color: #999;
  1181. position: relative;
  1182. padding-right: 58rpx;
  1183. .iconfont {
  1184. font-size: 35rpx;
  1185. color: #707070;
  1186. position: absolute;
  1187. right: 0;
  1188. top: 50%;
  1189. transform: translateY(-50%);
  1190. margin-left: 30rpx;
  1191. }
  1192. }
  1193. textarea {
  1194. background-color: #f9f9f9;
  1195. width: auto !important;
  1196. height: 140rpx;
  1197. border-radius: 14rpx;
  1198. margin-top: 30rpx;
  1199. padding: 15rpx;
  1200. box-sizing: border-box;
  1201. font-weight: 400;
  1202. }
  1203. .placeholder {
  1204. color: #ccc;
  1205. }
  1206. .list {
  1207. margin-top: 35rpx;
  1208. .payItem {
  1209. border: 1px solid #eee;
  1210. border-radius: 14rpx;
  1211. height: 86rpx;
  1212. width: 100%;
  1213. box-sizing: border-box;
  1214. margin-top: 20rpx;
  1215. font-size: 28rpx;
  1216. color: #282828;
  1217. &.on {
  1218. border-color: #fc5445;
  1219. color: $theme-color;
  1220. }
  1221. .name {
  1222. flex: 1;
  1223. // width: 50%;
  1224. text-align: center;
  1225. border-right: 1px solid #eee;
  1226. justify-content: flex-start;
  1227. padding: 0 0 0 12%;
  1228. .iconfont {
  1229. width: 44rpx;
  1230. height: 44rpx;
  1231. border-radius: 50%;
  1232. text-align: center;
  1233. line-height: 44rpx;
  1234. background-color: #fe960f;
  1235. color: #fff;
  1236. font-size: 30rpx;
  1237. margin-right: 15rpx;
  1238. &.icon-wechat {
  1239. background-color: #41b035;
  1240. }
  1241. &.icon-zhifubao {
  1242. background-color: #06b4fd;
  1243. }
  1244. }
  1245. }
  1246. .tip {
  1247. width: 49%;
  1248. text-align: center;
  1249. font-size: 26rpx;
  1250. color: #aaa;
  1251. }
  1252. }
  1253. }
  1254. }
  1255. }
  1256. .moneyList {
  1257. margin-top: 15rpx;
  1258. background-color: #fff;
  1259. padding: 30rpx;
  1260. .item {
  1261. font-size: 28rpx;
  1262. color: #282828;
  1263. & ~ .item {
  1264. margin-top: 20rpx;
  1265. }
  1266. .money {
  1267. color: #666666;
  1268. }
  1269. }
  1270. }
  1271. .footer {
  1272. width: 100%;
  1273. height: 100rpx;
  1274. background-color: #fff;
  1275. padding: 0 30rpx;
  1276. font-size: 28rpx;
  1277. color: #333;
  1278. box-sizing: border-box;
  1279. position: fixed;
  1280. bottom: 0;
  1281. left: 0;
  1282. .settlement {
  1283. font-size: 30rpx;
  1284. color: #fff;
  1285. width: 240rpx;
  1286. height: 70rpx;
  1287. background-color: $theme-color;
  1288. border-radius: 50rpx;
  1289. text-align: center;
  1290. line-height: 70rpx;
  1291. z-index: 100;
  1292. }
  1293. .transparent {
  1294. opacity: 0;
  1295. }
  1296. }
  1297. }
  1298. .line2 {
  1299. width: 504rpx;
  1300. }
  1301. .textR {
  1302. text-align: right;
  1303. }
  1304. </style>