confirm-order.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <template>
  2. <view class="confirm-order">
  3. <!-- 收货地址部分 -->
  4. <view class="section-card">
  5. <view class="flex-a flex-j-b mb-20" @click="handleAddress" v-if="defaultAddr.id">
  6. <image src="/pages-mine/static/adderss.png" style="width: 40rpx; height: 40rpx"></image>
  7. <view class="flex-d flex-1 ml-24" style="margin-right: 90rpx">
  8. <view class="flex-a flex-j-b mb-10">
  9. <view :style="titleStyle">收货人:{{ defaultAddr.name }}</view>
  10. <view :style="titleStyle">{{ defaultAddr.mobile }}</view>
  11. </view>
  12. <view :style="titleStyle">地址:{{ defaultAddr.fullAddress }}</view>
  13. </view>
  14. <u-icon name="arrow-right" :size="28" color="#666" top="4"></u-icon>
  15. </view>
  16. <view class="flex-a flex-j-b" @click="handleAddress" v-else>
  17. <view class="flex-a">
  18. <u-icon name="plus-circle-fill" :size="48" color="#38C148" top="2"></u-icon>
  19. <view :style="titleStyle" class="ml-10 font-30">添加收货地址</view>
  20. <text class="u-required">*</text>
  21. </view>
  22. <view class="flex-a">
  23. <view :style="titleStyle" class="ml-10">请添加</view>
  24. <u-icon name="arrow-right" :size="28" color="#666" top="4"></u-icon>
  25. </view>
  26. </view>
  27. </view>
  28. <!-- 商品列表 -->
  29. <view class="book-list">
  30. <buy-book-item v-for="(book, index) in books" :key="index" :book="book"></buy-book-item>
  31. </view>
  32. <!-- 订单信息 -->
  33. <view class="section-card mt-20" style="padding: 0; overflow: hidden;">
  34. <u-cell-group :border="false">
  35. <u-cell-item title="配送服务" value="快递 免邮" :arrow="false" :title-style="{ color: '#333' }"
  36. :value-style="{ color: '#333' }"></u-cell-item>
  37. <u-cell-item title="红包" :value="selectedPacket ? selectedPacket.name : ''" @click="showRedPacket = true"
  38. :title-style="{ color: '#333' }"></u-cell-item>
  39. <u-cell-item title="订单备注" :arrow="false" :title-style="{ color: '#333' }">
  40. <u-input slot="right-icon" v-model="submitData.remark" type="text" placeholder="无备注"
  41. input-align="right" :custom-style="{ color: '#999', minHeight: '28px' }" />
  42. </u-cell-item>
  43. <u-cell-item title="如遇缺货" :value="selectedStockOption.text || '其他商品继续发货'"
  44. @click="showStockShortage = true" :border-bottom="false"
  45. :title-style="{ color: '#ff4500', fontWeight: 'bold' }"></u-cell-item>
  46. </u-cell-group>
  47. </view>
  48. <!-- 底部栏 -->
  49. <view class="bottom-bar">
  50. <view class="order-summary">
  51. <view class="total">
  52. 共<text class="num">{{ totalNum }}</text>本
  53. <text class="reduce-text" v-if="totalReduced > 0">已降¥{{ totalReduced }}</text>
  54. 合计: <text class="price">¥{{ totalPrice }}</text>
  55. </view>
  56. <u-button type="primary" shape="circle" @click="submitOrder">提交订单</u-button>
  57. </view>
  58. </view>
  59. <submit-confirm ref="submitConfirmDialog" @confirm="handleConfirmSubmit"></submit-confirm>
  60. <red-packet-popup v-model="showRedPacket" @confirm="onRedPacketConfirm"></red-packet-popup>
  61. <stock-shortage-popup v-model="showStockShortage" @confirm="onStockShortageConfirm"></stock-shortage-popup>
  62. </view>
  63. </template>
  64. <script>
  65. import SubmitConfirm from "@/pages-car/components/submit-confirm.vue";
  66. import BuyBookItem from "@/pages-car/components/buy-book-item.vue";
  67. import RedPacketPopup from "@/pages-car/components/red-packet-popup.vue";
  68. import StockShortagePopup from "@/pages-car/components/stock-shortage-popup.vue";
  69. export default {
  70. components: {
  71. SubmitConfirm,
  72. BuyBookItem,
  73. RedPacketPopup,
  74. StockShortagePopup
  75. },
  76. data() {
  77. return {
  78. titleStyle: {
  79. "font-family": "PingFang SC",
  80. "font-weight": 400,
  81. color: "#333333",
  82. },
  83. books: [],
  84. defaultAddr: {},
  85. submitData: {
  86. addressId: "",
  87. remark: "",
  88. },
  89. totalNum: 0,
  90. totalPrice: 0,
  91. totalReduced: 0,
  92. btnStyle: {
  93. width: '240rpx',
  94. height: '80rpx',
  95. lineHeight: '80rpx',
  96. background: 'linear-gradient(90deg, #ff8c00, #ff4500)',
  97. color: '#fff',
  98. fontSize: '30rpx',
  99. margin: '0'
  100. },
  101. showRedPacket: false,
  102. showStockShortage: false,
  103. selectedPacket: null,
  104. selectedStockOption: { text: '其他商品继续发货(缺货商品退款)', value: 2 }
  105. };
  106. },
  107. methods: {
  108. //添加或者选择地址
  109. handleAddress() {
  110. uni.navigateTo({
  111. url: `/pages-mine/pages/address/list?id=${this.defaultAddr.id}&isSelect=1`,
  112. });
  113. },
  114. onRedPacketConfirm(packet) {
  115. this.selectedPacket = packet;
  116. // Recalculate price if needed
  117. },
  118. onStockShortageConfirm(option) {
  119. this.selectedStockOption = option;
  120. },
  121. submitOrder() {
  122. if (!this.submitData.addressId) {
  123. this.$u.toast("请选择收货地址");
  124. return;
  125. }
  126. // 显示确认弹窗
  127. this.$refs.submitConfirmDialog.openPopup();
  128. },
  129. // 确认提交订单
  130. handleConfirmSubmit() {
  131. // 处理订单提交
  132. uni.showToast({
  133. title: '订单提交成功',
  134. icon: "success",
  135. });
  136. setTimeout(() => {
  137. uni.redirectTo({
  138. url: "/pages-car/pages/my-order"
  139. });
  140. }, 1500);
  141. // uni.$u.http.post("/token/order/submitBuyOrder", this.submitData).then((res) => {
  142. // if (res.code == 200) {
  143. // uni.navigateTo({
  144. // url: "/pages-car/pages/pay-success",
  145. // });
  146. // } else {
  147. // uni.showToast({
  148. // title: res.msg,
  149. // icon: "none",
  150. // });
  151. // }
  152. // });
  153. },
  154. //获取默认地址
  155. getDefaultAddress() {
  156. // Mock default address
  157. this.defaultAddr = {
  158. id: '1',
  159. name: '张三',
  160. mobile: '18888888888',
  161. fullAddress: '北京市朝阳区xx街道xx小区1号楼101'
  162. };
  163. this.submitData.addressId = this.defaultAddr.id;
  164. // uni.$u.http.get("/token/user/address/getDefault").then((res) => {
  165. // if (res.code == 200) {
  166. // this.defaultAddr = res.data;
  167. // this.submitData.addressId = this.defaultAddr.id;
  168. // }
  169. // });
  170. },
  171. // 获取结算商品信息
  172. getCheckoutInfo() {
  173. // Mock books data
  174. this.books = [
  175. {
  176. title: '商品名称商品名称商品',
  177. cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg',
  178. quality: '中等',
  179. price: '0.01',
  180. originalPrice: '0.01',
  181. priceReduced: '0.5',
  182. num: 1
  183. },
  184. {
  185. title: '商品名称商品名称商品',
  186. cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg',
  187. quality: '中等',
  188. canReduce: '0.5',
  189. price: '0.01',
  190. originalPrice: '0.01',
  191. num: 1
  192. }
  193. ];
  194. this.totalNum = 2;
  195. this.totalPrice = '0.01';
  196. this.totalReduced = '1.01';
  197. }
  198. },
  199. mounted() {
  200. this.getDefaultAddress();
  201. this.getCheckoutInfo();
  202. },
  203. onShow() {
  204. let selectAddr = uni.getStorageSync("selectAddr");
  205. if (selectAddr) {
  206. this.defaultAddr = selectAddr;
  207. this.submitData.addressId = selectAddr.id;
  208. uni.removeStorageSync("selectAddr"); // Clear after use
  209. }
  210. },
  211. };
  212. </script>
  213. <style lang="scss">
  214. .confirm-order {
  215. min-height: 100vh;
  216. background: #f5f5f5;
  217. padding: 20rpx 30rpx;
  218. padding-bottom: calc(env(safe-area-inset-bottom) + 120rpx);
  219. }
  220. .section-card {
  221. background: #fff;
  222. margin-bottom: 20rpx;
  223. padding: 30rpx;
  224. border-radius: 16rpx;
  225. box-sizing: border-box;
  226. }
  227. .u-required {
  228. color: #ff0000;
  229. margin-left: 8rpx;
  230. }
  231. .book-list {
  232. background: #fff;
  233. border-radius: 16rpx;
  234. margin-bottom: 20rpx;
  235. }
  236. .info-row {
  237. display: flex;
  238. justify-content: space-between;
  239. align-items: center;
  240. padding: 20rpx 0;
  241. font-size: 28rpx;
  242. color: #333;
  243. .label {
  244. &.red-label {
  245. color: #ff4500;
  246. font-weight: bold;
  247. }
  248. }
  249. .value {
  250. &.text-gray {
  251. color: #999;
  252. }
  253. }
  254. .mr-10 {
  255. margin-right: 10rpx;
  256. }
  257. }
  258. .bottom-bar {
  259. position: fixed;
  260. bottom: 0;
  261. left: 0;
  262. right: 0;
  263. background: #fff;
  264. padding: 20rpx 30rpx;
  265. padding-bottom: env(safe-area-inset-bottom);
  266. box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
  267. .order-summary {
  268. display: flex;
  269. justify-content: space-between;
  270. align-items: center;
  271. .total {
  272. font-size: 28rpx;
  273. color: #666;
  274. .num {
  275. color: #333;
  276. font-weight: bold;
  277. margin: 0 4rpx;
  278. }
  279. .reduce-text {
  280. color: #38C148;
  281. margin-left: 10rpx;
  282. margin-right: 10rpx;
  283. background-color: #e6f9e9;
  284. padding: 4rpx 10rpx;
  285. border-radius: 4rpx;
  286. font-size: 24rpx;
  287. }
  288. .price {
  289. font-size: 36rpx;
  290. color: #ff4500;
  291. font-weight: bold;
  292. margin-left: 10rpx;
  293. }
  294. }
  295. }
  296. }
  297. .mt-20 {
  298. margin-top: 20rpx;
  299. }
  300. .ml-10 {
  301. margin-left: 10rpx;
  302. }
  303. </style>