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

474 lines
11 KiB

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