ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

云禾外卖补充—项目整体初始架构解析

云禾外卖补充—项目整体初始架构解析

sky-server 只完成了一个业务模块(员工管理),其它业务(订单/菜品/套餐/购物车/用户/地址/报表)只到 entity/dto/vo 这层,没有业务实现

一、三个子工程的整体职责

模块职责可被谁依赖
sky-common通用工具箱:常量、异常、响应包装、配置类、JWT/OSS/微信工具、JSON 映射sky-pojo、sky-server
sky-pojo数据模型层:entity(数据库表映射)、dto(前端→后端入参)、vo(后端→前端出参)sky-server
sky-server业务实现层:启动类、配置、Controller、Service、Mapper、拦截器、异常处理不被任何模块依赖(部署入口)

依赖方向:server → pojo → common,server → common(直接用工具类)。典型的三层依赖倒置结构。


二、sky-common(28 个类,6 个包)

包类职责
constantAutoFillConstantAOP 自动填充注解里用的常量(SET_CREATE_USER/SET_UPDATE_USER等)
JwtClaimsConstantJWT claims 的 key 名(如EMP_ID= "empId")
MessageConstant业务异常文案(如"账号不存在""密码错误")
PasswordConstant默认密码常量"123456"
StatusConstant员工/菜品状态常量(ENABLE=1/DISABLE=0)
contextBaseContext基于 ThreadLocal 存当前登录用户 id(拦截器写入,业务层取出)
enumerationOperationTypeAOP 枚举:UPDATE/INSERT,配合@AutoFill用
exceptionBaseException所有业务异常的父类
AccountNotFoundException账号不存在
AccountLockedException账号被锁定
PasswordErrorException密码错误
PasswordEditFailedException修改密码失败
LoginFailedException登录失败
UserNotLoginException用户未登录
AddressBookBusinessException地址簿业务异常
OrderBusinessException订单业务异常
ShoppingCartBusinessException购物车业务异常
SetmealEnableFailedException套餐起售失败(含未停售菜品)
DeletionNotAllowedException删除受限(外键关联)
jsonJacksonObjectMapper自定义 Jackson 序列化器(LocalDateTime/Long→String 等)
propertiesJwtProperties绑定sky.jwt.*配置(密钥、TTL、token 名称)
AliOssProperties绑定sky.alioss.*配置(endpoint、accessKey、bucket)
WeChatProperties绑定sky.wechat.*配置(appid、secret、商户号)
resultResult<T>统一响应体{code, msg, data}
PageResult分页结果{total, records}
utilsJwtUtilcreateJWT / parseJWT(基于 jjwt 0.9.1)
AliOssUtilupload / getFileUrl(基于阿里云 OSS SDK)
WeChatPayUtil微信支付下单/退款/查询封装
HttpClientUtil基于 HttpClient 的 HTTP 工具

三、sky-pojo(51 个类,3 个包,纯 POJO)

包数量职责
entity11 个数据库表映射:Employee/Category(分类)/Dish(菜品)/DishFlavor(菜品口味)/Setmeal(套餐)/SetmealDish(套餐-菜品关系)/Orders(订单)/OrderDetail(订单明细)/ShoppingCart(购物车)/User(C 端用户)/AddressBook(地址簿)
dto19 个Controller 入参:EmployeeDTO(新增员工)、EmployeeLoginDTO(登录)、EmployeePageQueryDTO(分页)、CategoryDTO/CategoryPageQueryDTO、DishDTO/DishPageQueryDTO、SetmealDTO/SetmealPageQueryDTO、OrdersDTO(下单)/OrdersPageQueryDTO(分页)/OrdersSubmitDTO(提交)/OrdersPaymentDTO(支付)/OrdersConfirmDTO(接单)/OrdersRejectionDTO(拒单)/OrdersCancelDTO(取消)、ShoppingCartDTO、UserLoginDTO(C 端微信登录)、PasswordEditDTO、GoodsSalesDTO(销量 Top10)、DataOverViewQueryDTO(数据看板)
vo21 个Controller 出参:EmployeeLoginVO(带 token)、UserLoginVO(C 端带 openid)、DishVO(含口味列表)、SetmealVO(含菜品列表)、OrderVO(含明细)、OrderSubmitVO、OrderPaymentVO(支付参数)、OrderStatisticsVO(各状态订单数量)、OrderOverViewVO(管理端今日订单概览)、SetmealOverViewVO/DishOverViewVO(起售停售概览)、TurnoverReportVO/UserReportVO/OrderReportVO/SalesTop10ReportVO(数据报表)、DishItemVO(按分类查菜品)、BusinessDataVO(工作台数据)

注意:pojo 的类全部是数据载体,没有任何业务逻辑(没有注解、没有方法),跟表结构/接口一一对应。


四、sky-server(全模块只 8 个文件)

sky-server/src/main/java/com/sky/ ├── SkyApplication.java # 启动类 ├── config/ │ └── WebMvcConfiguration.java # Web 配置(拦截器、Knife4j、静态资源) ├── handler/ │ └── GlobalExceptionHandler.java # 全局异常处理 ├── interceptor/ │ └── JwtTokenAdminInterceptor.java # JWT 拦截器 ├── controller/admin/ │ └── EmployeeController.java # 员工 Controller(仅 1 个) ├── service/ │ ├── EmployeeService.java # 员工 Service 接口 │ └── impl/ │ └── EmployeeServiceImpl.java # 员工 Service 实现(仅 1 个) └── mapper/ └── EmployeeMapper.java # 员工 Mapper(仅 1 个)

每个类真实职责

类关键注解 / 配置实际做的事
SkyApplication@SpringBootApplication+@EnableTransactionManagement启动入口,开启注解事务
WebMvcConfiguration@Configuration继承WebMvcConfigurationSupport① 注册 JWT 拦截器:拦截/admin/**,放行/admin/employee/login;② 配置 Knife4j 文档:扫描com.sky.controller包,访问/doc.html;③ 映射 Swagger 静态资源
JwtTokenAdminInterceptor@Component实现HandlerInterceptor从请求头拿token→JwtUtil.parseJWT解析 → 把员工 id 存到BaseContext的 ThreadLocal里;失败返 401
GlobalExceptionHandler@RestControllerAdvice+@ExceptionHandler捕获所有BaseException子类 → 打日志 → 返回Result.error(msg),保证任何业务异常都包成统一响应体
EmployeeController@RestController+@RequestMapping("/admin/employee")3 个接口:/login(登录返 JWT token)、/logout(登出)、POST /(新增员工save)
EmployeeService接口2 个方法签名:login(EmployeeLoginDTO)、save(EmployeeDTO)
EmployeeServiceImpl@Service只有login写完了(58 行):查用户 → MD5 比对密码 → 校验账号状态。save方法是空的(接口里声明了,实现没写)
EmployeeMapper@Mapper,XML 在resources/mapper/EmployeeMapper.xml当前只有 1 个方法:@Select注解方式按用户名查询

五、目前项目情况

业务entitydtovoControllerServiceMapper
员工 Employee✅✅✅✅ 1 个✅ 1 个(只完成 login)✅ 1 个
分类 Category✅✅—❌❌❌
菜品 Dish / DishFlavor✅✅✅❌❌❌
套餐 Setmeal / SetmealDish✅✅✅❌❌❌
订单 Orders / OrderDetail✅✅✅❌❌❌
购物车 ShoppingCart✅✅—❌❌❌
C 端用户 User✅✅✅❌❌❌
地址簿 AddressBook✅——❌❌❌
报表(营业额/用户/订单/SalesTop10)—✅✅❌❌❌
  • 目前能跑通的接口:只有/admin/employee/login、/admin/employee/logout
  • 需要编写:分类/菜品/套餐的 CRUD、购物车、订单(下单→支付→接单→拒单→催单)、WebSocket 实时通知、阿里云 OSS 上传、Excel 报表、微信登录/支付、AOP 自动填充、切面日志、AOP Redis 缓存等

目前entity/dto/vo 都已建好表,只需写 Controller → Service → Mapper 即可

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进