2026-05-12-table-qrcode-orders.md 12 KB

餐桌码查看关联订单 Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 在商家端餐桌码管理页面增加「订单」按钮,点击后弹窗展示该餐桌关联的所有订单列表。

Architecture: 后端在 TableQrcodeController 新增 getTableOrders 接口,通过 tableId 查询 pos_order 表;前端在 TableQRCode.vue 操作列新增按钮和订单弹窗。权限复用现有 verifyOwnership 模式。

Tech Stack: Java 21 / Spring Boot / MyBatis Plus / Vue 2 + Element UI


File Structure

File Action Responsibility
ruoyi-admin/src/main/java/com/ruoyi/app/tableqrcode/TableQrcodeController.java Modify 新增 getTableOrders 接口
foodie-store/src/api/tableQrcode.js Modify 新增 getTableOrders API 方法
foodie-store/src/views/TableQRCode.vue Modify 新增订单按钮和订单弹窗

Task 1: 后端 — 新增 getTableOrders 接口

Files:

  • Modify: ruoyi-admin/src/main/java/com/ruoyi/app/tableqrcode/TableQrcodeController.java

  • [ ] Step 1: 添加新的 import 语句

TableQrcodeController.java 文件顶部的 import 区域,添加 PosOrder 和 PosOrderService 相关的 import:

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.system.domain.PosOrder;
import com.ruoyi.system.service.IPosOrderService;

注意:IPagePage 需要检查是否与已有 import 冲突。文件中没有这些 import,直接添加即可。

  • Step 2: 注入 PosOrderService

在已有的 @Autowired private IPosStoreService posStoreService; 之后添加:

@Autowired
private IPosOrderService posOrderService;
  • Step 3: 添加 getTableOrders 方法

getQrcodeImage 方法之前(约第 366 行),添加以下方法:

/**
 * 查看餐桌关联订单
 */
@Anonymous
@Auth
@GetMapping("/getTableOrders")
public AjaxResult getTableOrders(@RequestHeader String token,
                                  @RequestParam Long id,
                                  @RequestParam(defaultValue = "1") Integer page,
                                  @RequestParam(defaultValue = "10") Integer size,
                                  @RequestParam(required = false) String state)
{
    if (!verifyOwnership(token, id))
    {
        return error("无权访问");
    }
    TableQrcode tableQrcode = tableQrcodeService.selectTableQrcodeById(id);
    if (tableQrcode == null)
    {
        return error("餐桌码不存在");
    }

    IPage<PosOrder> pageParam = new Page<>(page, size);
    QueryWrapper<PosOrder> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("table_id", id).orderByDesc("cretim");
    if (state != null && !state.isEmpty())
    {
        if (state.equals("z01"))
        {
            queryWrapper.apply("((state = 0 AND (collect_payment = 1 OR type = 1)) OR (state = 1))");
        }
        else if (state.equals("z234"))
        {
            queryWrapper.in("state", 2, 3, 4);
        }
        else if (state.equals("z23"))
        {
            queryWrapper.in("state", 2, 3);
        }
        else if (state.equals("z34"))
        {
            queryWrapper.in("state", 3, 4);
        }
        else if (state.equals("z678911"))
        {
            queryWrapper.in("state", 6, 7, 8, 9, 11);
        }
        else
        {
            queryWrapper.eq("state", state);
        }
    }

    IPage<PosOrder> result = posOrderService.page(pageParam, queryWrapper);
    return success(result);
}

还需要在 import 区域添加 QueryWrapper(如果还没有的话):

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

注意:检查文件顶部是否已有 LambdaQueryWrapper 的 import — 如果有,QueryWrapper 在同一个包下,只需额外添加这一行。

  • Step 4: 编译验证

Run: cd E:/QtwCode/foodie/foodie_server && mvn compile -pl ruoyi-admin -am -q Expected: BUILD SUCCESS

  • [ ] Step 5: Commit

    git add ruoyi-admin/src/main/java/com/ruoyi/app/tableqrcode/TableQrcodeController.java
    git commit -m "feat: 添加餐桌码关联订单查询接口 GET /table-qrcode/getTableOrders"
    

Task 2: 前端 — API 模块新增 getTableOrders

Files:

  • Modify: foodie-store/src/api/tableQrcode.js

  • [ ] Step 1: 添加 getTableOrders 方法

tableQrcode.js 文件末尾(getQrcodeImage 函数之后)添加:

// 查看餐桌关联订单
export function getTableOrders(params) {
  return request({
    url: '/table-qrcode/getTableOrders',
    method: 'get',
    headers: { isToken: true },
    params
  })
}
  • [ ] Step 2: Commit

    git add foodie-store/src/api/tableQrcode.js
    git commit -m "feat: 前端API模块添加 getTableOrders 方法"
    

Task 3: 前端 — TableQRCode.vue 新增订单按钮和弹窗

Files:

  • Modify: foodie-store/src/views/TableQRCode.vue

由于前端文件使用 CRLF 换行符,必须使用 Python 脚本进行编辑,不能用 Edit 工具直接替换。

  • Step 1: 在 import 行添加 getTableOrders

当前第 134 行:

import { getTableQrcodeList, addTableQrcode, updateTableQrcode, deleteTableQrcode, changeTableQrcodeStatus, getQrcodeImage } from '@/api/tableQrcode'

改为:

import { getTableQrcodeList, addTableQrcode, updateTableQrcode, deleteTableQrcode, changeTableQrcodeStatus, getQrcodeImage, getTableOrders } from '@/api/tableQrcode'
  • Step 2: 在操作列添加「订单」按钮

在模板第 69 行的「查看二维码」按钮之前,添加订单按钮:

当前代码(第 68-73 行):

        <template slot-scope="scope">
          <el-button @click="handleViewQrcode(scope.row)" type="text" size="small">查看二维码</el-button>
          <el-button @click="handleEdit(scope.row)" type="text" size="small">编辑</el-button>
          <el-button @click="handleDelete(scope.row)" type="text" size="small" style="color: red;">删除</el-button>
        </template>

改为:

        <template slot-scope="scope">
          <el-button @click="handleViewOrders(scope.row)" type="text" size="small">订单</el-button>
          <el-button @click="handleViewQrcode(scope.row)" type="text" size="small">查看二维码</el-button>
          <el-button @click="handleEdit(scope.row)" type="text" size="small">编辑</el-button>
          <el-button @click="handleDelete(scope.row)" type="text" size="small" style="color: red;">删除</el-button>
        </template>

同时将操作列宽度从 width="220" 改为 width="280" 以容纳新按钮。

  • Step 3: 添加订单弹窗模板

在二维码查看弹窗(第 119-130 行)的 </el-dialog> 之后、</div> 之前(第 130 行后),添加:


    <!-- 订单查看弹窗 -->
    <el-dialog :title="'餐桌订单 - ' + orderDialogTableNo" :visible.sync="orderDialogVisible" width="800px" append-to-body>
      <el-form :inline="true" style="margin-bottom: 15px;">
        <el-form-item label="订单状态">
          <el-select v-model="orderQueryState" placeholder="全部" clearable size="small" @change="loadOrders">
            <el-option label="待处理" value="z01"></el-option>
            <el-option label="进行中" value="z234"></el-option>
            <el-option label="已完成" value="z678911"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <el-table v-loading="orderLoading" :data="orderList" :header-cell-style="{ background: '#f0f0f0' }" max-height="400">
        <el-table-column prop="ddId" label="订单号" width="180"></el-table-column>
        <el-table-column prop="amount" label="金额" width="100"></el-table-column>
        <el-table-column prop="state" label="订单状态" width="100">
          <template slot-scope="scope">
            <el-tag :type="orderStateTagType(scope.row.state)" size="small">{{ orderStateText(scope.row.state) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="diningStatus" label="出餐状态" width="100">
          <template slot-scope="scope">
            <el-tag :type="scope.row.diningStatus === 1 ? 'success' : 'info'" size="small">
              {{ scope.row.diningStatus === 1 ? '已出餐' : '未出餐' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="cretim" label="下单时间" width="180"></el-table-column>
      </el-table>
      <el-pagination
        v-if="orderTotal > 0"
        :current-page.sync="orderPage"
        :page-size="10"
        :total="orderTotal"
        layout="total, prev, pager, next"
        @current-change="loadOrders"
        style="margin-top: 15px; text-align: right;">
      </el-pagination>
    </el-dialog>
  • Step 4: 添加 data 属性

在 data() 的 currentRow: {} 之后添加:

      orderDialogVisible: false,
      orderDialogTableNo: '',
      orderDialogTableId: null,
      orderLoading: false,
      orderList: [],
      orderTotal: 0,
      orderPage: 1,
      orderQueryState: ''
  • Step 5: 添加 methods

downloadQrcode 方法之后,methods 闭合 } 之前,添加以下方法:

    handleViewOrders(row) {
      this.orderDialogTableNo = row.tableNo
      this.orderDialogTableId = row.id
      this.orderPage = 1
      this.orderQueryState = ''
      this.orderDialogVisible = true
      this.loadOrders()
    },
    loadOrders() {
      this.orderLoading = true
      const params = { id: this.orderDialogTableId, page: this.orderPage, size: 10 }
      if (this.orderQueryState) {
        params.state = this.orderQueryState
      }
      getTableOrders(params).then(res => {
        if (res.code === 200) {
          const data = res.data
          this.orderList = data.records || []
          this.orderTotal = data.total || 0
        } else {
          this.$message.error(res.msg || '获取订单失败')
        }
        this.orderLoading = false
      }).catch(() => {
        this.$message.error('获取订单失败')
        this.orderLoading = false
      })
    },
    orderStateText(state) {
      const map = { 0: '待处理', 1: '已付款', 2: '已接单', 3: '配送中', 4: '已送达', 6: '已取消', 7: '退款中', 8: '已退款', 9: '退款拒绝', 11: '已评价' }
      return map[state] || '未知'
    },
    orderStateTagType(state) {
      if (state === 0 || state === 1) return 'warning'
      if (state === 2 || state === 3) return ''
      if (state === 4) return 'success'
      if (state === 6 || state === 7 || state === 8) return 'danger'
      return 'info'
    }
  • Step 6: 验证前端编译

Run: cd E:/QtwCode/foodie/foodie-store && npm run build Expected: 编译成功无报错

  • [ ] Step 7: Commit

    git add foodie-store/src/views/TableQRCode.vue
    git commit -m "feat: 餐桌码管理页面新增查看关联订单功能"
    

Spec Coverage Check

Spec 需求 对应 Task
GET /table-qrcode/getTableOrders 接口 Task 1
权限校验(userType 1/3/4) Task 1(复用 verifyOwnership)
按 tableId 查询订单,支持分页和状态筛选 Task 1
前端 API 模块 Task 2
操作列「订单」按钮 Task 3
订单弹窗(订单号、金额、状态、出餐状态、时间) Task 3
订单状态筛选下拉 Task 3
分页 Task 3