| @ -0,0 +1,379 @@ | |||||
| <template> | |||||
| <view class="page"> | |||||
| <!-- 导航栏 --> | |||||
| <navbar title="订单管理" bgColor="#019245" color="#fff" /> | |||||
| <!-- 搜索框 --> | |||||
| <view style="background-color: #fff; padding: 12rpx 20rpx 0rpx; "> | |||||
| <uv-search placeholder="搜索商品名" v-model="keyword" :showAction="false" actionText="" height="80rpx" animation | |||||
| bgColor="#F5F5F5" inputAlign="center" color="#000" placeholderColor="#979797" searchIconSize="50rpx" | |||||
| @search="handleSearch" @clickIcon="handleSearch" /> | |||||
| </view> | |||||
| <!-- 订单筛选 --> | |||||
| <view class="tabs"> | |||||
| <uv-tabs :list="tabs" :activeStyle="{ color: '#019245'}" lineColor="#019245" :scrollable="false" | |||||
| :inactiveStyle="{color: 'black'}" lineHeight="6rpx" lineWidth="55rpx" :current="status" | |||||
| @click="clickTabs" /> | |||||
| </view> | |||||
| <!-- 批量操作区域 --> | |||||
| <view class="batch-actions" v-if="leaderOrderList.length > 0"> | |||||
| <checkbox-group @change="handleCheckAllChange"> | |||||
| <label class="checkbox-all"> | |||||
| <checkbox :checked="isAllChecked" color="#019245" /> | |||||
| <text>全选</text> | |||||
| </label> | |||||
| </checkbox-group> | |||||
| <view class="batch-btns"> | |||||
| <button class="batch-btn" @tap="handleBatchAction('出餐')" v-if="status === 0">批量出餐</button> | |||||
| <button class="batch-btn" @tap="handleBatchAction('取餐')" v-if="status === 1">批量待取餐</button> | |||||
| <button class="batch-btn" @tap="handleBatchAction('完成')" v-if="status === 2">批量完成</button> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 团餐列表 --> | |||||
| <view class="group-meal-list"> | |||||
| <view class="meal-item" v-for="(meal, index) in leaderOrderList" :key="meal.id"> | |||||
| <view class="meal-checkbox"> | |||||
| <checkbox :checked="checkedOrders.includes(meal.id)" :value="meal.id" color="#019245" @tap.stop="toggleCheckOrder(meal.id)" /> | |||||
| </view> | |||||
| <view class="meal-content" @tap="viewOrder(meal)"> | |||||
| <view class="meal-name">{{ meal.title }}</view> | |||||
| <view class="meal-price">本单佣金合计: <text class="price-value">¥{{ (meal.commission || 0).toFixed(2) || 0.00 }}</text> | |||||
| </view> | |||||
| </view> | |||||
| <view class="meal-action"> | |||||
| <button class="action-btn" @tap.stop="handleSingleAction(meal, '出餐')" v-if="status === 0">出餐</button> | |||||
| <button class="action-btn" @tap.stop="handleSingleAction(meal, '取餐')" v-if="status === 2">取餐</button> | |||||
| <button class="action-btn" @tap.stop="handleSingleAction(meal, '完成')" v-if="status === 2">完成</button> | |||||
| <button class="order-btn" @tap.stop="viewOrder(meal)">查看</button> | |||||
| </view> | |||||
| </view> | |||||
| <view style="margin-top: 200rpx; min-width: 700rpx;"> | |||||
| <uv-empty mode="order" v-if="leaderOrderList.length == 0" /> | |||||
| </view> | |||||
| </view> | |||||
| <tabber select="order" /> | |||||
| </view> | |||||
| </template> | |||||
| <script> | |||||
| import mixinsList from '@/mixins/list.js' | |||||
| import tabber from '@/components/base/tabbar.vue' | |||||
| export default { | |||||
| mixins: [mixinsList], | |||||
| components: { | |||||
| tabber | |||||
| }, | |||||
| data() { | |||||
| return { | |||||
| keyword: '', | |||||
| title: '', | |||||
| tabs: [ | |||||
| { name: '待出餐' }, | |||||
| { name: '已出餐' }, | |||||
| { name: '待取餐' }, | |||||
| { name: '已完成' } | |||||
| ], | |||||
| status: 0, | |||||
| leaderOrderList: [], | |||||
| mixinsListApi: 'managerOrderList', | |||||
| mixinsListKey: 'leaderOrderList', | |||||
| checkedOrders: [], // 已选择的订单ID | |||||
| isAllChecked: false | |||||
| } | |||||
| }, | |||||
| onLoad(args) { | |||||
| // 检查是否有tabIndex参数,如果有则自动切换到对应tab | |||||
| if (args.tabIndex !== undefined) { | |||||
| const index = parseInt(args.tabIndex) | |||||
| if (!isNaN(index) && index >= 0 && index < this.tabs.length) { | |||||
| this.status = index | |||||
| } | |||||
| } | |||||
| }, | |||||
| methods: { | |||||
| handleSearch() { | |||||
| this.title = this.keyword | |||||
| this.getData() | |||||
| this.keyword = '' | |||||
| this.title = '' | |||||
| }, | |||||
| beforeGetData() { | |||||
| const params = { | |||||
| status: this.status, | |||||
| title: this.title || '' | |||||
| } | |||||
| return params | |||||
| }, | |||||
| //点击tab栏 | |||||
| clickTabs({ index }) { | |||||
| this.status = index | |||||
| this.getData() | |||||
| this.checkedOrders = [] // 切换标签时清空选择 | |||||
| this.isAllChecked = false | |||||
| }, | |||||
| // 查看团餐订单 | |||||
| viewOrder(meal) { | |||||
| this.$utils.navigateTo({ | |||||
| url: '/pages_order/order/groupMealDetail?id=' + meal.id | |||||
| }) | |||||
| }, | |||||
| // 切换选择订单 | |||||
| toggleCheckOrder(id) { | |||||
| const index = this.checkedOrders.indexOf(id) | |||||
| if (index === -1) { | |||||
| this.checkedOrders.push(id) | |||||
| } else { | |||||
| this.checkedOrders.splice(index, 1) | |||||
| } | |||||
| // 更新全选状态 | |||||
| this.isAllChecked = this.checkedOrders.length === this.leaderOrderList.length | |||||
| }, | |||||
| // 处理全选/取消全选 | |||||
| handleCheckAllChange(e) { | |||||
| this.isAllChecked = !this.isAllChecked | |||||
| if (this.isAllChecked) { | |||||
| this.checkedOrders = this.leaderOrderList.map(item => item.id) | |||||
| } else { | |||||
| this.checkedOrders = [] | |||||
| } | |||||
| }, | |||||
| // 处理单个订单操作 | |||||
| handleSingleAction(meal, action) { | |||||
| const actionMap = { | |||||
| '出餐': { | |||||
| status: 1, | |||||
| confirmText: '确定将该订单标记为已出餐吗?', | |||||
| successText: '已出餐' | |||||
| }, | |||||
| '取餐': { | |||||
| status: 2, | |||||
| confirmText: '确定将该订单标记为待取餐吗?', | |||||
| successText: '待取餐' | |||||
| }, | |||||
| '完成': { | |||||
| status: 3, | |||||
| confirmText: '确定将该订单标记为已完成吗?', | |||||
| successText: '已完成' | |||||
| } | |||||
| } | |||||
| const currentAction = actionMap[action] | |||||
| uni.showModal({ | |||||
| title: '提示', | |||||
| content: currentAction.confirmText, | |||||
| confirmColor: '#019245', | |||||
| success: (res) => { | |||||
| if (res.confirm) { | |||||
| // 使用统一的updateOrders接口处理单个订单 | |||||
| uni.showLoading({ | |||||
| title: '处理中...' | |||||
| }) | |||||
| this.$api('updateOrders', { | |||||
| orderIds: meal.id, // 单个订单直接传ID | |||||
| status: currentAction.status | |||||
| }, res => { | |||||
| uni.hideLoading() | |||||
| if (res.code === 200) { | |||||
| uni.showToast({ | |||||
| title: currentAction.successText, | |||||
| icon: 'success' | |||||
| }) | |||||
| this.getData() | |||||
| } else { | |||||
| uni.showToast({ | |||||
| title: '操作失败', | |||||
| icon: 'none' | |||||
| }) | |||||
| } | |||||
| }) | |||||
| } | |||||
| } | |||||
| }) | |||||
| }, | |||||
| // 处理批量操作 | |||||
| handleBatchAction(action) { | |||||
| if (this.checkedOrders.length === 0) { | |||||
| uni.showToast({ | |||||
| title: '请先选择订单', | |||||
| icon: 'none' | |||||
| }) | |||||
| return | |||||
| } | |||||
| const actionMap = { | |||||
| '出餐': { | |||||
| status: 1, | |||||
| confirmText: `确定将选中的${this.checkedOrders.length}个订单标记为已出餐吗?`, | |||||
| successText: '批量操作成功' | |||||
| }, | |||||
| '取餐': { | |||||
| status: 2, | |||||
| confirmText: `确定将选中的${this.checkedOrders.length}个订单标记为待取餐餐吗?`, | |||||
| successText: '批量操作成功' | |||||
| }, | |||||
| '完成': { | |||||
| status: 3, | |||||
| confirmText: `确定将选中的${this.checkedOrders.length}个订单标记为已完成吗?`, | |||||
| successText: '批量操作成功' | |||||
| } | |||||
| } | |||||
| const currentAction = actionMap[action] | |||||
| uni.showModal({ | |||||
| title: '批量操作', | |||||
| content: currentAction.confirmText, | |||||
| confirmColor: '#019245', | |||||
| success: (res) => { | |||||
| if (res.confirm) { | |||||
| // 显示加载中 | |||||
| uni.showLoading({ | |||||
| title: '处理中...' | |||||
| }) | |||||
| // 使用分号分隔多个订单ID | |||||
| const orderIds = this.checkedOrders.join(';') | |||||
| this.$api('updateOrders', { | |||||
| orderIds: orderIds, | |||||
| status: currentAction.status | |||||
| }, res => { | |||||
| uni.hideLoading() | |||||
| if (res.code === 200) { | |||||
| uni.showToast({ | |||||
| title: currentAction.successText, | |||||
| icon: 'success' | |||||
| }) | |||||
| this.checkedOrders = [] | |||||
| this.isAllChecked = false | |||||
| this.getData() | |||||
| } else { | |||||
| uni.showToast({ | |||||
| title: '操作失败', | |||||
| icon: 'none' | |||||
| }) | |||||
| } | |||||
| }) | |||||
| } | |||||
| } | |||||
| }) | |||||
| } | |||||
| } | |||||
| } | |||||
| </script> | |||||
| <style scoped lang="scss"> | |||||
| .page {} | |||||
| .tabs { | |||||
| background: #fff; | |||||
| padding-bottom: 4rpx; | |||||
| } | |||||
| /* 批量操作区域 */ | |||||
| .batch-actions { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| background-color: #fff; | |||||
| padding: 20rpx; | |||||
| margin-bottom: 10rpx; | |||||
| border-bottom: 1px solid #f5f5f5; | |||||
| } | |||||
| .checkbox-all { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| font-size: 28rpx; | |||||
| } | |||||
| .batch-btns { | |||||
| display: flex; | |||||
| gap: 20rpx; | |||||
| } | |||||
| .batch-btn { | |||||
| background-color: $uni-color; | |||||
| color: #fff; | |||||
| font-size: 26rpx; | |||||
| padding: 10rpx 30rpx; | |||||
| border-radius: 30rpx; | |||||
| line-height: 1.5; | |||||
| margin: 0; | |||||
| } | |||||
| /* 团餐列表样式 */ | |||||
| .group-meal-list { | |||||
| padding: 20rpx; | |||||
| } | |||||
| .meal-item { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| padding: 30rpx 20rpx; | |||||
| background-color: #fff; | |||||
| margin-bottom: 20rpx; | |||||
| border-radius: 10rpx; | |||||
| } | |||||
| .meal-checkbox { | |||||
| margin-right: 20rpx; | |||||
| } | |||||
| .meal-content { | |||||
| flex: 1; | |||||
| } | |||||
| .meal-name { | |||||
| font-size: 32rpx; | |||||
| font-weight: 500; | |||||
| margin-bottom: 10rpx; | |||||
| } | |||||
| .meal-price { | |||||
| font-size: 28rpx; | |||||
| color: $uni-color; | |||||
| background-color: #ECFEF4; | |||||
| padding: 10rpx 20rpx; | |||||
| border-radius: 10rpx; | |||||
| display: inline-block; | |||||
| } | |||||
| .price-value { | |||||
| margin-left: 10rpx; | |||||
| font-weight: 500; | |||||
| } | |||||
| .meal-action { | |||||
| display: flex; | |||||
| gap: 15rpx; | |||||
| margin-left: 20rpx; | |||||
| } | |||||
| .action-btn { | |||||
| background-color: #f0f0f0; | |||||
| color: #333; | |||||
| font-size: 26rpx; | |||||
| padding: 10rpx 25rpx; | |||||
| border-radius: 30rpx; | |||||
| line-height: 1.5; | |||||
| margin: 0; | |||||
| } | |||||
| .order-btn { | |||||
| background-color: $uni-color; | |||||
| color: #fff; | |||||
| font-size: 26rpx; | |||||
| padding: 10rpx 25rpx; | |||||
| border-radius: 30rpx; | |||||
| line-height: 1.5; | |||||
| margin: 0; | |||||
| } | |||||
| </style> | |||||