敢为人鲜小程序前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

509 lines
13 KiB

  1. <template>
  2. <view class="page">
  3. <!-- 导航栏 -->
  4. <navbar :title="orderStatus === 'pending' ? '待支付订单' : '订单详情' " leftClick @leftClick="navigateBack" bgColor="#019245"
  5. color="#fff" />
  6. <!-- 店铺信息 -->
  7. <view class="shop-info">
  8. <view class="shop-header">
  9. <image class="shop-logo" :src="teamLeader.spotImage" mode="aspectFill"></image>
  10. <view class="shop-name-container">
  11. <text class="shop-name"> {{ teamLeader.spotName }} </text>
  12. <view class="shop-address">
  13. <view style="padding-top: 7rpx;">
  14. <!-- 需要置顶 -->
  15. <uv-icon name="map-fill" color="#019245" size="28rpx"></uv-icon>
  16. </view>
  17. <text class="address-text">{{ teamLeader.area }} {{ teamLeader.address }}</text>
  18. </view>
  19. <view class="shop-phone">
  20. <view style="padding-top: 7rpx;">
  21. <!-- 需要置顶 -->
  22. <uv-icon name="phone-fill" color="#019245" size="28rpx"></uv-icon>
  23. </view>
  24. <text class="phone-text">{{teamLeader.phone}}</text>
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. <view class="order-status">
  30. <!-- 商品列表 -->
  31. <view class="food-list">
  32. <view class="food-item" v-for="(food, index) in showedFoods" :key="food.id">
  33. <image class="food-image" :src="food.goods.image" mode="aspectFill" />
  34. <view class="food-info">
  35. <text class="food-name">{{food.goods.title}}</text>
  36. <view class="food-sold">
  37. <uv-icon name="bag" size="28rpx"></uv-icon>
  38. <text>已售出 {{ food.goods.sales }}</text>
  39. </view>
  40. <text class="food-price"> <text style="font-size: 20rpx;"></text> {{food.goods.price}}</text>
  41. <text class="food-count">×{{food.num}}</text>
  42. </view>
  43. </view>
  44. <view class="expand-more" @tap="showAllFoods = !showAllFoods" v-if="orderDetail.goodsList.length > 3">
  45. <text>{{showAllFoods ? '收起' : '展开'}} ({{orderDetail.goodsList.length}})</text>
  46. <uv-icon :name="showAllFoods ? 'arrow-up' : 'arrow-down'" size="28rpx"></uv-icon>
  47. </view>
  48. </view>
  49. <!-- 订单信息 -->
  50. <view class="order-info">
  51. <view class="info-item">
  52. <text class="info-label">合计:</text>
  53. <text class="info-value price">{{ orderDetail.priceAll }}</text>
  54. </view>
  55. <view class="info-item">
  56. <text class="info-label">创建时间:</text>
  57. <text class="info-value">{{ orderDetail.createTime }}</text>
  58. </view>
  59. <view class="info-item">
  60. <text class="info-label">订单编号:</text>
  61. <text class="info-value">{{orderDetail.id}}</text>
  62. </view>
  63. </view>
  64. </view>
  65. <view class="discount-info-container">
  66. <!-- 优惠信息 -->
  67. <view class="discount-info">
  68. <view class="discount-header">
  69. <text>优惠</text>
  70. </view>
  71. <view class="discount-item">
  72. <view class="discount-left">
  73. <image src="@/static/image/券.webp" mode="aspectFill" class="coupon-icon" />
  74. <view>新用户立减</view>
  75. </view>
  76. <text class="discount-amount">-{{ orderDetail.pricePreferential }}</text>
  77. </view>
  78. </view>
  79. <!-- 备注 -->
  80. <view class="remark-section">
  81. <view class="remark-header">
  82. <text>备注</text>
  83. </view>
  84. <view class="remark-content">
  85. <input v-if="orderDetail.status_dictText === '待支付'" type="text" v-model="orderDetail.remark"
  86. placeholder="请输入您要备注的内容" placeholder-style="font-size: 28rpx" />
  87. <text v-else>{{orderDetail.remark || '无备注信息'}}</text>
  88. </view>
  89. </view>
  90. </view>
  91. <!-- 支付方式 -->
  92. <uv-radio-group v-model="payMethod" v-if="orderDetail.status_dictText === '待支付'">
  93. <view class="payment-methods">
  94. <view class="payment-item">
  95. <uv-icon name="weixin-circle-fill" size="70rpx" color="#019245"></uv-icon>
  96. <text class="payment-name">微信支付</text>
  97. <uv-radio activeColor="#019245" size="40rpx" name="weixin"></uv-radio>
  98. </view>
  99. <view class="payment-item">
  100. <uv-icon name="red-packet" size="70rpx" color="#019245"></uv-icon>
  101. <text class="payment-name">账户余额<text class="balance-text">(余额: {{ userInfo.balance }})</text></text>
  102. <uv-radio activeColor="#019245" size="40rpx" name="account" />
  103. </view>
  104. </view>
  105. </uv-radio-group>
  106. <!-- 底部支付栏 -->
  107. <view class="bottom-bar">
  108. <view class="total-section">
  109. <text class="total-label">{{ orderDetail.goodsList.length || 0 }}<text style="color: black;">合计</text> </text>
  110. <text class="total-price">{{ orderDetail.pricePay }}</text>
  111. </view>
  112. <view class="pay-button" @tap="handlePay" v-if="orderStatus === '待支付'">立即下单</view>
  113. <view class="pay-button" @tap="handlePay" v-if="orderStatus === '已送达'">立即取餐</view>
  114. </view>
  115. </view>
  116. </template>
  117. <script>
  118. import navbar from '@/components/base/navbar.vue'
  119. export default {
  120. components: {
  121. navbar
  122. },
  123. data() {
  124. return {
  125. id: '',
  126. payMethod: 'weixin',
  127. showAllFoods: false,
  128. orderStatus: '',
  129. orderDetail: { }
  130. }
  131. },
  132. computed: {
  133. statusText() {
  134. const statusMap = {
  135. 'pending': '等待支付',
  136. 'processing': '正在出餐',
  137. 'shipping': '正在配送中',
  138. 'delivered': '已送达,等待取餐',
  139. 'completed': '订单已完成',
  140. 'canceled': '订单已取消'
  141. }
  142. return statusMap[this.orderDetail.status] || '等待支付'
  143. },
  144. showedFoods() {
  145. return this.showAllFoods ? this.orderDetail.goodsList : this.orderDetail.goodsList.slice(0, 3)
  146. },
  147. teamLeader() {
  148. return this.orderDetail.teamLeader
  149. }
  150. },
  151. onLoad(options) {
  152. if (options.id) {
  153. this.getOrderDetail(options.id)
  154. }
  155. this.orderStatus = options.status
  156. },
  157. methods: {
  158. // 返回上一页
  159. navigateBack() {
  160. uni.navigateBack()
  161. },
  162. // 获取订单详情
  163. getOrderDetail(id) {
  164. this.id = id
  165. this.$api('queryMemberOrderList', {
  166. id: this.id
  167. }, res => {
  168. if (res.code === 200) {
  169. this.orderDetail = res.result.records[0]
  170. // console.log('111', this.orderDetail);
  171. console.log('222', this.showedFoods);
  172. }
  173. })
  174. },
  175. // 处理支付
  176. handlePay() {
  177. uni.showLoading({
  178. title: '支付处理中...'
  179. })
  180. // 模拟支付过程
  181. setTimeout(() => {
  182. uni.hideLoading()
  183. uni.showToast({
  184. title: '支付成功',
  185. icon: 'success',
  186. duration: 2000
  187. })
  188. // 支付成功后,跳转回订单列表页面,并刷新
  189. setTimeout(() => {
  190. this.navigateBack()
  191. // 页面栈中的order页面需要刷新
  192. const pages = getCurrentPages()
  193. const prevPage = pages[pages.length - 2]
  194. if (prevPage && prevPage.route.includes('order')) {
  195. // 更新上一页的数据
  196. prevPage.$vm.loadMockOrders()
  197. prevPage.$vm.filterOrdersByStatus(1) // 切换到待出餐Tab
  198. prevPage.$vm.current = 1 // 更新Tab索引
  199. }
  200. }, 1000)
  201. }, 2000)
  202. }
  203. }
  204. }
  205. </script>
  206. <style lang="scss" scoped>
  207. .page {
  208. background-color: #f5f5f5;
  209. min-height: 100vh;
  210. padding-bottom: 120rpx;
  211. }
  212. .status-bar {
  213. background-color: #019245;
  214. padding: 30rpx;
  215. color: #fff;
  216. font-size: 32rpx;
  217. font-weight: 500;
  218. }
  219. .shop-info {
  220. background-color: #fff;
  221. margin: 20rpx;
  222. border-radius: 16rpx;
  223. padding: 20rpx;
  224. .shop-header {
  225. display: flex;
  226. align-items: center;
  227. // background-color: red;
  228. .shop-logo {
  229. width: 150rpx;
  230. height: 150rpx;
  231. // border-radius: 10rpx;
  232. margin-right: 20rpx;
  233. }
  234. .shop-name-container {
  235. flex: 1;
  236. .shop-name {
  237. font-size: 30rpx;
  238. font-weight: 500;
  239. margin-bottom: 10rpx;
  240. display: block;
  241. }
  242. .shop-address, .shop-phone {
  243. display: flex;
  244. align-items: start;
  245. font-size: 24rpx;
  246. color: $uni-color-third;
  247. margin-top: 8rpx;
  248. .address-text, .phone-text {
  249. margin-left: 8rpx;
  250. width: 80%;
  251. white-space: wrap;
  252. // overflow: hidden;
  253. // text-overflow: ellipsis;
  254. }
  255. }
  256. .shop-address-top{
  257. display: flex;
  258. align-items: start;
  259. background-color: red;
  260. // gap: 10rpx;
  261. }
  262. }
  263. }
  264. }
  265. .order-status{
  266. background-color: #fff;
  267. margin: 20rpx;
  268. border-radius: 16rpx;
  269. padding: 20rpx;
  270. .food-list {
  271. // gap: 20rpx;
  272. // background-color: #019245;
  273. .food-item {
  274. display: flex;
  275. margin-bottom: 20rpx;
  276. // background-color: red;
  277. .food-image {
  278. width: 120rpx;
  279. height: 120rpx;
  280. // border-radius: 10rpx;
  281. margin-right: 20rpx;
  282. }
  283. .food-info {
  284. flex: 1;
  285. display: flex;
  286. flex-direction: column;
  287. justify-content: space-between;
  288. position: relative;
  289. .food-name {
  290. font-size: 28rpx;
  291. font-weight: 500;
  292. }
  293. .food-sold {
  294. display: flex;
  295. align-items: center;
  296. font-size: 24rpx;
  297. color: $uni-color-third;
  298. }
  299. .food-price {
  300. font-size: 28rpx;
  301. color: #f00;
  302. }
  303. .food-count {
  304. color: black;
  305. position: absolute;
  306. bottom: 50%;
  307. right: 0;
  308. }
  309. }
  310. }
  311. .expand-more {
  312. display: flex;
  313. align-items: center;
  314. justify-content: center;
  315. padding: 20rpx 0 0;
  316. font-size: 24rpx;
  317. color: $uni-color-third;
  318. }
  319. }
  320. .order-info {
  321. padding-top: 20rpx;
  322. .info-item {
  323. display: flex;
  324. justify-content: space-between;
  325. margin-bottom: 15rpx;
  326. font-size: 26rpx;
  327. .info-label {
  328. color: black;
  329. }
  330. .info-value {
  331. color: #333;
  332. &.price {
  333. color: #f00;
  334. font-weight: 500;
  335. }
  336. }
  337. }
  338. }
  339. }
  340. .discount-info-container {
  341. background-color: #fff;
  342. margin: 20rpx;
  343. border-radius: 16rpx;
  344. padding: 20rpx;
  345. display: flex;
  346. flex-direction: column;
  347. gap: 40rpx;
  348. }
  349. .discount-info {
  350. display: flex;
  351. align-items: center;
  352. justify-content: space-between;
  353. .discount-header {
  354. font-size: 28rpx;
  355. }
  356. .discount-item {
  357. display: flex;
  358. justify-content: space-between;
  359. align-items: center;
  360. gap: 20rpx;
  361. .discount-left {
  362. display: flex;
  363. align-items: center;
  364. gap: 10rpx;
  365. .coupon-icon {
  366. width: 36rpx;
  367. height: 36rpx;
  368. margin-top: 6rpx;
  369. }
  370. }
  371. .discount-amount {
  372. color: #f00;
  373. font-weight: 500;
  374. }
  375. }
  376. }
  377. .remark-section {
  378. display: flex;
  379. // flex-direction: column;
  380. gap: 40rpx;
  381. // background-color: red;
  382. align-items: center;
  383. .remark-header {
  384. font-size: 28rpx;
  385. // font-weight: 500;
  386. }
  387. .remark-content {
  388. font-size: 26rpx;
  389. color: black;
  390. min-height: 60rpx;
  391. display: flex;
  392. align-items: center;
  393. }
  394. }
  395. .payment-methods {
  396. background-color: #fff;
  397. width: 100%;
  398. margin: 20rpx;
  399. border-radius: 16rpx;
  400. padding: 20rpx;
  401. display: flex;
  402. flex-direction: column;
  403. gap: 20rpx;
  404. .payment-item {
  405. display: flex;
  406. align-items: center;
  407. padding: 20rpx 0;
  408. border-bottom: 1rpx solid #f5f5f5;
  409. &:last-child {
  410. border-bottom: none;
  411. }
  412. .payment-name {
  413. flex: 1;
  414. margin-left: 20rpx;
  415. font-size: 28rpx;
  416. .balance-text {
  417. font-size: 24rpx;
  418. color: $uni-color-third;
  419. margin-left: 10rpx;
  420. }
  421. }
  422. }
  423. }
  424. .bottom-bar {
  425. position: fixed;
  426. bottom: 0;
  427. left: 0;
  428. right: 0;
  429. height: 100rpx;
  430. background-color: #fff;
  431. display: flex;
  432. align-items: center;
  433. padding: 0 30rpx;
  434. box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
  435. .total-section {
  436. flex: 1;
  437. .total-label {
  438. font-size: 26rpx;
  439. color: $uni-color-third;
  440. }
  441. .total-price {
  442. font-size: 32rpx;
  443. color: #f00;
  444. margin-left: 10rpx;
  445. }
  446. }
  447. .pay-button {
  448. width: 240rpx;
  449. height: 80rpx;
  450. background-color: #019245;
  451. color: #fff;
  452. font-size: 30rpx;
  453. display: flex;
  454. align-items: center;
  455. justify-content: center;
  456. border-radius: 40rpx;
  457. }
  458. }
  459. </style>