敢为人鲜小程序前端代码仓库
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.

446 lines
10 KiB

5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
3 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
  1. <template>
  2. <view class="page">
  3. <!-- 导航栏 -->
  4. <navbar title=" " bgColor="#019245" color="#fff" />
  5. <!-- 搜索框 -->
  6. <view class="search-box" style="background-color: #fff; padding: 12rpx 20rpx 0rpx; ">
  7. <uv-search placeholder="搜索商品名" v-model="keyword" :showAction="false" actionText="" height="80rpx" animation
  8. bgColor="#F5F5F5" inputAlign="center" color="#000" placeholderColor="#979797"
  9. searchIconSize="50rpx"></uv-search>
  10. </view>
  11. <!-- 订单筛选 -->
  12. <view class="tabs">
  13. <uv-tabs :list="tabs" :activeStyle="{ color: '#019245'}" lineColor="#019245" :scrollable="false"
  14. :inactiveStyle="{color: 'black'}" lineHeight="6rpx" lineWidth="55rpx" :current="current"
  15. @tap="clickTabs" />
  16. </view>
  17. <!-- 团餐列表 -->
  18. <view class="group-meal-list">
  19. <view class="meal-item" v-for="(meal, index) in groupMeals" :key="index+meal.id">
  20. <view class="meal-name">{{ meal.name }}</view>
  21. <view class="meal-price">本单佣金合计: <text class="price-value">¥{{meal.price}}</text></view>
  22. <view class="meal-action">
  23. <button class="order-btn" @tap="viewOrder(meal)">查看订单</button>
  24. </view>
  25. </view>
  26. </view>
  27. <!-- 订单列表 -->
  28. <view class="order-list" v-if="false">
  29. <OrderItem v-for="(order, index) in orderList" :key="order.id" :order="order" @cancel="handleCancelOrder"
  30. @pay="handlePayOrder" @tap="goToOrderDetail(order)" />
  31. <view style="
  32. margin-top: 200rpx;
  33. min-width: 700rpx;">
  34. <uv-empty mode="order" v-if="orderList.length == 0"></uv-empty>
  35. </view>
  36. </view>
  37. <!-- <view class="list">
  38. <view class="item" v-for="(item, index) in list" @tap="toOrderDetail(item.id)" :key="index">
  39. <view class="content" :key="index" v-for="(good, index) in item.commonOrderSkuList">
  40. <view class="top">
  41. <view class="service">
  42. {{ good.title }}
  43. </view>
  44. <view class="status">
  45. <text> {{ tabs[Number(item.state) + 1].name }}</text>
  46. </view>
  47. </view>
  48. <view class="main">
  49. <view class="left">
  50. <image mode="aspectFill" :src="good.image && good.image.split(',')[0]"></image>
  51. </view>
  52. <view class="right">
  53. <view class="text-hidden-1">
  54. 客户姓名{{item.name}}
  55. </view>
  56. <view class="text-hidden-1">
  57. 下单时间{{item.createTime}}
  58. </view>
  59. <view class="text-hidden-1">
  60. 联系电话{{item.phone}}
  61. </view>
  62. </view>
  63. </view>
  64. </view>
  65. <view class="bottom">
  66. <view class="price">
  67. <text class="total-title">总价格</text>
  68. <text class="unit"></text>
  69. <text class="num">{{item.price}}</text>
  70. <text class="c-unit"></text>
  71. </view>
  72. <view @tap.stop="toPayOrder(item)" class="btn" v-if="item.state == 0">
  73. 立即付款
  74. </view>
  75. <view @tap.stop="cancelOrder(item)" class="btn" v-if="item.state == 0">
  76. 取消订单
  77. </view>
  78. <view class="btn" @tap.stop="confirmOrder(item)" v-if="item.state == 2">
  79. 确认收货
  80. </view>
  81. <view @tap.stop="$refs.customerServicePopup.open()" class="btn" v-if="item.state > 0">
  82. 联系客服
  83. </view>
  84. </view>
  85. </view>
  86. <view style="
  87. margin-top: 20rpx;
  88. min-width: 700rpx;">
  89. <uv-empty mode="list" v-if="list.length == 0"></uv-empty>
  90. </view>
  91. </view> -->
  92. <customerServicePopup ref="customerServicePopup" />
  93. <tabber select="order" />
  94. </view>
  95. </template>
  96. <script>
  97. import {
  98. mapGetters
  99. } from 'vuex'
  100. import mixinsList from '@/mixins/list.js'
  101. import mixinsOrder from '@/mixins/order.js'
  102. import tabber from '@/components/base/tabbar.vue'
  103. import customerServicePopup from '@/components/config/customerServicePopup.vue'
  104. import OrderItem from '@/components/order/OrderItem.vue'
  105. import { mockOrders, mockGroupMeals} from '@/static/js/mockOrders.js'
  106. export default {
  107. mixins: [mixinsList, mixinsOrder],
  108. components: {
  109. tabber,
  110. customerServicePopup,
  111. OrderItem
  112. },
  113. computed: {},
  114. data() {
  115. return {
  116. keyword: '',
  117. tabs: [{
  118. name: '待支付'
  119. },
  120. {
  121. name: '待出餐'
  122. },
  123. {
  124. name: '送餐中'
  125. },
  126. {
  127. name: '待取餐'
  128. },
  129. {
  130. name: '已完成'
  131. }
  132. ],
  133. statusMap: {
  134. 0: 'pending', // 待支付
  135. 1: 'processing', // 待出餐
  136. 2: 'shipping', // 送餐中
  137. 3: 'delivered', // 待取餐
  138. 4: 'completed' // 已完成
  139. },
  140. current: 0,
  141. mixinsListApi: 'getOrderPageList',
  142. orderList: [],
  143. groupMeals: []
  144. }
  145. },
  146. onLoad(args) {
  147. // this.current = args.type || 0
  148. // this.clickTabs({
  149. // index: this.current
  150. // })
  151. if (args.status) {
  152. // 因为传过来的是状态 所以需要 遍历Map找到下标
  153. for (const key in this.statusMap) {
  154. if (this.statusMap[key] === args.status) {
  155. this.current = Number(key)
  156. break
  157. }
  158. }
  159. this.clickTabs({
  160. index: this.current
  161. })
  162. }
  163. // 加载模拟订单数据
  164. this.loadMockOrders()
  165. this.filterOrdersByStatus(this.current)
  166. },
  167. methods: {
  168. //点击tab栏
  169. clickTabs({
  170. index
  171. }) {
  172. if (index == 0) {
  173. delete this.queryParams.state
  174. } else {
  175. this.queryParams.state = index - 1
  176. }
  177. // 关闭请求
  178. // this.getData()
  179. // 模拟根据状态筛选订单
  180. this.filterOrdersByStatus(index)
  181. },
  182. // 跳转到新订单详情页
  183. goToOrderDetail(order) {
  184. if (order.status === 'completed') {
  185. this.$utils.navigateTo({
  186. url: '/pages_order/order/newOrderDetail?id=' + order.id + '&status=' + order.status
  187. })
  188. } else {
  189. this.$utils.navigateTo({
  190. url: '/pages_order/order/newOrderDetail?id=' + order.id + '&status=' + order.status
  191. })
  192. }
  193. },
  194. // 查看团餐订单
  195. viewOrder(meal) {
  196. this.$utils.navigateTo({
  197. url: '/pages_order/order/groupMealDetail?id=' + meal.id + '&status=' + meal.status
  198. })
  199. },
  200. // 加载模拟订单数据
  201. loadMockOrders() {
  202. this.orderList = mockOrders
  203. this.groupMeals = mockGroupMeals
  204. },
  205. // 根据状态筛选订单
  206. filterOrdersByStatus(index) {
  207. this.loadMockOrders() // 先重置数据
  208. // if (index === 0) return // 全部订单不需要筛选
  209. const targetStatus = this.statusMap[index]
  210. if (targetStatus) {
  211. this.orderList = this.orderList.filter(order => order.status === targetStatus)
  212. this.groupMeals = this.groupMeals.filter(meal => meal.status === targetStatus)
  213. }
  214. },
  215. // 处理取消订单
  216. handleCancelOrder(orderId) {
  217. uni.showModal({
  218. title: '提示',
  219. content: '确定要取消订单吗?',
  220. success: (res) => {
  221. if (res.confirm) {
  222. // 模拟取消订单API调用
  223. uni.showToast({
  224. title: '订单已取消',
  225. icon: 'success'
  226. })
  227. // 更新订单状态
  228. const orderIndex = this.orderList.findIndex(item => item.id === orderId)
  229. if (orderIndex !== -1) {
  230. this.orderList[orderIndex].status = 'canceled'
  231. // 如果当前标签页不是全部或已取消,则移除该订单
  232. if (this.current !== 0 && this.current !== 5) {
  233. this.orderList.splice(orderIndex, 1)
  234. }
  235. }
  236. }
  237. }
  238. })
  239. },
  240. // 处理支付订单
  241. handlePayOrder(orderId) {
  242. uni.showToast({
  243. title: '正在跳转支付...',
  244. icon: 'loading'
  245. })
  246. // 模拟支付操作,实际项目中应调用支付API
  247. setTimeout(() => {
  248. uni.hideToast()
  249. uni.showToast({
  250. title: '支付成功',
  251. icon: 'success'
  252. })
  253. // 更新订单状态
  254. const orderIndex = this.orderList.findIndex(item => item.id === orderId)
  255. if (orderIndex !== -1) {
  256. this.orderList[orderIndex].status = 'processing'
  257. // 如果当前标签页不是全部或待发货,则移除该订单
  258. if (this.current !== 0 && this.current !== 2) {
  259. this.orderList.splice(orderIndex, 1)
  260. }
  261. }
  262. }, 1500)
  263. }
  264. }
  265. }
  266. </script>
  267. <style scoped lang="scss">
  268. .page {}
  269. .tabs {
  270. background: #fff;
  271. padding-bottom: 4rpx;
  272. }
  273. .order-list {
  274. padding: 0 20rpx;
  275. // position: relative;
  276. }
  277. /* 团餐列表样式 */
  278. .group-meal-list {
  279. padding: 20rpx;
  280. }
  281. .meal-item {
  282. display: flex;
  283. justify-content: space-between;
  284. align-items: center;
  285. padding: 30rpx 20rpx;
  286. background-color: #fff;
  287. margin-bottom: 20rpx;
  288. border-radius: 10rpx;
  289. }
  290. .meal-info {
  291. flex: 1;
  292. }
  293. .meal-name {
  294. font-size: 32rpx;
  295. font-weight: 500;
  296. margin-bottom: 10rpx;
  297. }
  298. .meal-price {
  299. font-size: 28rpx;
  300. color: $uni-color;
  301. background-color: #ECFEF4;
  302. padding: 10rpx 20rpx;
  303. border-radius: 10rpx;
  304. }
  305. .price-value {
  306. margin-left: 10rpx;
  307. font-weight: 500;
  308. }
  309. .meal-action {
  310. margin-left: 20rpx;
  311. }
  312. .order-btn {
  313. background-color: $uni-color;
  314. color: #fff;
  315. font-size: 28rpx;
  316. padding: 10rpx 30rpx;
  317. border-radius: 30rpx;
  318. line-height: 1.5;
  319. min-width: 160rpx;
  320. }
  321. .list {
  322. .item {
  323. width: calc(100% - 40rpx);
  324. background-color: #fff;
  325. margin: 20rpx;
  326. box-sizing: border-box;
  327. border-radius: 16rpx;
  328. padding: 30rpx;
  329. .content {
  330. .top {
  331. display: flex;
  332. justify-content: space-between;
  333. align-items: center;
  334. font-size: 34rpx;
  335. .status {
  336. font-weight: 600;
  337. color: #FFAC2F;
  338. flex-shrink: 0;
  339. margin-left: 20rpx;
  340. }
  341. }
  342. .main {
  343. display: flex;
  344. margin: 20rpx 0rpx;
  345. .left {
  346. display: flex;
  347. align-items: center;
  348. justify-content: center;
  349. width: 180rpx;
  350. height: 180rpx;
  351. image {
  352. width: 95%;
  353. height: 95%;
  354. border-radius: 10rpx;
  355. }
  356. }
  357. .right {
  358. display: flex;
  359. flex-direction: column;
  360. justify-content: space-between;
  361. width: calc(100% - 200rpx);
  362. color: #777;
  363. font-size: 26rpx;
  364. padding: 30rpx 20rpx;
  365. box-sizing: border-box;
  366. margin-left: 20rpx;
  367. border-radius: 10rpx;
  368. background-color: #F8F8F8;
  369. }
  370. }
  371. }
  372. .bottom {
  373. display: flex;
  374. justify-content: space-between;
  375. font-size: 25rpx;
  376. .price {
  377. .total-title {}
  378. .num {
  379. font-size: 36rpx;
  380. }
  381. .num,
  382. .unit,
  383. .c-unit {
  384. color: $uni-color;
  385. }
  386. }
  387. .btn {
  388. border: 1px solid #C7C7C7;
  389. padding: 10rpx 20rpx;
  390. border-radius: 40rpx;
  391. color: #575757;
  392. }
  393. }
  394. }
  395. }
  396. </style>