# 餐饮模块迁移分析文档 > 本文档整合了从 JeePlus Cloud 微服务项目 `xg_total_process_master` 迁移至 Forge Admin 框架的完整分析,涵盖数据库表结构、后端架构、PC 前端、H5 移动端、框架差异适配、工时评估等全部信息。 --- ## 一、源项目概况 ### 1.1 源项目信息 | 项 | 值 | |---|---| | 源项目路径 | `D:\java_project\xg_total_process_master\` | | 源框架 | JeePlus Cloud(Spring Cloud 微服务版) | | 后端结构 | `jeeplus-gateway` + `jeeplus-auth` + `jeeplus-api` + `jeeplus-common` + `jeeplus-modules` | | PC 前端 | `xg_total_process_master_cloud_vue`(Vue 2 + Element Plus + vxe-table) | | H5 移动端 | `xg_total_process_master_cloud_h5`(uni-app Vue 2 Options API + uView) | | 业务模块位置 | `jeeplus-modules/jeeplus-psi-management` | | 数据库 | MySQL 5.7,库名 `xg_saas` | ### 1.2 目标框架 | 项 | 值 | |---|---| | 目标框架 | Forge Admin(单体 + 插件化) | | 后端 | Spring Boot 3.2 + MyBatis-Plus 3.5 + Sa-Token 1.38 + Flowable 7.0 | | PC 前端 | Vue 3.5 + Naive UI 2.42 + Vite 7 + Pinia 3 + UnoCSS 66 | | H5 移动端 | uni-app Vue 3 Composition API(forge-h5-ui) | | 目标模块 | `forge-server/forge-business/forge-restaurant` | | 数据库 | MySQL 8.0+ / Redis 6.0+ | --- ## 二、数据库表全景(共 28 张表) 源 SQL 文件 `psi_credit_customer.sql` 实际包含 **3 个业务域**,不只是"菜品管理"。 ### 2.1 域 1:菜品管理(dishManage)— 8 张表 | 表名 | 说明 | 核心字段 | |------|------|----------| | `psi_dish_library` | 菜品库 | dish_code, dish_name, type_id, image_url, sale_price, cost_price, status | | `psi_dish_type` | 菜品分类(树形) | name, parent_id, parent_ids, level, sort, status | | `psi_dish_room` | 包房 | room_no, room_name, capacity, min_consumption, status, use_status | | `psi_dish_menu` | 菜单主表 | is_history, history_time | | `psi_dish_menu_dish` | 菜单-菜品关联 | menu_id, dish_id, sale_price, sort, is_history, history_time | | `psi_dish_order` | 点菜订单 | order_no, room_id, order_status, total_amount, settle_type, payable_amount, proc_ins_id | | `psi_dish_order_detail` | 订单明细 | order_id, dish_id, quantity, amount, dish_sort, is_add_dish, reason | | `psi_credit_customer` | 挂账客户 | customer_name, mobile, credit_status, total_arrears_amount, status, proc_ins_id | ### 2.2 域 2:物资管理(psi_management)— 约 19 张表 | 子域 | 表名 | 说明 | |------|------|------| | **领用** | `psi_management_collect_basics` | 领用基础表 | | | `psi_management_collect_detailed` | 领用明细表 | | | `psi_management_collect_detailed_record` | 领用明细记录(退回相关) | | | `psi_management_collect_basics_return` | 领用退回 | | | `psi_management_collect_basics_return_hi` | 领用退回历史 | | **采购** | `psi_management_food_purchase_basic` | 食材采购基础表 | | | `psi_management_food_purchase_detail` | 食材采购明细 | | | `psi_management_food_purchase_change` | 食材采购修改单 | | | `psi_management_food_purchase_change_detail` | 修改单明细 | | | `psi_management_pruchase_request_basics` | 采购申请基础表 | | | `psi_management_pruchase_request_detailed` | 采购申请明细 | | **报损** | `psi_management_loss_basics` | 报损基础表 | | | `psi_management_loss_detailed` | 报损明细 | | **入库** | `psi_management_warehouse_basics` | 入库基础表 | | | `psi_management_warehouse_detailed` | 入库明细 | | | `psi_management_warehouse_summary` | 入库汇总 | | | `psi_management_warehouse_up_hi` | 入库修改历史 | | **合同** | `psi_management_contract` | 合同表 | | | `psi_management_contract_user` | 合同联系人 | | **物资类型** | `psi_management_type` | 物资类型(树形) | ### 2.3 域 3:供应商 + 其他 — 3 张表 | 表名 | 说明 | |------|------| | `psi_supplier` | 供应商 | | `psi_supplier_link` | 供应商联系人 | | `psi_type_info` | 财务报销类型(树形) | > **注**:`psi_user` 是 JeePlus 自有用户表,Forge 使用 `sys_user`,无需迁移。 ### 2.4 源表结构特征(迁移需改造的点) | 特征 | JeePlus Cloud 现状 | Forge 目标 | |------|-------------------|-----------| | 主键类型 | `varchar(64)` | `bigint`(雪花 ID) | | 创建人字段 | `create_by_id` | `create_by` | | 更新人字段 | `update_by_id` | `update_by` | | 删除标记 | `tinyint(1)` / `int(1)`,值 `0/1` | `bigint`,值 `0/主键ID`(删除标记唯一索引) | | 租户字段 | `tenant_id varchar(255)` | `tenant_id bigint` | | 字符集 | `utf8` | `utf8mb4` | | 备注字段 | `remarks` | 按需保留或改为 `remark` | | 流程字段 | `proc_ins_id` + `process_definition_id` 散落在业务表 | Forge 通过 `forge-flow-client` 注解管理,不直接存业务表 | --- ## 三、后端架构详细分析 ### 3.1 源码模块结构 ``` dishManage/ ├── domain/ # 8 个实体类 │ ├── PsiDishLibrary # 菜品库 │ ├── PsiDishType # 菜品分类(树形) │ ├── PsiDishRoom # 包房 │ ├── PsiDishMenu # 菜单主表 │ ├── PsiDishMenuDish # 菜单-菜品关联 │ ├── PsiDishOrder # 点菜订单 │ ├── PsiDishOrderDetail # 订单明细 │ └── PsiCreditCustomer # 挂账客户 ├── controller/ # 6 个 Controller ├── service/ # 6 个 Service ├── mapper/ # 8 个 Mapper + 8 个 XML └── service/dto/ # 导出 DTO ``` ### 3.2 实体类设计(Domain) #### PsiDishLibrary — 菜品库 - **继承**: `DataEntity` → 需改为 Forge `BaseEntity` - **虚拟字段**(`@TableField(exist = false)`):typeName、createName - **唯一约束**:编码(dishCode)全局唯一;名称 + 分类联合唯一 - **编码生成**:`CP` + `System.currentTimeMillis()` #### PsiDishType — 菜品分类(树形) - **继承**: `TreeEntity`(parent_id / parent_ids / level 层级) - **删除约束**:存在子分类或关联菜品时不允许删除 #### PsiDishRoom — 包房 - **业务规则**:停用前检查 `useStatus`,使用中不允许停用 - **唯一约束**:room_no 全局唯一、room_name 全局唯一 #### PsiDishMenu — 菜单主表 - **核心机制**:系统中始终只有一份"当前菜单"(`is_history = '0' or null`),更新菜单时旧菜单归档为历史 - **虚拟字段**:createName、dishCount #### PsiDishMenuDish — 菜单菜品关联 - **关键设计**:`sale_price` 为菜单级独立定价(覆盖菜品库价格) - **大量虚拟字段**:dishCode、dishName、typeId、typeName、imageUrl 等 #### PsiDishOrder — 点菜订单 - **订单状态**:0=用餐中,1=已结账,2=已取消 - **结账方式**:0=结账,1=折扣结账,2=优惠结账 - **流程绑定**:含 `proc_ins_id` + `process_definition_id` - **虚拟字段**:createTimes/settleTimes(时间范围查询)、detailList/addDishList/reduceDishList(三类明细列表) #### PsiDishOrderDetail — 订单明细 - **核心设计**:退菜时 quantity 为负数,汇总通过 `SUM(quantity)` + `HAVING > 0` 过滤 - **冗余字段**:dishCode、dishName、typeName 等(避免关联查询) #### PsiCreditCustomer — 挂账客户 - **挂账状态**:0=正常挂账,1=暂停挂账,2=黑名单 - **审核状态**:含 `status` 字段(审核流程) - **流程绑定**:含 `proc_ins_id` ### 3.3 Service 层核心逻辑 #### PsiDishOrderService(493 行)— 订单核心 | 方法 | 说明 | |------|------| | `list(page, info)` | 分页查询订单,支持多条件筛选 | | `submitOrder(info)` | **核心下单逻辑**,通过 `settleFlag` 区分操作类型 | | `cancelOrder(id)` | 取消订单 + 释放包房 | | `currentOrder(roomId)` | 查询包房当前用餐中订单 | | `findOrderById(id)` | 订单详情(含三类明细) | | `refreshOrderAmount(order)` | 重算金额 + 结账处理 + 异步流程通知 | | `typeList()` / `dishList()` | 查询可点分类和菜品(来自当前菜单) | | `exportRecordList()` | 订单导出(EasyExcel) | **`submitOrder` 核心流程**: ``` settleFlag 判断: ├── "0" → 下单/加菜/退菜/仅排序 │ ├── id 为空 → 新建订单(orderStatus=0,占用包房 useStatus=1) │ ├── detailList 数量全为负 → 退菜(插入负数明细) │ ├── detailList 数量全为正 → 加菜(isAddDish=1) │ └── 混合 → 仅排序(更新 dishSort) ├── "1" → 结账 │ ├── 填充结账金额(fillSettleAmount) │ ├── orderStatus → 1 │ ├── settleTime → now │ ├── 释放包房 useStatus=0 │ └── 异步发送 Flowable 通知(线程池 5 线程) └── "2" → 仅刷新金额 ``` **结账金额计算(`fillSettleAmount`)**: - `settleType=0`(普通结账):payableAmount = totalAmount - `settleType=1`(折扣结账):payableAmount = totalAmount × discountRate / 100 - `settleType=2`(优惠结账):payableAmount = totalAmount - discountAmount #### PsiDishMenuService(369 行)— 菜单管理 **核心机制 — 菜单版本归档**: ``` updateMenu(dishIds): 1. 查找当前菜单(is_history = '0' or null) 2. 将当前菜单标记为历史(is_history='1', historyTime=now) 3. 将当前菜单的所有菜品也标记为历史 4. 创建新菜单(is_history='0') 5. 复制菜品到新菜单(保持价格独立) ``` #### PsiDishLibraryService(123 行)— 菜品库 | 方法 | 说明 | |------|------| | `saveDish(info)` | 保存菜品(自动生成编码、校验唯一性、分类必须选最子级) | | `deleteByIds(ids)` | 批量删除 | | `changeStatus(id, status)` | 启用/停用 | #### PsiDishRoomService(108 行)— 包房管理 | 方法 | 说明 | |------|------| | `saveRoom(info)` | 保存(编号/名称唯一校验) | | `deleteByIds(ids)` | 删除(检查使用状态) | | `changeStatus(id, status)` | 启用/停用(检查使用状态) | #### PsiDishTypeService(168 行)— 分类管理 | 方法 | 说明 | |------|------| | `saveDishType(info)` | 保存分类(自动维护 parentIds/level) | | `treeData(extId)` | 构建树形数据 | | `remove(id)` | 删除(检查子分类 + 关联菜品) | #### PsiCreditCustomerService(142 行)— 挂账客户 | 方法 | 说明 | |------|------| | `saveCreditCustomer(info)` | 保存(手机号唯一校验) | | `saveCreditCustomerForFlow(info)` | 流程表单保存(抛异常供流程引擎调用) | | `changeStatus(id, creditStatus)` | 修改挂账状态 | ### 3.4 Controller 层 API 接口 #### PsiDishLibraryController — `/psi/dish` | 方法 | 路径 | 权限 | |------|------|------| | GET | `/list` | - | | POST | `/save` | `psi:dish:add` / `psi:dish:edit` | | GET | `/findById` | - | | DELETE | `/delete` | `psi:dish:del` | | GET | `/changeStatus` | `psi:dish:edit` | #### PsiDishTypeController — `/psi/dishType` | 方法 | 路径 | 权限 | |------|------|------| | GET | `/list` | - | | GET | `/treeData` | - | | POST | `/save` | `psi:dishType:add` / `psi:dishType:edit` | | GET | `/findById` | - | | GET | `/deleteById` | `psi:dishType:del` | | GET | `/changeStatus` | `psi:dishType:edit` | #### PsiDishRoomController — `/psi/dishRoom` | 方法 | 路径 | |------|------| | GET | `/list`(不分页) | | GET | `/findById` | | POST | `/save` | | DELETE | `/delete` | | GET | `/changeStatus` | #### PsiDishMenuController — `/psi/dishMenu` | 方法 | 路径 | |------|------| | GET | `/list`(当前菜单菜品列表,分页) | | GET | `/historyList`(历史菜单列表,分页) | | GET | `/historyDetailList`(历史菜单菜品详情) | | GET | `/availableDishList`(可添加菜品列表) | | GET | `/orderDishList`(点单菜品列表) | | GET | `/orderTypeList`(点单分类列表) | | POST | `/addDishes`(添加菜品到菜单) | | POST | `/saveDishes`(全量保存菜品) | | POST | `/updatePrice`(调整菜单价格) | | DELETE | `/delete`(删除菜单菜品) | | POST | `/updateMenu`(更新菜单,归档旧菜单) | #### PsiDishOrderController — `/psi/dishOrder` | 方法 | 路径 | |------|------| | GET | `/typeList`(有菜品的分类列表) | | GET | `/dishList`(可点菜品列表) | | GET | `/orderList`(订单列表,分页) | | GET | `/exportFile`(导出订单,EasyExcel) | | GET | `/findOrderById`(订单详情) | | GET | `/currentOrder`(当前包房订单) | | GET | `/cancelOrder`(取消订单) | | POST | `/submit`(下单/加菜/退菜/结账) | #### PsiCreditCustomerController — `/psi/creditCustomer` | 方法 | 路径 | 权限 | |------|------|------| | GET | `/list` | - | | GET | `/findById` | - | | POST | `/save` | `psi:creditCustomer:add/edit` | | POST | `/saveFlow` | `psi:creditCustomer:add/edit` | | POST | `/updateStatusById` | `psi:creditCustomer:add/edit` | | DELETE | `/delete` | `psi:creditCustomer:del` | | GET | `/changeStatus` | `psi:creditCustomer:edit` | ### 3.5 Mapper XML 关键 SQL #### PsiDishLibraryMapper | SQL ID | 说明 | |--------|------| | `findList` | LEFT JOIN psi_dish_type + sys_user,按 sort ASC, create_time DESC | | `queryById` | 详情查询 | | `checkCodeIsExist` | 编码唯一性校验(排除自身) | | `checkNameIsExist` | 名称+分类联合唯一校验 | | `countByTypeId` | 统计分类下菜品数(删除前校验) | | `findOrderDishList` | 点菜查询(仅 status=0 的菜品和分类) | #### PsiDishMenuDishMapper(最复杂) | SQL ID | 说明 | |--------|------| | `findCurrentDishList` | 当前菜单菜品(is_history='0' or null),4 表 JOIN | | `findHistoryDishList` | 历史菜单菜品(is_history='1') | | `findAvailableDishList` | 可添加菜品(NOT EXISTS 排除已选) | | `findOrderDishList` | 点菜专用(菜单价覆盖菜品库价) | | `findOrderTypeList` | 点菜分类(DISTINCT,仅含菜单中有菜品的分类) | | `findCurrentByDishId` | 按菜品查当前菜单记录 | | `getMaxSort` | 获取当前菜单最大排序号 | **关键设计**:`findOrderDishList` 中 `md.sale_price`(菜单价)覆盖了 `dl.sale_price`(菜品库价),实现菜单级独立定价。 #### PsiDishOrderDetailMapper | SQL ID | 说明 | |--------|------| | `findSummaryByOrderId` | **汇总查询**:GROUP BY dish_id,SUM(quantity/amount),HAVING SUM(quantity)>0 | | `findAddDishList` | 加菜列表(is_add_dish='1' AND quantity>0) | | `findReduceDishList` | 退菜列表(quantity<0) | | `updateDishSort` | 更新排序(按 order_id + dish_id) | --- ## 四、PC 前端详细设计 ### 4.1 源项目技术栈 - **框架**: Vue 2 + Element Plus - **表格**: vxe-table(支持树形、导出、分页) - **图片**: OSS 临时 URL + el-image 预览 - **拖拽**: sortablejs - **字典**: `$dictUtils.getDictList()` ### 4.2 页面清单 ``` src/views/psiManagement/dishManage/ ├── library/ # 菜品库管理 │ ├── DishLibrary.vue # 列表页 │ ├── DishLibraryForm.vue # 新增/编辑/查看弹窗 │ ├── DishImageUpload.vue # 图片上传组件 │ └── DishTypeSelectTree.vue # 分类选择树组件 ├── type/ # 分类管理 │ ├── DishType.vue # 树形列表页 │ └── DishTypeForm.vue # 新增/编辑弹窗 ├── room/ # 包房管理 │ ├── DishRoomList.vue # 卡片列表页 │ └── DishRoomForm.vue # 新增/编辑弹窗 ├── menu/ # 菜单管理 │ ├── DishMenu.vue # 当前/历史菜单 Tab 页(366 行) │ ├── DishMenuDishDialog.vue # 添加/更新菜品弹窗 │ ├── DishMenuPriceDialog.vue# 修改价格弹窗 │ └── DishMenuHistoryDetailDialog.vue # 历史详情弹窗 ├── order/ # 点菜管理 │ ├── DishOrder.vue # 包房选择页(点菜入口) │ ├── DishOrderDetail.vue # 核心点菜页面(954 行) │ ├── DishOrderAdd.vue # 加菜页面(656 行) │ ├── DishOrderList.vue # 订单记录列表(306 行) │ ├── DishOrderSettleDialog.vue # 结账弹窗 │ ├── DishOrderConfirmDialog.vue # 确认下单弹窗 │ ├── DishOrderReturnDialog.vue # 退菜弹窗 │ └── DishOrderInfoDialog.vue # 订单详情弹窗 └── creditCustomer/ # 挂账客户 ├── CreditCustomer.vue # 列表页 ├── CreditCustomerForm.vue # 新增/编辑弹窗 └── CreditCustomerApproval.vue # 审批表单页 ``` ### 4.3 核心页面详解 #### DishOrderDetail.vue — 核心点菜页面(954 行) **布局**:左右分栏 - **左侧**(flex:1):菜品选择区 - 分类列表(左侧导航栏,"所有菜品" + 动态分类) - 菜品网格(4 列卡片,含图片/名称/规格/价格/点菜按钮) - 搜索框(按名称搜索) - **右侧**(480px):已点菜面板 - 已点菜品列表(可拖拽排序,sortablejs) - 数量增减按钮(未下单时) - 金额汇总 - 操作按钮(下单/结账/取消订单/订单详情) **关键交互流程**: ``` 首次点菜: 选菜 → 调整数量 → 点击"下单" → 弹出确认弹窗(备注+特殊要求)→ 提交 已有订单: ├── 直接调整数量 → 点击"下单" → 提交变更(增量) ├── 点击"加菜" → 跳转 DishOrderAdd 页面 ├── 点击"退菜" → 弹出退菜弹窗 → 提交负数数量 ├── 点击"结账" → 弹出结账弹窗(3 种方式)→ 提交结账 └── 点击"取消订单" → 确认后取消 ``` #### DishMenu.vue — 菜单管理(366 行) - **Tab 1 — 当前菜单**:树形表格(vxe-table tree-config),分类为父节点、菜品为子节点 - **Tab 2 — 历史菜单**:列表展示历史版本 - **树形构建逻辑**:筛选有菜品的分类 → 分类节点作为树父节点 → 菜品挂在对应分类下 ### 4.4 弹窗组件 | 弹窗 | 功能 | |------|------| | DishOrderSettleDialog | 3 Tab(结账/折扣/优惠),实时计算金额 | | DishOrderConfirmDialog | 备注 + 特殊要求 checkbox(字典驱动,自动同步到备注) | | DishOrderReturnDialog | 退菜数量输入(0 ~ 现有数量),退菜原因 | | DishOrderInfoDialog | 订单概要 + 3 Tab(实际菜单/加菜/退菜) | --- ## 五、H5 移动端详细设计 ### 5.1 源项目技术栈 - **框架**: uni-app(Vue 2 Options API) - **UI**: 自定义样式 + uView 组件 - **路由**: uni.navigateTo / uni.navigateBack - **图片**: OSS 临时 URL + uni.previewImage - **单位**: rpx ### 5.2 页面清单 ``` pages/psiManagement/dishManage/ ├── DishOrder.vue # 包房选择页(269 行) ├── DishOrderDetail.vue # 核心点菜页面(1381 行) ├── DishOrderAdd.vue # 加菜页面(667 行) └── DishOrderApproval.vue # 订单审批页(513 行) ``` ### 5.3 与 PC 端差异 | 维度 | PC 前端 | H5 移动端 | |------|---------|-----------| | 组件化 | 独立弹窗组件 | 内联弹窗 | | 表格 | vxe-table | 原生 div + CSS Grid | | 路由 | Vue Router | uni.navigateTo | | 图片预览 | el-image preview-src-list | uni.previewImage | | 弹窗 | el-dialog | 原生 view + 遮罩 | | 提示 | $message / $confirm | uni.showToast / uni.showModal | | 生命周期 | mounted / activated | onLoad / onShow | ### 5.4 H5 独有页面 **DishOrderApproval.vue(513 行)**:PC 端无对应页面,用于 Flowable 流程审批时查看订单详情。 - 作为流程表单嵌入,接收 `businessId` prop - 只读展示订单信息(金额/状态/菜品明细) - 3 个 Tab 切换:实际菜单 / 加菜 / 退菜 - 实现 `saveForm` / `agreeForm` / `startForm` / `reapplyForm` / `updateStatusById` 等流程回调方法 --- ## 六、核心业务流程 ### 6.1 完整点餐流程 ``` 选择包房 → 查看当前订单 ├── 已有订单 → 显示已点菜(可加菜/退菜/结账) └── 无订单 → 选择菜品 → 确认下单 → 创建订单 → 占用包房 ↓ 用餐中(加菜/退菜/结账) ↓ 结账处理(计算金额 → 释放包房 → 异步通知老板) ``` ### 6.2 菜单版本管理流程 ``` 当前菜单 V1(is_history = '0') ↓ 点击"更新菜单" 历史菜单 V1(is_history = '1', historyTime = now) ↓ 当前菜单 V2(is_history = '0',新菜品组合) ``` ### 6.3 订单明细汇总逻辑 ```sql -- 按菜品汇总,退菜为负数,HAVING 过滤已退完的菜品 SELECT dish_id, SUM(quantity) as quantity, SUM(amount) as amount, MIN(dish_sort) as dish_sort FROM psi_dish_order_detail WHERE order_id = ? AND del_flag = '0' GROUP BY dish_id HAVING SUM(quantity) > 0 ``` --- ## 七、权限与字典配置 ### 7.1 权限标识(19 条) | 权限标识 | 说明 | |----------|------| | `psi:dish:add` | 新增菜品 | | `psi:dish:edit` | 修改菜品 | | `psi:dish:del` | 删除菜品 | | `psi:dish:view` | 查看菜品 | | `psi:dishType:add` | 新增分类 | | `psi:dishType:edit` | 修改分类 | | `psi:dishType:del` | 删除分类 | | `psi:dishRoom:add` | 新增包房 | | `psi:dishRoom:edit` | 修改包房 | | `psi:dishRoom:del` | 删除包房 | | `psi:menu:add` | 添加菜单菜品 | | `psi:menu:edit` | 修改菜单 | | `psi:menu:del` | 删除菜单菜品 | | `psi:order:detail` | 查看订单详情 | | `psi:order:export` | 导出订单 | | `psi:creditCustomer:add` | 新增挂账人 | | `psi:creditCustomer:edit` | 修改挂账人 | | `psi:creditCustomer:del` | 删除挂账人 | | `psi:creditCustomer:view` | 查看挂账人 | ### 7.2 字典配置 | 字典类型 | 说明 | 使用场景 | |----------|------|----------| | `special_requirement` | 特殊要求 | 确认下单弹窗 checkbox | | `credit_status` | 挂账状态 | 挂账客户列表(0=正常/1=暂停/2=黑名单) | | `cw_status` | 审核状态 | 挂账客户审核状态显示 | | `cw_status_flag` | 审核状态标签类型 | 审核状态按钮颜色 | --- ## 八、关键设计决策 | 决策 | 说明 | |------|------| | 菜单级价格独立 | 菜单菜品关联表维护独立 `sale_price`,点菜用菜单价而非菜品库价,调整菜单价不影响历史订单 | | 退菜用负数数量 | 退菜不删记录,插入 `quantity` 为负数的明细,汇总时 `SUM(quantity)` + `HAVING > 0`,保留完整操作轨迹 | | 菜单归档而非覆盖 | 更新菜单时旧菜单标记为历史并创建新菜单,支持查看任意历史版本 | | 包房状态自动管理 | 下单自动 `useStatus=1`,结账/取消自动恢复 `useStatus=0` | | 折扣/优惠结账异步通知 | 折扣和优惠结账需老板审批,通过线程池异步发 Flowable 待办通知 | | 订单冗余设计 | 订单表冗余 roomNo/roomName,订单明细冗余 dishCode/dishName/typeName,避免关联查询、保证源数据变更后仍可读 | --- ## 九、框架差异适配要点(JeePlus Cloud → Forge) ### 9.1 架构层差异 | 维度 | JeePlus Cloud | Forge Admin | 改造方式 | |------|---------------|-------------|----------| | 架构模式 | Spring Cloud 微服务(Nacos + Gateway + Feign) | 单体 + 插件化 | 去 Nacos/Gateway/Feign,改本地 Service 调用 | | 认证授权 | JeePlus Cloud Auth(JWT/OAuth2)+ `@RequiresPermissions` | Sa-Token + `@SaCheckPermission` | 全部替换注解 | | 配置中心 | Nacos 动态配置 | 本地 application.yml + `@RefreshScope` | 配置迁移到本地 yml | | 服务调用 | Feign Client 跨服务 | 本地 Service | 删除 Feign 接口,改为本地注入 | | 分布式事务 | Seata / TCC | 本地 `@Transactional` | 简化为本地事务 | | 多租户 | JeePlus 自有策略 | `TenantLineInnerInterceptor` 行级拦截 | 适配租户拦截器 | ### 9.2 实体层差异 | 维度 | JeePlus Cloud | Forge Admin | |------|---------------|-------------| | 基类 | `DataEntity` / `TreeEntity` | `BaseEntity` / `TreeEntity` | | 主键 | `String id`(varchar 64) | `Long id`(雪花 bigint) | | 创建人 | `createById`(varchar) | `createBy`(Long) | | 更新人 | `updateById`(varchar) | `updateBy`(Long) | | 创建时间 | `createDate` | `createTime` | | 删除标记 | `delFlag`(String/Integer,0/1) | `delFlag`(Long,0/主键ID) | | 租户 | `tenantId`(String) | `tenantId`(Long) | | 备注 | `remarks` | 按需保留 | ### 9.3 前端差异 | 维度 | JeePlus Cloud | Forge Admin | |------|---------------|-------------| | 组件库 | Element Plus | Naive UI | | 表格 | vxe-table | AiTable(NDataTable 封装) | | 弹窗 | el-dialog | NModal | | 字典 | `$dictUtils.getDictList()` | `useDict()` + `DictSelect` / `DictTag` | | 权限指令 | `v-if="hasPermission('xxx')"` | `v-hasPermi` | | 图片 | OSS 临时 URL + el-image | fileId + `AuthImage` + `getFileUrl()` | | 请求工具 | 自有 axios 封装 | `@/utils/request` | | URL 占位符 | `{id}` 花括号 | `:id` 冒号 | ### 9.4 H5 端差异 | 维度 | JeePlus Cloud | Forge Admin | |------|---------------|-------------| | Vue 版本 | Vue 2 Options API | Vue 3 Composition API | | UI 库 | uView | 自定义 / UnoCSS | | 路由 | uni.navigateTo | uni.navigateTo(一致) | | 生命周期 | onLoad / onShow | onLoad / onShow(一致) | | 字典 | `$dictUtils` | `useDict()` | | 流程表单 | JeePlus Flow 回调 | `forge-flow-client` H5 表单回调 | --- ## 十、建议的模块结构 ``` forge-server/forge-business/forge-restaurant/ ├── pom.xml └── src/main/java/com/mdframe/forge/business/core/restaurant/ ├── dish/ # 菜品管理 │ ├── domain/ # PsiDishLibrary, PsiDishType │ ├── controller/ │ ├── service/ │ └── mapper/ ├── room/ # 包房管理 │ ├── domain/ # PsiDishRoom │ ├── controller/ │ ├── service/ │ └── mapper/ ├── menu/ # 菜单管理 │ ├── domain/ # PsiDishMenu, PsiDishMenuDish │ ├── controller/ │ ├── service/ │ └── mapper/ ├── order/ # 点菜订单 │ ├── domain/ # PsiDishOrder, PsiDishOrderDetail │ ├── controller/ │ ├── service/ │ └── mapper/ ├── credit/ # 挂账客户 │ ├── domain/ # PsiCreditCustomer │ ├── controller/ │ ├── service/ │ └── mapper/ ├── material/ # 物资管理(后续迭代) │ ├── collect/ # 领用 │ ├── purchase/ # 采购 │ ├── warehouse/ # 入库 │ ├── loss/ # 报损 │ └── contract/ # 合同 └── supplier/ # 供应商(后续迭代) ``` --- ## 十一、工时评估 ### 11.1 仅菜品管理(8 张表) | 模块 | 人日 | 说明 | |------|-----:|------| | 后端 | 24.5 | 含 Flyway、实体、Mapper、Service、Controller、Flowable、Cloud 基础设施剥离 | | PC 前端 | 26.0 | 含 API 层、6 组页面、4 个弹窗、字典/权限适配 | | H5 移动端 | 16.0 | 含 4 个页面 Vue3 重写、流程审批页 | | 公共/管理 | 9.0 | 含 Spec、环境部署、联调、UAT | | **合计** | **75.5** | **约 15 人日(AI 全速冲刺)~ 26 工作日(团队并行)** | ### 11.2 全量迁移(含物资管理 + 供应商,28 张表) | 模块 | 人日 | 说明 | |------|-----:|------| | 菜品管理 | 75.5 | 同上 | | 物资管理 | ~55 | 19 张表,含采购/领用/入库/报损/合同,流程审批多 | | 供应商 | ~8 | 2 张表,CRUD 为主 | | 公共/管理 | ~12 | 联调范围更大 | | **合计** | **~150** | **约 30 工作日(AI 全速)~ 52 工作日(团队并行)** | ### 11.3 AI 全速冲刺方案 | 阶段 | 日历天 | 产出 | |------|-------:|------| | Day 1 | 1 | Flyway 脚本 + 8 个 Entity | | Day 2 | 1 | 8 个 Mapper + XML + 基础 3 个 Service/Controller | | Day 3 | 1 | 菜单 Service + 订单核心 Service | | Day 4 | 1 | 挂账 + Flowable + Cloud 剥离 | | Day 5 | 1 | PC 基础页面(菜品库/分类/包房/挂账) | | Day 6 | 1 | PC 菜单页 + 订单列表 + 弹窗 | | Day 7 | 1.5 | PC 点菜核心页 + 加菜页 | | Day 8 | 1 | H5 全部 4 个页面 | | Day 9~12 | 3 | 联调修复 | | **合计** | **~12** | **含风险缓冲 ~15 工作日** | --- ## 十二、风险评估 | 风险 | 等级 | 说明 | |------|------|------| | 订单核心状态机 | 高 | `submitOrder` 4 分支 + `fillSettleAmount` 3 种结账,跨端一致性易出 bug | | Flowable 集成 | 高 | JeePlus Cloud Feign 调用 → Forge `@FlowBind` 本地调用,回调机制完全不同 | | 多租户 + 异步线程池 | 中 | 异步通知老板需 `TenantContextHolder.executeWithTenant` 透传 | | 逻辑删除 + 唯一键改造 | 中 | 菜品编码、包房编号/名称、手机号等唯一键需改为 `UNIQUE(tenant_id, xxx, del_flag)` | | vxe-table → AiTable | 中 | 菜单管理的树表 + 订单导出的多选/全量模式需重新调参 | | H5 点菜页 1381 行 | 中 | Vue2 → Vue3 + 内联 4 个弹窗全重写,代码量大 | | 物资管理流程多 | 中 | 采购/领用/入库/报损均有审批流程,Flowable 集成工作量大 | --- ## 十三、待确认事项 > 以下事项需要你审阅本文档后确认,才能开始实际迁移工作。 1. **迁移范围**:先只迁菜品管理(8 张表),还是连同物资管理 + 供应商一起? 2. **数据库表改造策略**:按 Forge 规范重建表结构(推荐),还是尽量保留原表结构? 3. **forge-restaurant 依赖确认**:当前 pom.xml 已包含 `forge-flow-client`(流程)和 `forge-starter-file`(文件),是否还需要其他依赖? 4. **Flowable 流程**:挂账客户审批流 + 折扣/优惠结账通知老板,是否需要在第一批就实现?还是先用简单状态字段替代? 5. **物资管理优先级**:物资管理 19 张表的工作量比菜品管理还大,是否纳入本批次? --- ## 附录 A:源项目完整文件清单与路径 ### A.1 后端源码路径 ``` 源项目根目录:D:\java_project\xg_total_process_master\ 后端模块:xg_total_process_master_cloud\jeeplus-modules\jeeplus-psi-management\ 包路径:com.jeeplus.psimanage dishManage/ # 菜品管理(8 表 6 控制器 6 服务) ├── domain/ │ ├── PsiDishLibrary.java # 菜品库(89 行) │ ├── PsiDishType.java # 菜品分类-树形(83 行) │ ├── PsiDishRoom.java # 包房(62 行) │ ├── PsiDishMenu.java # 菜单主表(37 行) │ ├── PsiDishMenuDish.java # 菜单菜品关联(76 行) │ ├── PsiDishOrder.java # 点菜订单(76 行) │ ├── PsiDishOrderDetail.java # 订单明细(60 行) │ └── PsiCreditCustomer.java # 挂账客户(79 行) ├── controller/ │ ├── PsiDishLibraryController.java # 70 行 │ ├── PsiDishTypeController.java # 74 行 │ ├── PsiDishRoomController.java # 65 行 │ ├── PsiDishMenuController.java # 111 行 │ ├── PsiDishOrderController.java # 208 行(含 Excel 导出样式) │ └── PsiCreditCustomerController.java # 90 行 ├── service/ │ ├── PsiDishLibraryService.java # 132 行 │ ├── PsiDishTypeService.java # 168 行 │ ├── PsiDishRoomService.java # 111 行 │ ├── PsiDishMenuService.java # 379 行 │ ├── PsiDishOrderService.java # 493 行(核心状态机) │ ├── PsiCreditCustomerService.java # 142 行 │ └── dto/ │ └── PsiDishOrderExportDto.java # 51 行(EasyExcel 导出) └── mapper/ ├── PsiDishLibraryMapper.java ├── PsiDishTypeMapper.java ├── PsiDishRoomMapper.java ├── PsiDishMenuMapper.java ├── PsiDishMenuDishMapper.java ├── PsiDishOrderMapper.java ├── PsiDishOrderDetailMapper.java ├── PsiCreditCustomerMapper.java └── xml/ ├── PsiDishLibraryMapper.xml # 119 行 ├── PsiDishTypeMapper.xml # 78 行 ├── PsiDishRoomMapper.xml # 84 行 ├── PsiDishMenuMapper.xml # 53 行 ├── PsiDishMenuDishMapper.xml # 206 行(最复杂) ├── PsiDishOrderMapper.xml # 73 行 ├── PsiDishOrderDetailMapper.xml # 134 行 └── PsiCreditCustomerMapper.xml # 84 行 collect/ # 物资领用(5 表 1 控制器 1 服务) ├── domain/ │ ├── PsiCollectBasic.java # 领用基础表 │ ├── PsiCollectDetailed.java # 领用明细 │ ├── PsiCollectDetailedRecord.java # 领用明细记录 │ ├── PsiCollectBasicsReturn.java # 领用退回 │ └── PsiCollectBasicsReturnHi.java # 领用退回历史 ├── controller/PsiCollectController.java ├── service/PsiCollectService.java ├── mapper/ + xml/ └── service/dto/(6 个 DTO) purchase/ # 食材采购(4 表 1 控制器 1 服务) ├── domain/ │ ├── PsiMaterialBasic.java # 采购基础表 │ └── PsiMaterialDetailed.java # 采购明细 ├── controller/PsiMaterialController.java ├── service/PsiMaterialService.java └── mapper/ + xml/ foodPurchase/ # 食材采购修改单(4 表,合并在 purchase 控制器中) loss/ # 报损(2 表 1 控制器 1 服务) ├── domain/ │ ├── PsiLossBasic.java │ └── PsiLossDetailed.java ├── controller/PsiLossController.java ├── service/PsiLossService.java └── mapper/ + xml/ psiWareHouse/ # 入库(4 表 1 控制器 1 服务) ├── domain/ │ ├── PsiWareHouseBasic.java │ ├── PsiWareHouseDetailed.java │ ├── PsiWareHouseSummary.java │ └── PsiWarehouseUpHi.java ├── controller/PsiWareHouseController.java ├── service/PsiWareHouseBasicService.java └── mapper/ + xml/ contract/ # 合同(2 表 1 控制器) ├── domain/ │ ├── PsiContract.java │ └── PsiContractUser.java └── controller/PsiContractController.java supplier/ # 供应商(2 表 1 控制器 1 服务) ├── domain/ │ ├── PsiMaterialSupplier.java # 供应商 │ └── PsiMaterialSupplierLink.java # 联系人 ├── controller/PsiMaterialSupplierController.java ├── service/PsiMaterialSupplierService.java ├── service/mapstruct/(2 个 Wrapper) └── mapper/ + xml/ materialType/ # 物资类型(1 表 1 控制器 2 服务) ├── domain/PsiMaterialTypeInfo.java ├── controller/PsiMaterialTypeController.java ├── service/PsiMaterialTypeService.java ├── service/PsiMaterialTypeForTreeDataService.java └── mapper/ + xml/ oss/ # OSS 文件上传(JeePlus 自有,Forge 无需迁移) ├── controller/PsiOssController.java ├── controller/PsiOssFileController.java ├── service/PsiOSSClientService.java ├── service/PsiOssService.java └── utils/FileUtil.java serialNumTpl/ # 序列号模板(JeePlus 基础设施,Forge 无需迁移) ``` ### A.2 PC 前端源码路径 ``` 源项目:D:\java_project\xg_total_process_master\xg_total_process_master_cloud_vue\ 页面路径:src/views/psiManagement/dishManage/ dishManage/ ├── library/ # 菜品库 │ ├── DishLibrary.vue # 列表页(左树右表) │ ├── DishLibraryForm.vue # 新增/编辑/查看弹窗 │ ├── DishImageUpload.vue # 图片上传组件(OSS) │ └── DishTypeSelectTree.vue # 分类选择树组件 ├── type/ # 分类管理 │ ├── DishType.vue # 树形列表页 │ └── DishTypeForm.vue # 新增/编辑弹窗 ├── room/ # 包房管理 │ ├── DishRoomList.vue # 卡片列表页 │ └── DishRoomForm.vue # 新增/编辑弹窗 ├── menu/ # 菜单管理 │ ├── DishMenu.vue # 当前/历史菜单 Tab 页 │ ├── DishMenuDishDialog.vue # 添加/更新菜品弹窗 │ ├── DishMenuPriceDialog.vue # 修改价格弹窗 │ └── DishMenuHistoryDetailDialog.vue # 历史详情弹窗 ├── order/ # 点菜管理 │ ├── DishOrder.vue # 包房选择页(点菜入口) │ ├── DishOrderDetail.vue # 核心点菜页面(954 行) │ ├── DishOrderAdd.vue # 加菜页面(656 行) │ ├── DishOrderList.vue # 订单记录列表(306 行) │ ├── DishOrderApproval.vue # 订单审批页(PC 端也有) │ ├── DishOrderSettleDialog.vue # 结账弹窗 │ ├── DishOrderConfirmDialog.vue # 确认下单弹窗 │ ├── DishOrderReturnDialog.vue # 退菜弹窗 │ └── DishOrderInfoDialog.vue # 订单详情弹窗 └── creditCustomer/ # 挂账客户 ├── CreditCustomer.vue # 列表页 ├── CreditCustomerForm.vue # 新增/编辑弹窗 └── CreditCustomerApproval.vue # 审批表单页 共 24 个 Vue 文件 ``` ### A.3 H5 移动端源码路径 ``` 源项目:D:\java_project\xg_total_process_master\xg_total_process_master_cloud_h5\ 页面路径:pages/psiManagement/dishManage/ dishManage/ ├── DishOrder.vue # 包房选择页 ├── DishOrderDetail.vue # 核心点菜页面(1381 行) ├── DishOrderAdd.vue # 加菜页面(667 行) └── DishOrderApproval.vue # 订单审批页(513 行) 4 个 Vue 文件 注意:H5 项目无 src 目录,页面直接在 pages/ 下 ``` --- ## 附录 A2:源项目 → Forge 文件对应关系表(双向查找) > **用途**:在源项目中找到某个文件,可以直接定位到 Forge 中对应的文件位置;反之亦然。 > > **路径缩写说明**: > - 源后端 = `xg_total_process_master_cloud\jeeplus-modules\jeeplus-psi-management\src\main\java\com\jeeplus\psimanage\` > - Forge 后端 = `forge-server\forge-business\forge-restaurant\src\main\java\com\mdframe\forge\business\core\restaurant\` > - 源PC前端 = `xg_total_process_master_cloud_vue\src\views\psiManagement\dishManage\` > - Forge PC前端 = `forge-admin-ui\src\views\restaurant\` > - 源H5 = `xg_total_process_master_cloud_h5\pages\psiManagement\dishManage\` > - Forge H5 = `forge-h5-ui\src\pages\restaurant\` ### A2.1 后端文件对应关系 #### 菜品库管理(dishLibrary) | 源文件(JeePlus) | Forge 目标文件 | 功能说明 | |---|---|---| | `dishManage/domain/PsiDishLibrary.java` | `dish/entity/DishLibrary.java` | 菜品库实体(编码/名称/分类/图片/价格/状态) | | `dishManage/mapper/PsiDishLibraryMapper.java` | `dish/mapper/DishLibraryMapper.java` | 菜品库 Mapper 接口 | | `dishManage/mapper/xml/PsiDishLibraryMapper.xml` | `dish/mapper/DishLibraryMapper.xml` | 菜品库 SQL(列表/详情/唯一性校验/点菜查询) | | `dishManage/service/PsiDishLibraryService.java` | `dish/service/DishLibraryService.java` | 菜品库 Service(保存/删除/启停用/编码生成) | | `dishManage/controller/PsiDishLibraryController.java` | `dish/controller/DishLibraryController.java` | 菜品库 Controller(`/psi/dish` → `/api/restaurant/dish`) | #### 菜品分类管理(dishType) | 源文件(JeePlus) | Forge 目标文件 | 功能说明 | |---|---|---| | `dishManage/domain/PsiDishType.java` | `dish/entity/DishType.java` | 菜品分类实体(树形:parentId/parentIds/level) | | `dishManage/mapper/PsiDishTypeMapper.java` | `dish/mapper/DishTypeMapper.java` | 分类 Mapper 接口 | | `dishManage/mapper/xml/PsiDishTypeMapper.xml` | `dish/mapper/DishTypeMapper.xml` | 分类 SQL(列表/树/唯一性校验/子分类统计) | | `dishManage/service/PsiDishTypeService.java` | `dish/service/DishTypeService.java` | 分类 Service(保存/树构建/删除校验/排序号生成) | | `dishManage/controller/PsiDishTypeController.java` | `dish/controller/DishTypeController.java` | 分类 Controller(`/psi/dishType` → `/api/restaurant/dishType`) | #### 包房管理(dishRoom) | 源文件(JeePlus) | Forge 目标文件 | 功能说明 | |---|---|---| | `dishManage/domain/PsiDishRoom.java` | `room/entity/DishRoom.java` | 包房实体(编号/名称/容量/最低消费/使用状态) | | `dishManage/mapper/PsiDishRoomMapper.java` | `room/mapper/DishRoomMapper.java` | 包房 Mapper 接口 | | `dishManage/mapper/xml/PsiDishRoomMapper.xml` | `room/mapper/DishRoomMapper.xml` | 包房 SQL(列表/详情/编号名称唯一性/使用状态检查) | | `dishManage/service/PsiDishRoomService.java` | `room/service/DishRoomService.java` | 包房 Service(保存/删除/启停用/使用状态校验) | | `dishManage/controller/PsiDishRoomController.java` | `room/controller/DishRoomController.java` | 包房 Controller(`/psi/dishRoom` → `/api/restaurant/room`) | #### 菜单管理(dishMenu) | 源文件(JeePlus) | Forge 目标文件 | 功能说明 | |---|---|---| | `dishManage/domain/PsiDishMenu.java` | `menu/entity/DishMenu.java` | 菜单主表实体(isHistory/historyTime 版本归档) | | `dishManage/domain/PsiDishMenuDish.java` | `menu/entity/DishMenuDish.java` | 菜单菜品关联实体(菜单级独立定价 salePrice) | | `dishManage/mapper/PsiDishMenuMapper.java` | `menu/mapper/DishMenuMapper.java` | 菜单 Mapper 接口 | | `dishManage/mapper/xml/PsiDishMenuMapper.xml` | `menu/mapper/DishMenuMapper.xml` | 菜单 SQL(历史菜单列表+菜品数量统计) | | `dishManage/mapper/PsiDishMenuDishMapper.java` | `menu/mapper/DishMenuDishMapper.java` | 菜单菜品 Mapper 接口 | | `dishManage/mapper/xml/PsiDishMenuDishMapper.xml` | `menu/mapper/DishMenuDishMapper.xml` | **最复杂 SQL**(当前/历史菜品、可添加菜品、点菜菜品/分类、菜单价覆盖) | | `dishManage/service/PsiDishMenuService.java` | `menu/service/DishMenuService.java` | 菜单 Service(379 行:版本归档/添加菜品/全量保存/调价/点菜查询) | | `dishManage/controller/PsiDishMenuController.java` | `menu/controller/DishMenuController.java` | 菜单 Controller(`/psi/dishMenu` → `/api/restaurant/menu`) | #### 点菜订单(dishOrder) | 源文件(JeePlus) | Forge 目标文件 | 功能说明 | |---|---|---| | `dishManage/domain/PsiDishOrder.java` | `order/entity/DishOrder.java` | 订单实体(状态机/结账方式/金额/冗余包房信息) | | `dishManage/domain/PsiDishOrderDetail.java` | `order/entity/DishOrderDetail.java` | 订单明细实体(退菜负数数量/冗余菜品信息) | | `dishManage/mapper/PsiDishOrderMapper.java` | `order/mapper/DishOrderMapper.java` | 订单 Mapper 接口 | | `dishManage/mapper/xml/PsiDishOrderMapper.xml` | `order/mapper/DishOrderMapper.xml` | 订单 SQL(列表/当前包房订单) | | `dishManage/mapper/PsiDishOrderDetailMapper.java` | `order/mapper/DishOrderDetailMapper.java` | 订单明细 Mapper 接口 | | `dishManage/mapper/xml/PsiDishOrderDetailMapper.xml` | `order/mapper/DishOrderDetailMapper.xml` | 明细 SQL(★ GROUP BY 汇总/加菜/退菜/排序更新) | | `dishManage/service/PsiDishOrderService.java` | `order/service/DishOrderService.java` | **核心 Service**(493 行:submitOrder 状态机/结账金额/异步流程通知) | | `dishManage/controller/PsiDishOrderController.java` | `order/controller/DishOrderController.java` | 订单 Controller(`/psi/dishOrder` → `/api/restaurant/order`,含 Excel 导出) | | `dishManage/service/dto/PsiDishOrderExportDto.java` | `order/dto/DishOrderExportDto.java` | 订单导出 DTO(EasyExcel 注解) | #### 挂账客户(creditCustomer) | 源文件(JeePlus) | Forge 目标文件 | 功能说明 | |---|---|---| | `dishManage/domain/PsiCreditCustomer.java` | `credit/entity/CreditCustomer.java` | 挂账客户实体(个人信息/发票/挂账状态/审核) | | `dishManage/mapper/PsiCreditCustomerMapper.java` | `credit/mapper/CreditCustomerMapper.java` | 挂账客户 Mapper 接口 | | `dishManage/mapper/xml/PsiCreditCustomerMapper.xml` | `credit/mapper/CreditCustomerMapper.xml` | 挂账客户 SQL(列表/详情/手机号唯一/审核状态更新) | | `dishManage/service/PsiCreditCustomerService.java` | `credit/service/CreditCustomerService.java` | 挂账客户 Service(保存/流程保存/启停用/审核) | | `dishManage/controller/PsiCreditCustomerController.java` | `credit/controller/CreditCustomerController.java` | 挂账客户 Controller(`/psi/creditCustomer` → `/api/restaurant/credit`) | #### 物资管理(后续迭代) | 源文件(JeePlus) | Forge 目标文件 | 功能说明 | |---|---|---| | `collect/domain/PsiCollectBasic.java` | `material/collect/entity/CollectBasic.java` | 领用基础表(编号/经办人/领用时间/流程 ID) | | `collect/domain/PsiCollectDetailed.java` | `material/collect/entity/CollectDetailed.java` | 领用明细 | | `collect/domain/PsiCollectDetailedRecord.java` | `material/collect/entity/CollectDetailedRecord.java` | 领用明细记录(退回相关) | | `collect/domain/PsiCollectBasicsReturn.java` | `material/collect/entity/CollectReturn.java` | 领用退回 | | `collect/domain/PsiCollectBasicsReturnHi.java` | `material/collect/entity/CollectReturnHi.java` | 领用退回历史 | | `collect/controller/PsiCollectController.java` | `material/collect/controller/CollectController.java` | 领用 Controller | | `collect/service/PsiCollectService.java` | `material/collect/service/CollectService.java` | 领用 Service(含流程审批) | | `purchase/domain/PsiMaterialBasic.java` | `material/purchase/entity/PurchaseBasic.java` | 食材采购基础表 | | `purchase/domain/PsiMaterialDetailed.java` | `material/purchase/entity/PurchaseDetailed.java` | 采购明细 | | `purchase/controller/PsiMaterialController.java` | `material/purchase/controller/PurchaseController.java` | 采购 Controller | | `purchase/service/PsiMaterialService.java` | `material/purchase/service/PurchaseService.java` | 采购 Service | | `foodPurchase/domain/*`(4 张表) | `material/foodPurchase/entity/*` | 食材采购修改单(基础+明细+变更+变更明细) | | `loss/domain/PsiLossBasic.java` | `material/loss/entity/LossBasic.java` | 报损基础表 | | `loss/domain/PsiLossDetailed.java` | `material/loss/entity/LossDetailed.java` | 报损明细 | | `loss/controller/PsiLossController.java` | `material/loss/controller/LossController.java` | 报损 Controller | | `loss/service/PsiLossService.java` | `material/loss/service/LossService.java` | 报损 Service | | `psiWareHouse/domain/PsiWareHouseBasic.java` | `material/warehouse/entity/WarehouseBasic.java` | 入库基础表 | | `psiWareHouse/domain/PsiWareHouseDetailed.java` | `material/warehouse/entity/WarehouseDetailed.java` | 入库明细 | | `psiWareHouse/domain/PsiWareHouseSummary.java` | `material/warehouse/entity/WarehouseSummary.java` | 入库汇总 | | `psiWareHouse/domain/PsiWarehouseUpHi.java` | `material/warehouse/entity/WarehouseUpHi.java` | 入库修改历史 | | `psiWareHouse/controller/PsiWareHouseController.java` | `material/warehouse/controller/WarehouseController.java` | 入库 Controller | | `psiWareHouse/service/PsiWareHouseBasicService.java` | `material/warehouse/service/WarehouseService.java` | 入库 Service | | `contract/domain/PsiContract.java` | `material/contract/entity/Contract.java` | 合同表 | | `contract/domain/PsiContractUser.java` | `material/contract/entity/ContractUser.java` | 合同联系人 | | `contract/controller/PsiContractController.java` | `material/contract/controller/ContractController.java` | 合同 Controller | | `materialType/domain/PsiMaterialTypeInfo.java` | `material/type/entity/MaterialType.java` | 物资类型(树形) | | `materialType/controller/PsiMaterialTypeController.java` | `material/type/controller/MaterialTypeController.java` | 物资类型 Controller | | `materialType/service/PsiMaterialTypeService.java` | `material/type/service/MaterialTypeService.java` | 物资类型 Service | #### 供应商 | 源文件(JeePlus) | Forge 目标文件 | 功能说明 | |---|---|---| | `supplier/domain/PsiMaterialSupplier.java` | `supplier/entity/Supplier.java` | 供应商实体(名称/信用代码/地区/性质/联系方式) | | `supplier/domain/PsiMaterialSupplierLink.java` | `supplier/entity/SupplierLink.java` | 供应商联系人实体(姓名/部门/职务/电话/邮箱) | | `supplier/mapper/PsiMaterialSupplierMapper.java` | `supplier/mapper/SupplierMapper.java` | 供应商 Mapper | | `supplier/mapper/PsiMaterialSupplierLinkMapper.java` | `supplier/mapper/SupplierLinkMapper.java` | 联系人 Mapper | | `supplier/mapper/xml/PsiMaterialSupplierMapper.xml` | `supplier/mapper/SupplierMapper.xml` | 供应商 SQL | | `supplier/mapper/xml/PsiMaterialSupplierLinkMapper.xml` | `supplier/mapper/SupplierLinkMapper.xml` | 联系人 SQL | | `supplier/service/PsiMaterialSupplierService.java` | `supplier/service/SupplierService.java` | 供应商 Service | | `supplier/controller/PsiMaterialSupplierController.java` | `supplier/controller/SupplierController.java` | 供应商 Controller | #### 无需迁移的文件 | 源文件(JeePlus) | Forge 替代方案 | 说明 | |---|---|---| | `oss/controller/PsiOssController.java` | `forge-starter-file` | 文件上传,Forge 已有 | | `oss/controller/PsiOssFileController.java` | `forge-starter-file` | 文件下载,Forge 已有 | | `oss/service/PsiOSSClientService.java` | `forge-starter-file` | OSS 客户端,Forge 已有 | | `oss/service/PsiOssService.java` | `forge-starter-file` | OSS 服务,Forge 已有 | | `oss/utils/FileUtil.java` | `forge-starter-file` | 文件工具,Forge 已有 | | `serialNumTpl/*` | `forge-starter-id` | 序列号模板,Forge 用雪花 ID | ### A2.2 PC 前端文件对应关系 | 源文件(JeePlus Vue2 + Element Plus) | Forge 目标文件(Vue3 + Naive UI) | 功能说明 | |---|---|---| | **菜品库** | | | | `library/DishLibrary.vue` | `dish/DishLibrary.vue` | 菜品库列表页(左树右表,分类树+菜品表格) | | `library/DishLibraryForm.vue` | `dish/DishLibraryForm.vue` | 菜品新增/编辑/查看弹窗 | | `library/DishImageUpload.vue` | `dish/DishImageUpload.vue` | 菜品图片上传组件(OSS URL → Forge fileId+AuthImage) | | `library/DishTypeSelectTree.vue` | `dish/DishTypeSelectTree.vue` | 菜品分类选择树组件 | | **菜品分类** | | | | `type/DishType.vue` | `dish-type/DishType.vue` | 分类树形列表页(vxe-table tree-config → AiTable) | | `type/DishTypeForm.vue` | `dish-type/DishTypeForm.vue` | 分类新增/编辑弹窗 | | **包房管理** | | | | `room/DishRoomList.vue` | `room/DishRoomList.vue` | 包房卡片列表页(展示包房状态/容量/最低消费) | | `room/DishRoomForm.vue` | `room/DishRoomForm.vue` | 包房新增/编辑弹窗 | | **菜单管理** | | | | `menu/DishMenu.vue` | `menu/DishMenu.vue` | 菜单管理主页面(366 行,Tab1 当前菜单树表 + Tab2 历史菜单列表) | | `menu/DishMenuDishDialog.vue` | `menu/DishMenuDishDialog.vue` | 添加/更新菜品到菜单弹窗 | | `menu/DishMenuPriceDialog.vue` | `menu/DishMenuPriceDialog.vue` | 修改菜单价格弹窗 | | `menu/DishMenuHistoryDetailDialog.vue` | `menu/DishMenuHistoryDetailDialog.vue` | 历史菜单菜品详情弹窗 | | **点菜管理** | | | | `order/DishOrder.vue` | `order/DishOrder.vue` | 包房选择页(点菜入口,展示包房卡片+状态) | | `order/DishOrderDetail.vue` | `order/DishOrderDetail.vue` | **★ 核心点菜页面**(954 行,左右分栏:菜品选择+已点菜面板,拖拽排序) | | `order/DishOrderAdd.vue` | `order/DishOrderAdd.vue` | 加菜页面(656 行,独立页面跳转方式加菜) | | `order/DishOrderList.vue` | `order/DishOrderList.vue` | 订单记录列表(306 行,多条件筛选+导出) | | `order/DishOrderApproval.vue` | `order/DishOrderApproval.vue` | 订单审批页(Flowable 流程表单嵌入) | | `order/DishOrderSettleDialog.vue` | `order/DishOrderSettleDialog.vue` | 结账弹窗(3 Tab:普通/折扣/优惠,实时计算金额) | | `order/DishOrderConfirmDialog.vue` | `order/DishOrderConfirmDialog.vue` | 确认下单弹窗(备注+特殊要求 checkbox,字典驱动) | | `order/DishOrderReturnDialog.vue` | `order/DishOrderReturnDialog.vue` | 退菜弹窗(退菜数量输入+退菜原因) | | `order/DishOrderInfoDialog.vue` | `order/DishOrderInfoDialog.vue` | 订单详情弹窗(概要+3 Tab:实际菜单/加菜/退菜) | | **挂账客户** | | | | `creditCustomer/CreditCustomer.vue` | `credit/CreditCustomer.vue` | 挂账客户列表页(多条件筛选+启停用) | | `creditCustomer/CreditCustomerForm.vue` | `credit/CreditCustomerForm.vue` | 挂账客户新增/编辑弹窗(个人信息+发票信息) | | `creditCustomer/CreditCustomerApproval.vue` | `credit/CreditCustomerApproval.vue` | 挂账客户审批表单页(Flowable 流程嵌入) | ### A2.3 H5 移动端文件对应关系 | 源文件(JeePlus Vue2 + uView) | Forge 目标文件(Vue3 + UnoCSS) | 功能说明 | |---|---|---| | `DishOrder.vue`(269 行) | `DishOrder.vue` | 包房选择页(卡片展示包房状态,点击进入点菜) | | `DishOrderDetail.vue`(1381 行) | `DishOrderDetail.vue` | **★ 核心点菜页面**(分类导航+菜品网格+已点菜面板+内联弹窗×4) | | `DishOrderAdd.vue`(667 行) | `DishOrderAdd.vue` | 加菜页面(独立页面,与 PC 端 DishOrderAdd 功能相同) | | `DishOrderApproval.vue`(513 行) | `DishOrderApproval.vue` | 订单审批页(Flowable 流程表单,只读展示+审批操作) | ### A2.4 API 接口路径对应关系 | 源接口路径(JeePlus) | Forge 目标路径 | 方法 | 功能 | |---|---|---|---| | `GET /psi/dish/list` | `GET /api/restaurant/dish/page` | GET | 菜品库分页列表 | | `POST /psi/dish/save` | `POST /api/restaurant/dish` | POST | 新增菜品 | | `PUT /psi/dish/save` | `PUT /api/restaurant/dish` | PUT | 修改菜品 | | `GET /psi/dish/findById` | `GET /api/restaurant/dish/:id` | GET | 菜品详情 | | `DELETE /psi/dish/delete` | `DELETE /api/restaurant/dish/:id` | DELETE | 删除菜品 | | `GET /psi/dish/changeStatus` | `PUT /api/restaurant/dish/:id/status` | PUT | 启停用菜品 | | `GET /psi/dishType/list` | `GET /api/restaurant/dishType/list` | GET | 分类列表 | | `GET /psi/dishType/treeData` | `GET /api/restaurant/dishType/tree` | GET | 分类树 | | `POST /psi/dishType/save` | `POST/PUT /api/restaurant/dishType` | POST/PUT | 保存分类 | | `GET /psi/dishType/deleteById` | `DELETE /api/restaurant/dishType/:id` | DELETE | 删除分类 | | `GET /psi/dishRoom/list` | `GET /api/restaurant/room/list` | GET | 包房列表 | | `POST /psi/dishRoom/save` | `POST/PUT /api/restaurant/room` | POST/PUT | 保存包房 | | `DELETE /psi/dishRoom/delete` | `DELETE /api/restaurant/room/:id` | DELETE | 删除包房 | | `GET /psi/dishMenu/list` | `GET /api/restaurant/menu/page` | GET | 当前菜单菜品列表 | | `GET /psi/dishMenu/historyList` | `GET /api/restaurant/menu/history` | GET | 历史菜单列表 | | `GET /psi/dishMenu/historyDetailList` | `GET /api/restaurant/menu/history/:menuId` | GET | 历史菜单菜品详情 | | `GET /psi/dishMenu/availableDishList` | `GET /api/restaurant/menu/available` | GET | 可添加菜品 | | `GET /psi/dishMenu/orderDishList` | `GET /api/restaurant/menu/order-dish` | GET | 点单菜品列表 | | `GET /psi/dishMenu/orderTypeList` | `GET /api/restaurant/menu/order-type` | GET | 点单分类列表 | | `POST /psi/dishMenu/addDishes` | `POST /api/restaurant/menu/dish` | POST | 添加菜品到菜单 | | `POST /psi/dishMenu/saveDishes` | `PUT /api/restaurant/menu/dish` | PUT | 全量保存菜单菜品 | | `POST /psi/dishMenu/updatePrice` | `PUT /api/restaurant/menu/price` | PUT | 调整菜单价格 | | `DELETE /psi/dishMenu/delete` | `DELETE /api/restaurant/menu/dish/:id` | DELETE | 删除菜单菜品 | | `POST /psi/dishMenu/updateMenu` | `POST /api/restaurant/menu/update` | POST | 更新菜单(归档旧菜单) | | `GET /psi/dishOrder/typeList` | `GET /api/restaurant/order/type-list` | GET | 有菜品的分类 | | `GET /psi/dishOrder/dishList` | `GET /api/restaurant/order/dish-list` | GET | 可点菜品 | | `GET /psi/dishOrder/orderList` | `GET /api/restaurant/order/page` | GET | 订单列表 | | `GET /psi/dishOrder/exportFile` | `GET /api/restaurant/order/export` | GET | 导出订单 Excel | | `GET /psi/dishOrder/findOrderById` | `GET /api/restaurant/order/:id` | GET | 订单详情 | | `GET /psi/dishOrder/currentOrder` | `GET /api/restaurant/order/current` | GET | 当前包房订单 | | `GET /psi/dishOrder/cancelOrder` | `PUT /api/restaurant/order/:id/cancel` | PUT | 取消订单 | | `POST /psi/dishOrder/submit` | `POST /api/restaurant/order/submit` | POST | 下单/加菜/退菜/结账 | | `GET /psi/creditCustomer/list` | `GET /api/restaurant/credit/page` | GET | 挂账客户列表 | | `POST /psi/creditCustomer/save` | `POST/PUT /api/restaurant/credit` | POST/PUT | 保存挂账客户 | | `POST /psi/creditCustomer/saveFlow` | `POST /api/restaurant/credit/flow` | POST | 流程表单保存 | | `POST /psi/creditCustomer/updateStatusById` | `PUT /api/restaurant/credit/:id/status` | PUT | 更新审核状态 | | `DELETE /psi/creditCustomer/delete` | `DELETE /api/restaurant/credit/:id` | DELETE | 删除挂账客户 | | `GET /psi/creditCustomer/changeStatus` | `PUT /api/restaurant/credit/:id/credit-status` | PUT | 修改挂账状态 | --- ## 附录 B:实体类完整字段定义(迁移时需逐字段对照) > 以下字段定义直接从源码提取。迁移时需注意: > - `String id` → `Long id`(雪花 ID) > - `createById` → `createBy`(Long) > - `updateById` → `updateBy`(Long) > - `createDate` → `createTime`(LocalDateTime) > - `delFlag` Integer 0/1 → Long 0/主键ID > - `tenantId` String → Long > - `BigDecimal` 金额 → 保持或改 `Long` 分 ### B.1 PsiDishLibrary — 菜品库(89 行) | 字段 | 类型 | 数据库列 | 说明 | |------|------|----------|------| | id | String | id | 主键(varchar 64) | | dishCode | String | dish_code | 菜品编码,自动生成 `CP`+时间戳 | | dishName | String | dish_name | 菜品名称 | | typeId | String | type_id | 分类 ID | | imageUrl | String | image_url | 菜品图片(OSS URL → Forge 需改 fileId) | | unit | String | unit | 单位 | | spec | String | spec | 规格 | | salePrice | BigDecimal | sale_price | 销售价 | | costPrice | BigDecimal | cost_price | 参考成本价 | | taste | String | taste | 口味 | | status | String | status | 状态:0启用,1停用 | | sort | Integer | sort | 排序 | | remarks | String | remarks | 备注 | | *typeName* | String | — | 虚拟字段,LEFT JOIN psi_dish_type | | *createName* | String | — | 虚拟字段,LEFT JOIN sys_user | **继承自 BaseEntity**:createById, createTime, updateById, updateTime, delFlag, tenantId ### B.2 PsiDishType — 菜品分类(83 行,树形) | 字段 | 类型 | 数据库列 | 说明 | |------|------|----------|------| | id | String | id | 主键 | | name | String | name | 分类名称 | | parentId | String | parent_id | 父级 ID | | parentIds | String | parent_ids | 父级链路(逗号分隔) | | level | String | level | 层级 | | sort | Integer | sort | 排序 | | status | String | status | 0启用,1停用 | | remarks | String | remarks | 备注 | | delFlag | Integer | del_flag | @TableLogic | | *disabled* | Boolean | — | 虚拟字段,默认 false | **继承自 TreeEntity**:含 children 列表 ### B.3 PsiDishRoom — 包房(62 行) | 字段 | 类型 | 数据库列 | 说明 | |------|------|----------|------| | id | String | id | 主键 | | roomNo | String | room_no | 包房编号,自动生成 `BF`+时间戳 | | roomName | String | room_name | 包房名称 | | capacity | Integer | capacity | 容纳人数 | | minConsumption | BigDecimal | min_consumption | 最低消费 | | status | String | status | 0启用,1停用 | | useStatus | String | use_status | 0空闲中,1使用中 | | sort | Integer | sort | 排序 | | remarks | String | remarks | 备注 | ### B.4 PsiDishMenu — 菜单主表(37 行) | 字段 | 类型 | 数据库列 | 说明 | |------|------|----------|------| | id | String | id | 主键 | | isHistory | String | is_history | 0否/null否,1是 | | historyTime | Date | history_time | 成为历史的时间 | | remarks | String | remarks | 备注 | | *createName* | String | — | 虚拟字段 | | *dishCount* | Integer | — | 虚拟字段,菜品数量 | ### B.5 PsiDishMenuDish — 菜单菜品关联(76 行) | 字段 | 类型 | 数据库列 | 说明 | |------|------|----------|------| | id | String | id | 主键 | | salePrice | BigDecimal | sale_price | **菜单级独立定价** | | sort | Integer | sort | 排序 | | remarks | String | remarks | 备注 | | isHistory | String | is_history | 0否/null否,1是 | | historyTime | Date | history_time | 成为历史的时间 | | menuId | String | menu_id | 菜单 ID | | dishId | String | dish_id | 菜品 ID | | *dishCode* | String | — | 虚拟,来自 dish_library | | *dishName* | String | — | 虚拟 | | *typeId* | String | — | 虚拟 | | *typeName* | String | — | 虚拟 | | *imageUrl* | String | — | 虚拟 | | *unit* | String | — | 虚拟 | | *spec* | String | — | 虚拟 | | *taste* | String | — | 虚拟 | | *status* | String | — | 虚拟 | | *librarySalePrice* | BigDecimal | — | 虚拟,菜品库原价 | | *createName* | String | — | 虚拟 | ### B.6 PsiDishOrder — 点菜订单(76 行) | 字段 | 类型 | 数据库列 | 说明 | |------|------|----------|------| | id | String | id | 主键 | | orderNo | String | order_no | 订单号 `DC`+时间戳 | | roomId | String | room_id | 包房 ID | | roomNo | String | room_no | 包房编号(冗余) | | roomName | String | room_name | 包房名称(冗余) | | orderStatus | String | order_status | 0用餐中,1已结账,2已取消 | | totalAmount | BigDecimal | total_amount | 总金额 | | settleType | String | settle_type | 0结账,1折扣,2优惠 | | discountRate | BigDecimal | discount_rate | 折扣比例 | | discountAmount | BigDecimal | discount_amount | 优惠金额 | | payableAmount | BigDecimal | payable_amount | 实收金额 | | settleTime | Date | settle_time | 结账时间 | | tasteRemark | String | taste_remark | 口味备注 | | specialRequirements | String | special_requirements | 特殊要求 | | remarks | String | remarks | 备注 | | *createTimes* | String[] | — | 虚拟,时间范围查询 | | *settleTimes* | String[] | — | 虚拟 | | *createName* | String | — | 虚拟 | | *settleFlag* | String | — | 虚拟,0=下单/加菜/退菜,1=结账,2=刷新 | | *detailList* | List | — | 虚拟,三类明细 | | *addDishList* | List | — | 虚拟,加菜列表 | | *reduceDishList* | List | — | 虚拟,退菜列表 | ### B.7 PsiDishOrderDetail — 订单明细(60 行) | 字段 | 类型 | 数据库列 | 说明 | |------|------|----------|------| | id | String | id | 主键 | | orderId | String | order_id | 订单 ID | | roomId | String | room_id | 包房 ID | | dishId | String | dish_id | 菜品 ID | | dishCode | String | dish_code | 菜品编码(冗余) | | dishName | String | dish_name | 菜品名称(冗余) | | typeId | String | type_id | 分类 ID(冗余) | | typeName | String | type_name | 分类名称(冗余) | | unit | String | unit | 单位(冗余) | | spec | String | spec | 规格(冗余) | | salePrice | BigDecimal | sale_price | 单价(来自菜单价) | | quantity | Integer | quantity | **数量,退菜时为负数** | | amount | BigDecimal | amount | 金额 = salePrice × quantity | | dishSort | Integer | dish_sort | 排序 | | isAddDish | String | is_add_dish | 0否,1是 | | reason | String | reason | 退菜原因 | | remarks | String | remarks | 备注 | | *currentQuantity* | Integer | — | 虚拟字段 | ### B.8 PsiCreditCustomer — 挂账客户(79 行) | 字段 | 类型 | 数据库列 | 说明 | |------|------|----------|------| | id | String | id | 主键 | | customerName | String | customer_name | 姓名 | | mobile | String | mobile | 手机号(唯一校验) | | birthday | Date | birthday | 生日 | | idCard | String | id_card | 身份证 | | age | Integer | age | 年龄 | | occupation | String | occupation | 职业 | | companyName | String | company_name | 公司名称 | | address | String | address | 地址 | | emergencyContact | String | emergency_contact | 紧急联系人 | | emergencyContactPhone | String | emergency_contact_phone | 紧急联系电话 | | invoiceTitle | String | invoice_title | 发票抬头 | | taxNo | String | tax_no | 税号 | | bankName | String | bank_name | 银行名称 | | bankAccount | String | bank_account | 银行账号 | | invoiceAddressPhone | String | invoice_address_phone | 发票地址电话 | | creditStatus | String | credit_status | 1正常,2暂停,3黑名单 | | totalArrearsAmount | BigDecimal | total_arrears_amount | 累计挂账金额 | | unsettledBillCount | Integer | unsettled_bill_count | 未结账单数 | | firstCreditTime | Date | first_credit_time | 首次挂账时间 | | lastConsumeTime | Date | last_consume_time | 最近消费时间 | | auditorId | String | auditor_id | 审核人 ID | | status | String | status | 审核状态 | | remarks | String | remarks | 备注 | | *createName* | String | — | 虚拟 | | *auditorName* | String | — | 虚拟 | ### B.9 PsiMaterialSupplier — 供应商(71 行) | 字段 | 类型 | 数据库列 | 说明 | |------|------|----------|------| | id | String | id | 主键 | | name | String | name | 名称 | | isUscCode | String | is_usc_code | 是否有统一信用代码 | | uscCode | String | usc_code | 统一社会信用代码 | | reconciliationArea | String | reconciliation_area | 归属地区 | | characterIs | String | character_is | 供应商性质 | | zipCode | String | zip_code | 邮编 | | fax | String | fax | 传真 | | telPhone | String | tel_phone | 联系电话 | | address | String | address | 地址 | | remarks | String | remarks | 备注 | ### B.10 PsiMaterialSupplierLink — 供应商联系人(62 行) | 字段 | 类型 | 数据库列 | 说明 | |------|------|----------|------| | id | String | id | 主键 | | name | String | name | 联系人姓名 | | office | String | office | 部门 | | position | String | position | 职务 | | sex | String | sex | 性别 | | linkPhone | String | link_phone | 联系方式1 | | linkMobile | String | link_mobile | 联系方式2 | | email | String | email | E-mail | | supplierId | String | supplier_id | 供应商 ID | | remarks | String | remarks | 备注 | ### B.11 PsiCollectBasic — 领用基础表(64 行) | 字段 | 类型 | 数据库列 | 说明 | |------|------|----------|------| | id | String | id | 主键 | | remarks | String | remarks | 备注 | | procInsId | String | proc_ins_id | 流程实例 ID | | status | String | status | 状态 | | processDefinitionId | String | process_definition_id | 流程定义 ID | | collectNo | String | collect_no | 领用编号 | | handledBy | String | handled_by | 经办人 | | handledByOffice | String | handled_by_office | 经办人部门 | | collectDate | Date | collect_date | 领用时间 | | *detailInfos* | List | — | 虚拟,领用明细列表 | --- ## 附录 C:Mapper XML 完整 SQL(迁移时需逐条改写) > 迁移要点: > - `${ew.customSqlSegment}` 需保留(MP 动态条件注入) > - `del_flag = '0'` 需改为 `del_flag = 0`(Forge 用 bigint) > - `create_by_id` → `create_by`,`update_by_id` → `update_by` > - `sys_user` 表 JOIN 条件中 `su.id = a.create_by_id` → `su.id = a.create_by` > - 所有 `varchar` 主键 JOIN 改为 `bigint` 匹配 > - 租户拦截由 `TenantLineInnerInterceptor` 自动追加,XML 中不需写 `tenant_id` 条件 --- ## 附录 D:JeePlus → Forge 字段/注解/工具映射速查表 ### D.1 实体层映射 | JeePlus Cloud | Forge Admin | 说明 | |---------------|-------------|------| | `DataEntity` | `BaseEntity` | 基类替换 | | `TreeEntity` | `TreeEntity`(Forge 版) | 树形基类 | | `String id`(varchar 64) | `Long id`(bigint 雪花) | 主键类型 | | `String createById` | `Long createBy` | 创建人 | | `String updateById` | `Long updateBy` | 更新人 | | `Date createTime` | `LocalDateTime createTime` | 创建时间 | | `Date updateTime` | `LocalDateTime updateTime` | 更新时间 | | `Integer delFlag`(0/1) | `Long delFlag`(0/主键ID) | 逻辑删除 | | `String tenantId` | `Long tenantId` | 租户 ID | | `String remarks` | `String remark` | 备注(可选保留 remarks) | | `UUID.randomUUID().toString().replace("-","")` | 雪花 ID 自动生成 | 不需手动设 ID | | `@TableLogic Integer delFlag` | `@TableLogic Long delFlag` | 类型要匹配 | ### D.2 注解映射 | JeePlus Cloud | Forge Admin | 说明 | |---------------|-------------|------| | `@PreAuthorize("hasAuthority('xxx')")` | `@SaCheckPermission("xxx")` | 权限注解 | | `@PreAuthorize("hasAnyAuthority('a','b')")` | `@SaCheckPermission("a")` + `@SaCheckPermission("b")` | 多权限 | | `@ApiLog(value = "xxx", type = LogTypeEnum.SAVE)` | `@OperationLog("xxx")` | 操作日志 | | `@Api(tags = "xxx")` | 不需要(Forge 无 Swagger 注解要求) | 可删除 | | `@ApiOperation(value = "xxx")` | 不需要 | 可删除 | | `@Query(tableColumn = "a.xxx", type = QueryType.LIKE)` | 在 Mapper XML 中写 LIKE | Forge 不用 @Query | | `@JsonFormat(pattern = "yyyy-MM-dd")` | `@JsonFormat(pattern = "yyyy-MM-dd")` | 保持一致 | ### D.3 Service 层映射 | JeePlus Cloud | Forge Admin | 说明 | |---------------|-------------|------| | `extends ServiceImpl` | `extends ServiceImpl` | 保持一致 | | `SpringUtil.getBean(IUserApi.class).getByToken(...)` | `StpUtil.getLoginIdAsLong()` | 获取当前用户 | | `TokenProvider.getCurrentToken()` | 不需要 | Sa-Token 直接获取 | | `SpringUtil.getBean(IRoleApi.class).getRoleDTOByName2("老板")` | 本地 RoleService 查询 | 去 Feign | | `SpringUtil.getBean(IUserApi.class).findListByRoleId(...)` | 本地 UserService 查询 | 去 Feign | | `SpringUtil.getBean(IFlowableApi.class).add(map)` | `@FlowBind` + `@FlowStart` | 流程集成方式完全不同 | | `Executors.newFixedThreadPool(5)` | Spring `@Async` + `ThreadPoolTaskExecutor` | 异步线程池 | ### D.4 Controller 层映射 | JeePlus Cloud | Forge Admin | 说明 | |---------------|-------------|------| | `ResponseEntity` | `RespInfo` | 统一响应 | | `ResponseEntity.ok(data)` | `RespInfo.success(data)` | 成功响应 | | `ResponseEntity.badRequest().body(msg)` | `RespInfo.error(msg)` | 错误响应 | | `@RestController` | `@RestController` | 保持一致 | | `@RequestMapping("/psi/dish")` | `@RequestMapping("/api/restaurant/dish")` | 路径前缀调整 | | `@GetMapping("/list")` + `Page` | `@GetMapping("/page")` + `pageNum/pageSize` | 分页接口命名 | | `@GetMapping("/findById")` | `@GetMapping("/{id}")` | RESTful 风格 | | `@PostMapping("/save")` | `@PostMapping` 或 `@PutMapping` | 新增/修改分开 | | `@DeleteMapping("/delete")` + `ids` | `@DeleteMapping("/{id}")` | RESTful 风格 | | `@GetMapping("/changeStatus")` | `@PutMapping("/{id}/status")` | RESTful 风格 | ### D.5 前端映射 | JeePlus Cloud | Forge Admin | 说明 | |---------------|-------------|------| | Vue 2 Options API | Vue 3 Composition API (`