index.vue 43 KB

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