From 661036694f02ff1551683122a4f8b0d64a518242 Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Mon, 16 Mar 2026 16:56:41 +0800 Subject: [PATCH] =?UTF-8?q?changelog:=20522a737=20-=20feat:=20Knife4j?= =?UTF-8?q?=E7=BD=91=E5=85=B3=E6=96=87=E6=A1=A3=E4=BF=AE=E5=A4=8D=20+=20AI?= =?UTF-8?q?=20Bridge=E5=A2=9E=E5=BC=BA=20+=20bootstrap=E9=BB=98=E8=AE=A4Na?= =?UTF-8?q?cos=E6=94=B9=E6=9C=AC=E5=9C=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-03-16_522a737_feat_Knife4j.md | 36070 ++-------------- 1 file changed, 3193 insertions(+), 32877 deletions(-) diff --git a/changelogs/2026-03/2026-03-16_522a737_feat_Knife4j.md b/changelogs/2026-03/2026-03-16_522a737_feat_Knife4j.md index 78ad9f6..315a105 100644 --- a/changelogs/2026-03/2026-03-16_522a737_feat_Knife4j.md +++ b/changelogs/2026-03/2026-03-16_522a737_feat_Knife4j.md @@ -1,15 +1,3198 @@ -# 接口变更记录 +# 接口变更记录 - 2026-03-16 -## 提交信息 +> **提交**: `522a737` | **作者**: wx | **时间**: 2026-03-16 16:50:04 +0800 +> +> **说明**: feat: Knife4j网关文档修复 + AI Bridge增强 + bootstrap默认Nacos改本地 -| 项目 | 内容 | -|------|------| -| **Hash** | `522a737928b06cb5114e815e08b7ee997075ce6d` | -| **作者** | wx | -| **时间** | 2026-03-16 16:50:04 +0800 | -| **说明** | feat: Knife4j网关文档修复 + AI Bridge增强 + bootstrap默认Nacos改本地 | +## ⚡ 接口变更速览 -## 变更文件总览 +- **产品服务** + - ✏️ **District** 修改1个接口 + - ✏️ **Family** 修改2个接口 + - ✏️ **Formula** 修改13个接口 + - ✏️ **GroupBatch** 修改7个接口 + - ✏️ **InternalMpProduct** 修改4个接口 + - ✏️ **InternalProduct** 修改16个接口 + - ✏️ **Itinerary** 修改9个接口 + - ✏️ **MpProduct** 修改3个接口 + - ✏️ **Pricing** 修改3个接口 + - ✏️ **Product** 修改2个接口 + - ✏️ **ProductFolder** 修改1个接口 + - ✏️ **ProductLine** 修改2个接口 + - ✏️ **Quote** 修改1个接口 +- **任务服务** + - ✏️ **Board** 修改9个接口 + - ✏️ **Task** 修改9个接口 +- **企微回调服务** + - ✏️ **WxCallback** 修改4个接口 +- **保险服务** + - ✏️ **AdminInsurance** 修改3个接口 + - ✏️ **AdminInsuranceScheme** 修改2个接口 + - ✏️ **InternalInsurance** 修改1个接口 +- **合同服务** + - ✏️ **AdminClauseTemplate** 修改4个接口 + - ✏️ **AdminContract** 修改10个接口 + - ✏️ **ContractCallback** 修改1个接口 + - ✏️ **InternalContract** 修改4个接口 + - ✏️ **InternalMpContract** 修改4个接口 +- **小程序聚合服务** + - ✏️ **MpContract** 修改4个接口 + - ✏️ **MpDesigner** 修改2个接口 + - ✏️ **MpDict** 修改1个接口 + - ✏️ **MpExplore** 修改6个接口 + - ✏️ **MpFavorite** 修改1个接口 + - ✏️ **MpFootprint** 修改1个接口 + - ✏️ **MpInsurance** 修改1个接口 + - ✏️ **MpInvoice** 修改3个接口 + - ✏️ **MpOrder** 修改5个接口 + - ✏️ **MpPayment** 修改2个接口 + - ✏️ **MpProduct** 修改4个接口 + - ✏️ **MpRefund** 修改4个接口 + - ✏️ **MpReview** 修改7个接口 + - ✏️ **MpTraveler** 修改2个接口 + - ✏️ **MpTrip** 修改3个接口 + - ✏️ **MpUser** 修改3个接口 + - ✏️ **MpWeather** 修改3个接口 + - ✏️ **MpWiki** 修改2个接口 +- **支付服务** + - ✏️ **AdminPayment** 修改2个接口 + - ✏️ **InternalPayment** 修改3个接口 + - ✏️ **PaymentCallback** 修改1个接口 +- **攻略服务** + - ✏️ **AdminGuideArticle** 修改6个接口 + - ✏️ **AdminGuideCategory** 修改4个接口 + - ✏️ **AdminGuideTag** 修改4个接口 + - ✏️ **InternalWiki** 修改2个接口 +- **文件服务** + - ✏️ **File** 修改8个接口 + - ✏️ **InternalFile** 修改8个接口 + - ✏️ **MpFile** 修改1个接口 +- **用户服务** + - ✏️ **AdminAgreement** 修改3个接口 + - ✏️ **AdminBanner** 修改3个接口 + - ✏️ **AdminContact** 修改3个接口 + - ✏️ **AdminCustomer** 修改4个接口 + - ✏️ **AdminDesigner** 修改3个接口 + - ✏️ **AdminExploreCategory** 修改2个接口 + - ✏️ **AdminFaq** 修改6个接口 + - ✏️ **AdminFrontendConfig** 修改4个接口 + - ✏️ **AdminProfile** 修改4个接口 + - ✏️ **AdminTopic** 修改3个接口 + - ✏️ **AdminUser** 修改7个接口 + - ✏️ **Auth** 修改13个接口 + - ✏️ **Favorite** 修改2个接口 + - ✏️ **Footprint** 修改2个接口 + - ✏️ **InternalApproval** 修改3个接口 + - ✏️ **InternalBadge** 修改1个接口 + - ✏️ **InternalContact** 修改1个接口 + - ✏️ **InternalDesigner** 修改1个接口 + - ✏️ **InternalExploreCategory** 修改2个接口 + - ✏️ **InternalLike** 修改4个接口 + - ✏️ **InternalLoginLog** 修改1个接口 + - ✏️ **InternalMpCommon** 修改2个接口 + - ✏️ **InternalMpDict** 修改2个接口 + - ✏️ **InternalMpMessage** 修改6个接口 + - ✏️ **InternalMpUser** 修改19个接口 + - ✏️ **InternalOrderUser** 修改1个接口 + - ✏️ **InternalUser** 修改8个接口 + - ✏️ **InternalWechat** 修改6个接口 + - ✏️ **InternalWish** 修改1个接口 + - ✏️ **PublicDict** 修改1个接口 + - ✏️ **SysDict** 修改12个接口 + - ✏️ **SysJob** 修改7个接口 + - ✏️ **SysMenu** 修改5个接口 + - ✏️ **SysRole** 修改6个接口 + - ✏️ **Traveler** 修改4个接口 + - ✏️ **User** 修改8个接口 + - ✏️ **WechatSync** 修改5个接口 + - ✏️ **AdminNotification** 修改4个接口 +- **监控服务** + - ✏️ **ApprovalLog** 修改1个接口 + - ✏️ **DataRetention** 修改1个接口 + - ✏️ **ErrorLog** 修改1个接口 + - ✏️ **InternalLog** 修改5个接口 + - ✏️ **MysqlMonitor** 修改2个接口 + - ✏️ **NotificationLog** 修改1个接口 + - ✏️ **OperationLog** 修改1个接口 + - ✏️ **RocketMqMonitor** 修改2个接口 +- **素材服务** + - ✏️ **InternalMaterial** 修改4个接口 + - ✏️ **MaterialCategoryPermission** 修改2个接口 + - ✏️ **Material** 修改13个接口 + - ✏️ **MaterialTag** 修改1个接口 + - ✏️ **MpMaterial** 修改1个接口 +- **订单服务** + - ✏️ **AdminAlbum** 修改7个接口 + - ✏️ **AdminEarlyBird** 修改5个接口 + - ✏️ **AdminOrderConfig** 修改2个接口 + - ✏️ **AdminOrder** 修改13个接口 + - ✏️ **AdminOrderItinerary** 修改17个接口 + - ✏️ **AdminOrderTodo** 修改7个接口 + - ✏️ **AdminRefund** 修改6个接口 + - ✏️ **AdminRefundPolicy** 修改3个接口 + - ✏️ **AdminWorkOrder** 修改8个接口 + - ✏️ **InternalAlbum** 修改3个接口 + - ✏️ **InternalDashboard** 修改10个接口 + - ✏️ **InternalDesignerOrder** 修改4个接口 + - ✏️ **InternalEarlyBird** 修改2个接口 + - ✏️ **InternalInvoice** 修改4个接口 + - ✏️ **InternalMpOrder** 修改9个接口 + - ✏️ **InternalMpTrip** 修改4个接口 + - ✏️ **InternalOrderStats** 修改3个接口 + - ✏️ **InternalOrderTraveler** 修改2个接口 + - ✏️ **InternalPaymentOrder** 修改4个接口 + - ✏️ **InternalRefund** 修改8个接口 + - ✏️ **MpOrder** 修改2个接口 + - ✏️ **MpWeather** 修改3个接口 +- **评价服务** + - ✏️ **AdminReview** 修改5个接口 + - ✏️ **InternalMpReview** 修改8个接口 + - ✏️ **InternalReview** 修改6个接口 +- **资源服务** + - ✏️ **Activity** 修改9个接口 + - ✏️ **ActivityPriceCalendar** 修改4个接口 + - ✏️ **ActivityTag** 修改8个接口 + - ✏️ **InternalActivity** 修改3个接口 + - ✏️ **InternalMpActivity** 修改2个接口 + - ✏️ **InternalMpResourceBrief** 修改3个接口 + - ✏️ **InternalResource** 修改1个接口 + - ✏️ **InternalResourceDetail** 修改1个接口 + - ✏️ **InternalResourceStats** 修改2个接口 + - ✏️ **CostItem** 修改8个接口 + - ✏️ **CostPriceCalendar** 修改3个接口 + - ✏️ **InternalCost** 修改4个接口 + - ✏️ **Hotel** 修改10个接口 + - ✏️ **HotelTag** 修改8个接口 + - ✏️ **InternalHotel** 修改3个接口 + - ✏️ **InternalMpHotel** 修改2个接口 + - ✏️ **RoomPriceCalendar** 修改4个接口 + - ✏️ **RoomType** 修改7个接口 + - ✏️ **InternalMpRestaurant** 修改2个接口 + - ✏️ **InternalRestaurant** 修改3个接口 + - ✏️ **Restaurant** 修改9个接口 + - ✏️ **RestaurantTag** 修改8个接口 + - ✏️ **InternalMpScenic** 修改3个接口 + - ✏️ **InternalScenic** 修改7个接口 + - ✏️ **ScenicPriceCalendar** 修改4个接口 + - ✏️ **ScenicSeason** 修改3个接口 + - ✏️ **ScenicSpot** 修改9个接口 + - ✏️ **ScenicTag** 修改8个接口 + - ✏️ **InternalService** 修改3个接口 + - ✏️ **ServiceItem** 修改9个接口 + - ✏️ **ServicePriceCalendar** 修改4个接口 + - ✏️ **ServiceTag** 修改8个接口 + - ✏️ **InternalStaff** 修改6个接口 + - ✏️ **Staff** 修改8个接口 + - ✏️ **StaffPriceCalendar** 修改4个接口 + - ✏️ **StaffTag** 修改8个接口 + - ✏️ **InternalSupplies** 修改3个接口 + - ✏️ **Supplies** 修改9个接口 + - ✏️ **SuppliesTag** 修改8个接口 + - ✏️ **InternalVehicle** 修改5个接口 + - ✏️ **VehicleModel** 修改10个接口 + - ✏️ **VehiclePriceCalendar** 修改4个接口 + - ✏️ **VehicleTag** 修改8个接口 + +--- + +## 产品服务 + +### ✏️ District (修改) + +**修改接口:** + +- `GET /admin/product/district/admin/product/district` - + - 参数变化: `['@RequestParam keywords']` → `[]` + +### ✏️ Family (修改) + +**修改接口:** + +- `GET /admin/product/item/{productId}/admin/product/item/{productId}` - + - 参数变化: `['@PathVariable productId']` → `[]` +- `GET /admin/product/item/{productId}/families` - 获取家庭分组列表 + - 参数变化: `['@PathVariable productId', '@PathVariable productId', '@RequestBody request']` → `['@PathVariable productId']` + +### ✏️ Formula (修改) + +**修改接口:** + +- `GET /admin/product/formula/group/list` - 公式组列表 + - 参数变化: `['@RequestParam productType', '@PathVariable groupId']` → `['@RequestParam productType']` +- `GET /admin/product/formula/group/{groupId}` - 公式组详情 + - 参数变化: `['@PathVariable groupId', '@RequestBody request']` → `['@PathVariable groupId']` +- `POST /admin/product/formula/group` - 创建公式组 + - 参数变化: `['@RequestBody request', '@PathVariable groupId']` → `['@RequestBody request']` +- `PUT /admin/product/formula/group/{groupId}` - 更新公式组 + - 参数变化: `['@PathVariable groupId', '@RequestBody request', '@PathVariable groupId']` → `['@PathVariable groupId', '@RequestBody request']` +- `PUT /admin/product/formula/group/{groupId}/activate` - 激活公式组 + - 参数变化: `['@PathVariable groupId', '@PathVariable groupId']` → `['@PathVariable groupId']` +- `GET /admin/product/formula/step/{formulaId}` - 公式步骤详情 + - 参数变化: `['@PathVariable formulaId', '@RequestBody request']` → `['@PathVariable formulaId']` +- `POST /admin/product/formula/step` - 创建公式步骤 + - 参数变化: `['@RequestBody request', '@PathVariable formulaId', '@RequestBody request']` → `['@RequestBody request', '@PathVariable formulaId']` +- `PUT /admin/product/formula/step/{formulaId}/toggle` - 启用/禁用公式步骤 + - 参数变化: `['@PathVariable formulaId', '@PathVariable formulaId']` → `['@PathVariable formulaId']` +- `DELETE /admin/product/formula/step/{formulaId}` - 删除公式步骤 + - 参数变化: `['@PathVariable formulaId', '@PathVariable formulaId']` → `['@PathVariable formulaId']` +- `GET /admin/product/formula/step/{formulaId}/versions` - 公式步骤版本历史 + - 参数变化: `['@PathVariable formulaId', '@PathVariable formulaId', '@PathVariable versionNum']` → `['@PathVariable formulaId', '@PathVariable formulaId']` +- `GET /admin/product/formula/var/list` - 公式变量列表 + - 参数变化: `['@RequestParam category', '@RequestBody request']` → `['@RequestParam category']` +- `POST /admin/product/formula/var` - 创建公式变量 + - 参数变化: `['@RequestBody request', '@PathVariable varId', '@RequestBody request']` → `['@RequestBody request']` +- `PUT /admin/product/formula/var/{varId}` - 更新公式变量 + - 参数变化: `['@PathVariable varId', '@RequestBody request', '@PathVariable varId']` → `['@PathVariable varId', '@RequestBody request']` + +### ✏️ GroupBatch (修改) + +**修改接口:** + +- `PUT /admin/product/item/{productId}/batch/{batchId}` - 更新批次 + - 参数变化: `['@PathVariable productId', '@PathVariable batchId', '@RequestBody request', '@PathVariable productId', '@PathVariable batchId']` → `['@PathVariable productId', '@PathVariable batchId', '@RequestBody request']` +- `DELETE /admin/product/item/{productId}/batch/{batchId}` - 删除批次 + - 参数变化: `['@PathVariable productId', '@PathVariable batchId', '@PathVariable productId']` → `['@PathVariable productId', '@PathVariable batchId']` +- `GET /admin/product/item/{productId}/batch/list` - 批次列表(树形) + - 参数变化: `['@PathVariable productId', '@PathVariable productId', '@PathVariable batchId']` → `['@PathVariable productId']` +- `PUT /admin/product/item/{productId}/batch/{batchId}/open` - 开启报名(PENDING->ENROLLING) + - 参数变化: `['@PathVariable productId', '@PathVariable batchId', '@PathVariable productId', '@PathVariable batchId']` → `['@PathVariable productId', '@PathVariable batchId']` +- `PUT /admin/product/item/{productId}/batch/{batchId}/close` - 关闭报名(ENROLLING/CONFIRMED->CLOSED) + - 参数变化: `['@PathVariable productId', '@PathVariable batchId', '@PathVariable productId', '@PathVariable batchId']` → `['@PathVariable productId', '@PathVariable batchId']` +- `POST /admin/product/item/{productId}/batch/{batchId}/staff` - 保存服务人员(全量替换) + - 参数变化: `['@PathVariable productId', '@PathVariable batchId', '@RequestBody List', '@PathVariable productId']` → `['@PathVariable productId', '@PathVariable batchId', '@RequestBody List']` +- `GET /admin/product/item/{productId}/batch/{batchId}/staff` - 服务人员列表 + - 参数变化: `['@PathVariable productId', '@PathVariable batchId', '@PathVariable productId', '@PathVariable batchId']` → `['@PathVariable productId', '@PathVariable batchId']` + +### ✏️ InternalMpProduct (修改) + +**修改接口:** + +- `GET /internal/mp/product/list` - 产品列表 + - 参数变化: `['@PathVariable productId']` → `[]` +- `GET /internal/mp/product/{productId}` - 产品详情 + - 参数变化: `['@PathVariable productId', '@PathVariable productId', '@RequestBody request']` → `['@PathVariable productId', '@PathVariable productId']` +- `GET /internal/mp/product/lines` - 产品线列表(活跃) + - 参数变化: `['@RequestParam limit']` → `[]` +- `GET /internal/mp/product/recommend` - 推荐产品列表 + - 参数变化: `['@RequestParam limit', '@PathVariable productId']` → `['@RequestParam limit']` + +### ✏️ InternalProduct (修改) + +**修改接口:** + +- `POST /internal/product/approval-result` - 处理产品审批结果 + - 名称: ~~~~ → **处理产品审批结果** + - 返回类型: `` → `Result` +- `GET /internal/product/{productId}/detail` - 获取产品详情(内部) + - 名称: ~~~~ → **获取产品详情(内部)** +- `POST /internal/product/{productId}/quote` - 报价计算(内部) + - 名称: ~~~~ → **报价计算(内部)** +- `GET /internal/product/{productId}/simple-quote` - 简单报价(内部) + - 名称: ~~~~ → **简单报价(内部)** +- `POST /internal/product/{productId}/deduct-stock` - 扣减库存(内部) + - 名称: ~~~~ → **扣减库存(内部)** +- `POST /internal/product/{productId}/restore-stock` - 恢复库存(内部) + - 名称: ~~~~ → **恢复库存(内部)** +- `GET /internal/product/{productId}/itinerary-resources` - 获取行程关联资源(内部) + - 名称: ~~~~ → **获取行程关联资源(内部)** +- `PUT /internal/product/{productId}/custom-status` - 变更定制产品状态(内部) + - 名称: ~~~~ → **变更定制产品状态(内部)** +- `POST /internal/product/batch/{batchId}/enroll` - 报名入团(内部) + - 名称: ~~~~ → **报名入团(内部)** +- `POST /internal/product/batch/{batchId}/unenroll` - 退出报名(内部) + - 名称: ~~~~ → **退出报名(内部)** +- `GET /internal/product/batch/{batchId}/info` - 批次信息(内部) + - 名称: ~~~~ → **批次信息(内部)** +- `GET /internal/product/{productId}/group-quote` - GROUP产品报价(内部) + - 名称: ~~~~ → **GROUP产品报价(内部)** +- `GET /internal/product/{productId}/batches/calendar` - 团期日历数据(内部) + - 名称: ~~~~ → **团期日历数据(内部)** + - 参数变化: `['@PathVariable productId', '@PathVariable batchId']` → `['@PathVariable productId']` +- `GET /internal/product/batch/{batchId}/combos` - 批次套餐列表(内部) + - 名称: ~~~~ → **批次套餐列表(内部)** +- `GET /internal/product/global-stats` - 获取全局产品统计 + - 参数变化: `['@RequestParam createBy']` → `[]` +- `GET /internal/product/designer-stats` - 获取定制师产品统计 + - 参数变化: `['@RequestParam createBy', '@RequestParam createBy', '@RequestParam page']` → `['@RequestParam createBy']` + +### ✏️ Itinerary (修改) + +**修改接口:** + +- `PUT /admin/product/node/{nodeId}` - 更新行程节点 + - 参数变化: `['@PathVariable nodeId', '@RequestBody request', '@PathVariable nodeId']` → `['@PathVariable nodeId', '@RequestBody request']` +- `DELETE /admin/product/node/{nodeId}` - 删除行程节点 + - 参数变化: `['@PathVariable nodeId', '@PathVariable productId']` → `['@PathVariable nodeId']` +- `POST /admin/product/node/{nodeId}/copy` - 复制行程节点 + - 参数变化: `['@PathVariable nodeId', '@PathVariable nodeId', '@RequestBody request']` → `['@PathVariable nodeId']` +- `PUT /admin/product/hotel/{id}` - 更新每日住宿 + - 参数变化: `['@PathVariable id', '@RequestBody request', '@PathVariable id']` → `['@PathVariable id', '@RequestBody request']` +- `DELETE /admin/product/hotel/{id}` - 删除每日住宿 + - 参数变化: `['@PathVariable id', '@PathVariable productId']` → `['@PathVariable id']` +- `GET /admin/product/item/{productId}/day/{dayNumber}/dining` - 获取某天的餐厅推荐列表 + - 参数变化: `['@PathVariable productId', '@PathVariable dayNumber', '@PathVariable id']` → `['@PathVariable productId', '@PathVariable dayNumber']` +- `PUT /admin/product/supplies/{id}` - 更新物资配品 + - 参数变化: `['@PathVariable id', '@RequestBody request', '@PathVariable id']` → `['@PathVariable id', '@RequestBody request']` +- `PUT /admin/product/staff-config/{id}` - 更新人员配置 + - 参数变化: `['@PathVariable id', '@RequestBody request', '@PathVariable id']` → `['@PathVariable id', '@RequestBody request']` +- `DELETE /admin/product/staff-config/{id}` - 删除人员配置 + - 参数变化: `['@PathVariable id', '@PathVariable productId']` → `['@PathVariable id']` + +### ✏️ MpProduct (修改) + +**修改接口:** + +- `GET /mp/product/list` - 产品列表(C端) + - 名称: ~~产品列表~~ → **产品列表(C端)** + - 参数变化: `['@PathVariable productId']` → `[]` +- `GET /mp/product/{productId}` - 产品详情(C端) + - 名称: ~~产品详情~~ → **产品详情(C端)** + - 参数变化: `['@PathVariable productId', '@PathVariable productId', '@RequestBody request']` → `['@PathVariable productId']` +- `POST /mp/product/{productId}/quote` - 报价计算(C端) + - 名称: ~~报价计算~~ → **报价计算(C端)** + +### ✏️ Pricing (修改) + +**修改接口:** + +- `POST /admin/product/item/{productId}/pricing` - 保存定价规则 + - 参数变化: `['@PathVariable productId', '@RequestBody request', '@PathVariable productId']` → `['@PathVariable productId', '@RequestBody request']` +- `POST /admin/product/item/{productId}/price-calendar/calc-preview` - 测算预览(不写入数据库) + - 参数变化: `['@PathVariable productId', '@RequestBody request', '@PathVariable productId']` → `['@PathVariable productId', '@RequestBody request']` +- `POST /admin/product/item/{productId}/price-calendar/recalculate` - 重新测算所有自动测算日期的价格 + - 参数变化: `['@PathVariable productId', '@PathVariable productId', '@RequestBody request']` → `['@PathVariable productId']` + +### ✏️ Product (修改) + +**修改接口:** + +- `GET /admin/product/item/{productId}` - 获取产品详情 + - 参数变化: `['@PathVariable productId', '@PathVariable productId', '@RequestBody request']` → `['@PathVariable productId']` +- `PUT /admin/product/item/{productId}/status` - 产品状态变更(上架/下架/完成) + - 名称: ~~产品状态变更(上架/下架等)~~ → **产品状态变更(上架/下架/完成)** + +### ✏️ ProductFolder (修改) + +**修改接口:** + +- `GET /admin/product/folder/admin/product/folder` - + - 参数变化: `['@RequestBody request']` → `[]` + +### ✏️ ProductLine (修改) + +**修改接口:** + +- `GET /admin/product/line/admin/product/line` - + - 参数变化: `['@RequestBody request']` → `[]` +- `PUT /admin/product/line/{lineId}` - 更新产品线 + - 参数变化: `['@PathVariable lineId', '@RequestBody request', '@PathVariable lineId']` → `['@PathVariable lineId', '@RequestBody request']` + +### ✏️ Quote (修改) + +**修改接口:** + +- `GET /admin/product/item/{productId}/group-quote` - GROUP产品报价(按套餐组合) + - 名称: ~~GROUP产品报价(按组合)~~ → **GROUP产品报价(按套餐组合)** + +## 任务服务 + +### ✏️ Board (修改) + +**修改接口:** + +- `GET /admin/task/boards` - 获取可见看板列表 +- `GET /admin/task/board/{boardId}` - 看板详情 +- `POST /admin/task/board` - 创建自定义看板 + - 参数变化: `['@RequestBody req', '@PathVariable boardId']` → `['@RequestBody req']` +- `DELETE /admin/task/board/{boardId}` - 删除看板 +- `GET /admin/task/board/{boardId}/statuses` - 获取看板状态列 + - 参数变化: `['@PathVariable boardId', '@PathVariable boardId', '@RequestBody req']` → `['@PathVariable boardId', '@PathVariable boardId']` +- `DELETE /admin/task/status/{statusId}` - 删除状态列 +- `PUT /admin/task/board/{boardId}/status/sort` - 状态列排序 +- `GET /admin/task/board/{boardId}/members` - 获取看板成员 + - 参数变化: `['@PathVariable boardId', '@PathVariable boardId', '@RequestBody req']` → `['@PathVariable boardId', '@PathVariable boardId']` +- `DELETE /admin/task/board/{boardId}/member/{targetAdminId}` - 移除成员 + +### ✏️ Task (修改) + +**修改接口:** + +- `GET /admin/task/board/{boardId}/tasks` - 获取看板任务(按状态分组) +- `GET /admin/task/{taskId}` - 任务详情 +- `PUT /admin/task/{taskId}` - 更新任务 +- `PUT /admin/task/{taskId}/status` - 变更任务状态 +- `PUT /admin/task/{taskId}/sort` - 任务排序 +- `PUT /admin/task/subtask/{subtaskId}/toggle` - 切换子任务完成状态 +- `GET /admin/task/{taskId}/timeline` - 获取任务时间线 +- `POST /admin/task/{taskId}/comment` - 添加评论 +- `DELETE /admin/task/comment/{commentId}` - 删除评论 + +## 企微回调服务 + +### ✏️ WxCallback (修改) + +**修改接口:** + +- `GET /wx/callback/app` - 回调URL验证 + - 名称: ~~Callback URL verification~~ → **回调URL验证** +- `POST /wx/callback/app` - 接收回调事件 + - 名称: ~~Receive callback events~~ → **接收回调事件** +- `GET /wx/callback/contacts` - 联系人同步URL验证 + - 名称: ~~Contact sync URL verification~~ → **联系人同步URL验证** +- `POST /wx/callback/contacts` - 接收联系人同步事件 + - 名称: ~~Receive contact sync events~~ → **接收联系人同步事件** + +## 保险服务 + +### ✏️ AdminInsurance (修改) + +**修改接口:** + +- `POST /admin/insurance/purchase` - 投保下单(每人独立保单) +- `GET /admin/insurance/orders` - 保险订单列表 +- `GET /admin/insurance/orders/{id}` - 保险订单详情(含被保人) + +### ✏️ AdminInsuranceScheme (修改) + +**修改接口:** + +- `GET /admin/insurance/scheme/{id}` - 方案详情 + - 参数变化: `['@PathVariable schemeId', '@RequestBody request']` → `['@PathVariable schemeId']` +- `PUT /admin/insurance/scheme/{id}/toggle-status` - 切换方案状态(启用/停用) + - 参数变化: `['@PathVariable schemeId', '@PathVariable schemeId']` → `['@PathVariable schemeId']` + +### ✏️ InternalInsurance (修改) + +**修改接口:** + +- `POST /internal/insurance/by-orders` - 按订单批量查询保险单(内部调用) + - 参数变化: `['@RequestBody List', '@PathVariable orderId', '@RequestParam travelerCount']` → `['@RequestBody List', '@PathVariable orderId']` + +## 合同服务 + +### ✏️ AdminClauseTemplate (修改) + +**修改接口:** + +- `GET /admin/contract/clause-template/list-all` - 获取全部补充约定模板(管理页用) +- `PUT /admin/contract/clause-template/{id}/toggle-status` - 切换模板启用/停用状态 +- `PUT /admin/contract/clause-template/{id}` - 更新补充约定模板 +- `DELETE /admin/contract/clause-template/{id}` - 删除补充约定模板 + +### ✏️ AdminContract (修改) + +**修改接口:** + +- `GET /admin/contract/agencies` - 可用旅行社列表 +- `GET /admin/contract/templates` - 合同模板列表 +- `POST /admin/contract/create` - 创建合同(标准模式) +- `POST /admin/contract/report` - 报备合同(同步模式) +- `GET /admin/contract/list` - 合同列表 +- `GET /admin/contract/{id}` - 合同详情 +- `GET /admin/contract/{id}/status` - 刷新合同状态(从平台同步) +- `POST /admin/contract/{id}/invalidate` - 作废合同 +- `POST /admin/contract/{id}/resend-sms` - 重发签署短信 +- `POST /admin/contract/{id}/upload-pdf` - 上传已签署PDF(同步模式) + +### ✏️ ContractCallback (修改) + +**修改接口:** + +- `POST /contract/callback/12301` - 12301合同状态回调 + +### ✏️ InternalContract (修改) + +**修改接口:** + +- `GET /internal/contract/by-order/{orderId}` - 按订单查询合同(内部调用) +- `POST /internal/contract/by-orders` - 按订单批量查询合同(内部调用) +- `GET /internal/contract/has-signed/{orderId}` - 检查订单是否有已签署合同(内部调用) +- `POST /internal/contract/invalidate/{orderId}` - 按订单作废所有有效合同(级联调用) + +### ✏️ InternalMpContract (修改) + +**修改接口:** + +- `GET /internal/mp/contract/list` - 用户合同列表 +- `GET /internal/mp/contract/{id}` - 用户合同详情 +- `GET /internal/mp/contract/by-order/{orderId}` - 按订单查合同(返回最新有效合同) +- `GET /internal/mp/contract/by-order/{orderId}/all` - 按订单查所有有效合同(TOUR+INSURANCE各一条) + +## 小程序聚合服务 + +### ✏️ MpContract (修改) + +**修改接口:** + +- `GET /mp/contract/list` - 合同列表 +- `GET /mp/contract/{id}` - 合同详情 +- `GET /mp/contract/by-order/{orderId}` - 按订单查合同 +- `GET /mp/contract/by-order/{orderId}/all` - 按订单查所有合同 + +### ✏️ MpDesigner (修改) + +**修改接口:** + +- `GET /mp/designer/{id}/products` - 定制师已发布产品列表 +- `GET /mp/designer/{id}/reviews` - 定制师产品评价列表 + +### ✏️ MpDict (修改) + +**修改接口:** + +- `GET /dict/all` - 获取所有字典数据 + +### ✏️ MpExplore (修改) + +**修改接口:** + +- `GET /mp/explore/mp/explore` - + - 参数变化: `['@RequestParam sortType']` → `[]` +- `GET /mp/explore/list` - 探索列表 + - 返回类型: `` → `Result>` +- `GET /mp/explore/{id}` - 探索详情 + - 返回类型: `` → `Result>` +- `POST /mp/explore/{id}/view` - 浏览+1 + - 返回类型: `` → `Result` +- `POST /mp/explore/{id}/like` - 切换点赞 + - 返回类型: `` → `Result` +- `POST /mp/explore/{id}/favorite` - 切换收藏 + - 返回类型: `` → `Result` + +### ✏️ MpFavorite (修改) + +**修改接口:** + +- `GET /mp/user/favorite/check` - 检查是否已收藏 + +### ✏️ MpFootprint (修改) + +**修改接口:** + +- `DELETE /mp/user/footprint/{id}` - 删除足迹 + - 参数变化: `['@PathVariable id', '@RequestBody List']` → `['@PathVariable id']` + +### ✏️ MpInsurance (修改) + +**修改接口:** + +- `GET /mp/insurance/policy-pdf/{orderId}` - 获取订单所有保单PDF + +### ✏️ MpInvoice (修改) + +**修改接口:** + +- `GET /mp/invoice/{id}` - 发票详情 +- `GET /mp/invoice/order/{orderId}` - 通过订单ID查询发票 +- `POST /mp/invoice/{invoiceId}/reissue` - 发票换开 + +### ✏️ MpOrder (修改) + +**修改接口:** + +- `GET /mp/order/list` - 订单列表 +- `GET /mp/order/{orderId}` - 订单详情 +- `GET /mp/order/lookup` - 通过联系人手机号+姓名查找订单(无需登录) + - 返回类型: `` → `Result>>` +- `POST /mp/order/{orderId}/approve-unlock` - 同意解锁订单 +- `GET /mp/order/count` - 各状态订单数量 + +### ✏️ MpPayment (修改) + +**修改接口:** + +- `GET /mp/payment/status/{orderId}` - 发起支付 +- `GET /mp/payment/transactions/{orderId}` - 查询支付状态 + - 返回类型: `Result` → `` + +### ✏️ MpProduct (修改) + +**修改接口:** + +- `GET /mp/product/list` - 产品列表 +- `GET /mp/product/{productId}` - 产品详情(聚合收藏状态) +- `GET /mp/product/lines` - 产品线列表 +- `GET /mp/product/{productId}/price-calendar` - 价格日历 + +### ✏️ MpRefund (修改) + +**修改接口:** + +- `GET /mp/order/refund-reasons` - 退款原因列表 +- `GET /mp/order/refund/{applicationId}` - 退款申请详情 +- `GET /mp/order/{orderId}/refund-detail` - 根据订单ID获取最新退款详情 +- `POST /mp/order/refund/{applicationId}/cancel` - 撤回退款申请 + +### ✏️ MpReview (修改) + +**修改接口:** + +- `POST /mp/review/create` - 创建评价 +- `GET /mp/review/my` - 我的评价列表 +- `GET /mp/review/search` - 关键词搜索评价(公开) +- `GET /mp/review/target` - 某目标的已通过评价(公开) +- `GET /mp/review/product/{productId}` - 按产品ID查看评价列表 +- `GET /mp/review/featured` - 精选评价列表(公开) + - 参数变化: `['@RequestParam limit', '@PathVariable orderId']` → `['@RequestParam limit']` +- `GET /mp/review/order/{orderId}/reviewed` - 检查订单是否已评价 + - 参数变化: `['@PathVariable orderId', '@PathVariable orderId']` → `['@PathVariable orderId']` + +### ✏️ MpTraveler (修改) + +**修改接口:** + +- `GET /mp/user/traveler/{id}` - 出行人详情 + - 参数变化: `['@PathVariable id', '@PathVariable id']` → `['@PathVariable id']` +- `PUT /mp/user/traveler/{id}/default` - 设为默认出行人 + +### ✏️ MpTrip (修改) + +**修改接口:** + +- `GET /mp/trip/list` - 行程列表 +- `GET /mp/trip/{orderId}` - 行程详情 +- `GET /mp/trip/today` - 今日行程 + +### ✏️ MpUser (修改) + +**修改接口:** + +- `POST /mp/user/sms/send` - 发送短信验证码 +- `GET /mp/user/profile` - 获取用户信息 +- `PUT /mp/user/profile` - 更新用户信息 + +### ✏️ MpWeather (修改) + +**修改接口:** + +- `GET /mp/weather/itinerary/{orderId}` - 获取订单行程天气 +- `GET /mp/weather/live` - 获取指定城市实况天气 +- `GET /mp/weather/forecast` - 获取指定城市天气预报 + +### ✏️ MpWiki (修改) + +**修改接口:** + +- `GET /mp/wiki/categories` - 攻略分类列表 + - 参数变化: `['@PathVariable categoryId', '@RequestParam page']` → `['@PathVariable categoryId']` +- `GET /mp/wiki/article/{articleId}` - 文章详情 + +## 支付服务 + +### ✏️ AdminPayment (修改) + +**修改接口:** + +- `GET /admin/payment/{transactionId}` - 支付交易列表 +- `GET /admin/payment/order/{orderId}` - 交易详情 + +### ✏️ InternalPayment (修改) + +**修改接口:** + +- `GET /internal/payment/status/{orderId}` - 创建预支付订单 + - 名称: ~~Create prepay order (called by BFF)~~ → **创建预支付订单** +- `GET /internal/payment/transactions/{orderId}` - 查询支付状态 + - 名称: ~~Query payment status (called by BFF)~~ → **查询支付状态** +- `POST /internal/payment/refund` - 订单交易记录列表 + - 名称: ~~List all transactions for an order (called by BFF)~~ → **订单交易记录列表** + +### ✏️ PaymentCallback (修改) + +**修改接口:** + +- `POST /pay/callback/refund-notify/{mchId}` - 支付成功回调 + +## 攻略服务 + +### ✏️ AdminGuideArticle (修改) + +**修改接口:** + +- `GET /admin/guide/article/list` - 文章列表 +- `GET /admin/guide/article/{articleId}` - 文章详情 +- `PUT /admin/guide/article/{articleId}` - 更新文章 + - 参数变化: `['@PathVariable articleId', '@RequestBody request', '@PathVariable articleId']` → `['@PathVariable articleId', '@RequestBody request']` +- `PUT /admin/guide/article/{articleId}/status` - 发布/下架 +- `PUT /admin/guide/article/{articleId}/recommend` - 设置推荐 +- `PUT /admin/guide/article/{articleId}/top` - 设置置顶 + +### ✏️ AdminGuideCategory (修改) + +**修改接口:** + +- `GET /admin/guide/category/list` - 分类列表 +- `GET /admin/guide/category/enabled` - 启用的分类列表 +- `DELETE /admin/guide/category/{categoryId}` - 删除分类 +- `PUT /admin/guide/category/{categoryId}/status` - 更新分类状态 + +### ✏️ AdminGuideTag (修改) + +**修改接口:** + +- `GET /admin/guide/tag/managed` - 系统标签列表 +- `GET /admin/guide/tag/all` - 所有标签列表 +- `PUT /admin/guide/tag/{tagId}` - 更新标签 + - 参数变化: `['@PathVariable tagId', '@RequestBody request', '@PathVariable tagId']` → `['@PathVariable tagId', '@RequestBody request']` +- `PUT /admin/guide/tag/article/{articleId}` - 更新文章标签 + +### ✏️ InternalWiki (修改) + +**修改接口:** + +- `GET /internal/wiki/category/{categoryId}/articles` - 分页查询指定分类下的已发布文章 +- `GET /internal/wiki/article/{articleId}` - 查询已发布文章详情 + +## 文件服务 + +### ✏️ File (修改) + +**修改接口:** + +- `POST /admin/file/upload/token` - 请求上传凭证 +- `POST /admin/file/upload/confirm` - 确认上传完成 +- `GET /admin/file/list` - 文件列表(分页) +- `GET /admin/file/{fileId}` - 文件详情 +- `DELETE /admin/file/{fileId}` - 删除文件 +- `GET /admin/file/{fileId}/refs` - 文件引用列表 +- `GET /admin/file/stats` - 存储统计 +- `GET /admin/file/{fileId}/preview` - 文件内容流式预览 + +### ✏️ InternalFile (修改) + +**修改接口:** + +- `POST /internal/file/bindRefs` - 绑定文件到业务实体 +- `POST /internal/file/unbindRefs` - 解绑业务实体的所有文件 +- `POST /internal/file/byIds` - 批量获取文件信息 + - 参数变化: `['@RequestBody request', '@RequestBody request']` → `['@RequestBody request']` +- `POST /internal/file/upload/direct` - 内部直接上传文件(服务间调用) +- `POST /internal/file/upload/chunk/init` - 分片上传-初始化 +- `POST /internal/file/upload/chunk` - 分片上传-上传分片 +- `POST /internal/file/upload/chunk/complete` - 分片上传-完成合并 +- `POST /internal/file/upload/chunk/cancel` - 分片上传-取消 + +### ✏️ MpFile (修改) + +**修改接口:** + +- `POST /mp/file/upload` - 上传文件(C端用户) + +## 用户服务 + +### ✏️ AdminAgreement (修改) + +**修改接口:** + +- `GET /admin/agreement/admin/agreement` - + - 参数变化: `['@RequestParam page']` → `[]` +- `GET /admin/agreement/{id}` - 协议详情 + - 参数变化: `['@PathVariable id', '@RequestBody request']` → `['@PathVariable id']` +- `PUT /admin/agreement/{id}` - 编辑协议 + - 参数变化: `['@PathVariable id', '@RequestBody request', '@PathVariable id']` → `['@PathVariable id', '@RequestBody request']` + +### ✏️ AdminBanner (修改) + +**修改接口:** + +- `GET /admin/banner/admin/banner` - + - 参数变化: `['@RequestParam page']` → `[]` +- `GET /admin/banner/{id}` - Banner详情 + - 参数变化: `['@PathVariable id', '@RequestBody request']` → `['@PathVariable id']` +- `PUT /admin/banner/{id}` - 更新Banner + - 参数变化: `['@PathVariable id', '@RequestBody request', '@PathVariable id']` → `['@PathVariable id', '@RequestBody request']` + +### ✏️ AdminContact (修改) + +**修改接口:** + +- `GET /admin/contact/admin/contact` - + - 参数变化: `['@RequestParam page']` → `[]` +- `GET /admin/contact/{id}` - 联系方式详情 + - 参数变化: `['@PathVariable id', '@RequestBody request']` → `['@PathVariable id']` +- `PUT /admin/contact/{id}` - 更新联系方式 + - 参数变化: `['@PathVariable id', '@RequestBody request', '@PathVariable id']` → `['@PathVariable id', '@RequestBody request']` + +### ✏️ AdminCustomer (修改) + +**修改接口:** + +- `GET /admin/customer/admin/customer` - + - 参数变化: `['@RequestParam page']` → `[]` +- `GET /admin/customer/{userId}` - 客户详情 + - 参数变化: `['@PathVariable userId', '@PathVariable userId']` → `['@PathVariable userId']` +- `POST /admin/customer/{userId}/ban` - 封禁客户 + - 参数变化: `['@PathVariable userId', '@PathVariable userId']` → `['@PathVariable userId']` +- `POST /admin/customer/{userId}/unban` - 解封客户 + +### ✏️ AdminDesigner (修改) + +**修改接口:** + +- `GET /admin/designer/profile` - 获取我的个人资料(已废弃,请使用 /admin/profile/me) + - 参数变化: `['@RequestBody body']` → `[]` +- `GET /admin/designer/orders` - 我的订单列表(已废弃,请使用 /admin/profile/orders) +- `GET /admin/designer/products` - 我的产品列表(已废弃,请使用 /admin/profile/products) + +### ✏️ AdminExploreCategory (修改) + +**修改接口:** + +- `GET /admin/explore/category/admin/explore/category` - + - 参数变化: `['@RequestParam page']` → `[]` +- `GET /admin/explore/category/{id}` - 探索分类详情 + - 参数变化: `['@PathVariable id', '@RequestBody request']` → `['@PathVariable id']` + +### ✏️ AdminFaq (修改) + +**修改接口:** + +- `GET /admin/faq/categories` - 分类列表 + - 参数变化: `['@RequestBody request']` → `[]` +- `POST /admin/faq/categories` - 创建分类 + - 参数变化: `['@RequestBody request', '@PathVariable id', '@RequestBody request']` → `['@RequestBody request']` +- `PUT /admin/faq/categories/{id}` - 更新分类 + - 参数变化: `['@PathVariable id', '@RequestBody request', '@PathVariable id']` → `['@PathVariable id', '@RequestBody request']` +- `GET /admin/faq/items` - 条目列表 + - 参数变化: `['@RequestParam categoryId', '@RequestBody request']` → `['@RequestParam categoryId']` +- `POST /admin/faq/items` - 创建条目 + - 参数变化: `['@RequestBody request', '@PathVariable id', '@RequestBody request']` → `['@RequestBody request']` +- `PUT /admin/faq/items/{id}` - 更新条目 + - 参数变化: `['@PathVariable id', '@RequestBody request', '@PathVariable id']` → `['@PathVariable id', '@RequestBody request']` + +### ✏️ AdminFrontendConfig (修改) + +**修改接口:** + +- `GET /admin/frontend-config/admin/frontend-config` - + - 参数变化: `['@RequestParam page']` → `[]` +- `GET /admin/frontend-config/all` - 配置列表(不分页) + - 参数变化: `['@RequestParam configGroup', '@RequestParam status', '@PathVariable id']` → `['@RequestParam configGroup', '@RequestParam status']` +- `GET /admin/frontend-config/{id}` - 配置详情 + - 参数变化: `['@PathVariable id', '@PathVariable key']` → `['@PathVariable id']` +- `GET /admin/frontend-config/groups` - 获取所有分组 + - 参数变化: `['@RequestBody request']` → `[]` + +### ✏️ AdminProfile (修改) + +**修改接口:** + +- `GET /admin/profile/dashboard` - 工作台仪表盘(角色分发,支持时间范围) + - 返回类型: `` → `Result` +- `GET /admin/profile/reviews` - 我的评价列表 +- `GET /admin/profile/orders` - 订单列表 +- `GET /admin/profile/products` - 产品列表 + +### ✏️ AdminTopic (修改) + +**修改接口:** + +- `GET /admin/topic/admin/topic` - + - 参数变化: `['@RequestParam page']` → `[]` +- `GET /admin/topic/{id}` - 专题详情 + - 参数变化: `['@PathVariable id', '@RequestBody request']` → `['@PathVariable id']` +- `PUT /admin/topic/{id}` - 更新专题 + - 参数变化: `['@PathVariable id', '@RequestBody request', '@PathVariable id']` → `['@PathVariable id', '@RequestBody request']` + +### ✏️ AdminUser (修改) + +**修改接口:** + +- `GET /admin/user/admin/user` - + - 参数变化: `['@RequestBody request']` → `[]` +- `PUT /admin/user/{adminId}` - 更新管理员 +- `DELETE /admin/user/{adminId}` - 删除管理员 +- `POST /admin/user/{adminId}/unlock` - 解锁管理员 +- `POST /admin/user/{adminId}/reset-password` - 重置密码 +- `PUT /admin/user/{adminId}/wechat-binding` - 修改企业微信绑定(支持换绑) +- `GET /admin/user/{adminId}` - 获取管理员详情 + - 参数变化: `['@PathVariable adminId', '@RequestParam page']` → `['@PathVariable adminId']` + +### ✏️ Auth (修改) + +**修改接口:** + +- `POST /admin/auth/login` - 管理员登录 +- `POST /admin/auth/wechat/verify-2fa` - 2FA验证 +- `PUT /admin/auth/password` - 修改密码 +- `POST /admin/auth/logout` - 管理员登出 + - 参数变化: `['@RequestParam adminId']` → `[]` +- `GET /admin/auth/2fa/qrcode` - 生成2FA扫码会话 + - 参数变化: `['@RequestParam adminId', '@RequestParam code', '@RequestParam state']` → `['@RequestParam adminId']` +- `GET /admin/auth/2fa/callback` - 2FA企微扫码回调 +- `GET /admin/auth/wechat-qr` - 生成企业微信扫码登录会话 + - 参数变化: `['@RequestParam code', '@RequestParam state']` → `[]` +- `GET /admin/auth/wechat-qr/callback` - 企业微信扫码登录回调 +- `GET /admin/auth/wechat-qr/status` - 查询企业微信扫码登录状态 +- `GET /admin/auth/2fa/check` - 查询2FA扫码状态 +- `POST /admin/auth/switch-role` - 切换当前角色 +- `PUT /admin/auth/avatar` - 更新头像 +- `GET /admin/auth/info` - 获取当前管理员信息 + +### ✏️ Favorite (修改) + +**修改接口:** + +- `GET /user/favorite/user/favorite` - + - 参数变化: `['@RequestBody favoriteRequest']` → `[]` +- `DELETE /user/favorite/{favoriteId}` - 删除收藏 + +### ✏️ Footprint (修改) + +**修改接口:** + +- `GET /user/footprint/user/footprint` - + - 参数变化: `['@RequestBody footprintRequest']` → `[]` +- `DELETE /user/footprint/{footprintId}` - 删除足迹 + +### ✏️ InternalApproval (修改) + +**修改接口:** + +- `POST /internal/wechat/submit-approval` - 提交企业微信OA审批 + - 名称: ~~Submit approval to enterprise WeChat OA~~ → **提交企业微信OA审批** +- `POST /internal/wechat/revoke-approval/{spNo}` - 撤销企业微信OA审批 + - 名称: ~~Revoke a pending approval in enterprise WeChat OA~~ → **撤销企业微信OA审批** +- `GET /internal/wechat/approval-status/{spNo}` - 查询企业微信OA审批状态 + - 名称: ~~Get approval status from enterprise WeChat OA~~ → **查询企业微信OA审批状态** + +### ✏️ InternalBadge (修改) + +**修改接口:** + +- `GET /internal/mp/badge/internal/mp/badge` - + - 参数变化: `['@RequestParam userId']` → `[]` + +### ✏️ InternalContact (修改) + +**修改接口:** + +- `GET /internal/mp/contact/active` - 获取当前有效联系方式列表 + +### ✏️ InternalDesigner (修改) + +**修改接口:** + +- `GET /internal/mp/designer/internal/mp/designer` - + - 参数变化: `['@RequestParam page', '@RequestParam limit']` → `[]` + +### ✏️ InternalExploreCategory (修改) + +**修改接口:** + +- `GET /internal/mp/explore/active` - 获取上线探索分类列表 +- `POST /internal/mp/explore/{id}/view` - 增加浏览量 + - 参数变化: `['@PathVariable id', '@PathVariable id']` → `['@PathVariable id']` + +### ✏️ InternalLike (修改) + +**修改接口:** + +- `GET /internal/like/internal/like` - + - 参数变化: `['@RequestParam targetType']` → `[]` +- `POST /internal/like/toggle` - 切换点赞状态(通用) +- `GET /internal/like/check` - 检查是否已点赞(通用) +- `POST /internal/like/batch-check` - 批量检查是否已点赞(接受字符串ID,避免JS大数精度丢失) + +### ✏️ InternalLoginLog (修改) + +**修改接口:** + +- `GET /internal/login-logs` - 查询登录日志 + - 名称: ~~Query login logs~~ → **查询登录日志** + +### ✏️ InternalMpCommon (修改) + +**修改接口:** + +- `GET /internal/mp/common/faq` - FAQ列表 + - 参数变化: `['@RequestParam userId', '@RequestBody feedback']` → `[]` +- `POST /internal/mp/common/feedback` - 提交反馈 + - 参数变化: `['@RequestParam userId', '@RequestBody feedback', '@PathVariable type']` → `['@RequestParam userId', '@RequestBody feedback']` + +### ✏️ InternalMpDict (修改) + +**修改接口:** + +- `GET /internal/mp/dict/all` - 获取所有字典数据(C端小程序) +- `GET /internal/mp/dict/type/{dictType}` - 按字典类型获取字典数据列表 + +### ✏️ InternalMpMessage (修改) + +**修改接口:** + +- `GET /internal/mp/message/internal/mp/message` - + - 参数变化: `['@RequestParam userId']` → `[]` +- `GET /internal/mp/message/categories` - 消息分类列表(含未读数和最新消息预览) +- `GET /internal/mp/message/summary` - 消息摘要(兼容旧接口) + - 参数变化: `['@RequestParam userId', '@RequestParam userId', '@RequestParam categoryCode']` → `['@RequestParam userId']` +- `GET /internal/mp/message/list` - 分类内消息列表(进入后自动标记已读) +- `GET /internal/mp/message/unread-count` - 获取总未读数 +- `PUT /internal/mp/message/read-all` - 全部标记已读 + +### ✏️ InternalMpUser (修改) + +**修改接口:** + +- `POST /internal/mp/user/sms/send` - 发送短信验证码 + - 参数变化: `['@RequestBody request', '@RequestBody request']` → `['@RequestBody request']` +- `POST /internal/mp/user/login/sms` - 短信登录 + - 参数变化: `['@RequestBody request', '@RequestBody request']` → `['@RequestBody request']` +- `POST /internal/mp/user/login` - 微信登录 + - 参数变化: `['@RequestBody request', '@RequestParam userId']` → `['@RequestBody request']` +- `GET /internal/mp/user/profile` - 获取用户信息 +- `PUT /internal/mp/user/profile` - 更新用户信息 + - 参数变化: `['@RequestParam userId', '@RequestBody request', '@RequestParam userId']` → `['@RequestParam userId', '@RequestBody request']` +- `POST /internal/mp/user/logout` - 用户登出 + - 参数变化: `['@RequestParam userId', '@RequestParam userId']` → `['@RequestParam userId']` +- `POST /internal/mp/user/favorite` - 添加收藏 + - 参数变化: `['@RequestParam userId', '@RequestBody request', '@RequestParam userId', '@RequestParam targetType']` → `['@RequestParam userId', '@RequestBody request']` +- `GET /internal/mp/user/favorite` - 收藏列表 +- `GET /internal/mp/user/favorite/check` - 检查是否已收藏 + - 参数变化: `['@RequestParam userId', '@RequestParam targetType', '@RequestParam targetId', '@RequestParam userId']` → `['@RequestParam userId', '@RequestParam targetType', '@RequestParam targetId']` +- `DELETE /internal/mp/user/favorite/batch` - 批量删除收藏 + - 参数变化: `['@RequestParam userId', '@RequestBody List', '@RequestParam userId']` → `['@RequestParam userId', '@RequestBody List']` +- `DELETE /internal/mp/user/favorite/by-target` - 按目标取消收藏 +- `POST /internal/mp/user/footprint` - 记录足迹 + - 参数变化: `['@RequestParam userId', '@RequestBody request', '@RequestParam userId', '@RequestParam resourceType']` → `['@RequestParam userId', '@RequestBody request']` +- `GET /internal/mp/user/footprint` - 足迹列表 +- `DELETE /internal/mp/user/footprint/batch` - 批量删除足迹 + - 参数变化: `['@RequestParam userId', '@RequestBody List', '@RequestParam userId', '@PathVariable id']` → `['@RequestParam userId', '@RequestBody List']` +- `POST /internal/mp/user/traveler` - 添加出行人 + - 参数变化: `['@RequestParam userId', '@RequestBody request', '@RequestParam userId']` → `['@RequestParam userId', '@RequestBody request']` +- `GET /internal/mp/user/traveler` - 出行人列表 + - 参数变化: `['@RequestParam userId', '@RequestParam userId', '@PathVariable id']` → `['@RequestParam userId']` +- `GET /internal/mp/user/traveler/{id}` - 出行人详情 + - 参数变化: `['@RequestParam userId', '@PathVariable id', '@RequestParam userId', '@PathVariable id', '@RequestBody request']` → `['@RequestParam userId', '@PathVariable id']` +- `PUT /internal/mp/user/traveler/{id}` - 更新出行人 + - 参数变化: `['@RequestParam userId', '@PathVariable id', '@RequestBody request', '@RequestParam userId', '@PathVariable id']` → `['@RequestParam userId', '@PathVariable id', '@RequestBody request']` +- `DELETE /internal/mp/user/traveler/{id}` - 删除出行人 + - 参数变化: `['@RequestParam userId', '@PathVariable id', '@RequestParam userId', '@PathVariable id']` → `['@RequestParam userId', '@PathVariable id']` + +### ✏️ InternalOrderUser (修改) + +**修改接口:** + +- `GET /internal/order/user/internal/order/user` - + - 参数变化: `['@RequestParam userId']` → `[]` + +### ✏️ InternalUser (修改) + +**修改接口:** + +- `GET /internal/user/admin/info/{adminId}` - 根据ID获取管理员基本信息 + - 名称: ~~Get admin basic info by ID~~ → **根据ID获取管理员基本信息** +- `POST /internal/user/admin/batch-info` - 批量获取管理员基本信息 + - 名称: ~~Batch get admin basic info~~ → **批量获取管理员基本信息** +- `GET /internal/user/departments` - 获取所有部门列表 + - 名称: ~~Get all departments~~ → **获取所有部门列表** +- `GET /internal/user/admin/dept-members/{deptId}` - 获取部门下的管理员ID列表 + - 名称: ~~Get admin IDs belonging to a department~~ → **获取部门下的管理员ID列表** +- `GET /internal/user/admin/by-role-key` - 根据角色标识获取管理员列表 + - 名称: ~~Get admins by role key~~ → **根据角色标识获取管理员列表** +- `GET /internal/user/find-by-phone` - 根据手机号查找C端用户ID + - 名称: ~~Find C-end user ID by phone number~~ → **根据手机号查找C端用户ID** +- `POST /internal/user/wechat/miniapp/generate-url-link` - 生成小程序URL Link + - 名称: ~~Generate mini program URL Link for sharing~~ → **生成小程序URL Link** + - 参数变化: `['@RequestParam path', '@RequestParam query', '@RequestBody dto']` → `['@RequestParam path', '@RequestParam query']` +- `POST /internal/user/wechat/send-message` - 发送企业微信消息 + - 名称: ~~Send WeChat message to users~~ → **发送企业微信消息** + +### ✏️ InternalWechat (修改) + +**修改接口:** + +- `GET /internal/wechat/internal/wechat` - + - 参数变化: `['@RequestBody dto']` → `[]` +- `POST /internal/wechat/user/sync` - 同步单个企微用户(回调触发) + - 名称: ~~Sync single user from callback~~ → **同步单个企微用户(回调触发)** + - 返回类型: `` → `Result` +- `DELETE /internal/wechat/user/{userid}` - 删除单个企微用户(回调触发) + - 名称: ~~Delete single user from callback~~ → **删除单个企微用户(回调触发)** + - 返回类型: `` → `Result` +- `POST /internal/wechat/department/sync` - 同步单个企微部门(回调触发) + - 名称: ~~Sync single department from callback~~ → **同步单个企微部门(回调触发)** + - 返回类型: `` → `Result` +- `POST /internal/wechat/external-contact/event` - 接收外部联系人变更事件 + - 名称: ~~Receive external contact change event~~ → **接收外部联系人变更事件** + - 返回类型: `` → `Result` +- `DELETE /internal/wechat/department/{deptId}` - 删除单个企微部门(回调触发) + - 名称: ~~Delete single department from callback~~ → **删除单个企微部门(回调触发)** + - 返回类型: `` → `Result` + +### ✏️ InternalWish (修改) + +**修改接口:** + +- `GET /internal/mp/wish/internal/mp/wish` - + - 参数变化: `['@RequestParam userId']` → `[]` + +### ✏️ PublicDict (修改) + +**修改接口:** + +- `GET /dict/all` - 获取所有字典数据(公开接口) + - 名称: ~~获取所有字典数据~~ → **获取所有字典数据(公开接口)** + +### ✏️ SysDict (修改) + +**修改接口:** + +- `GET /admin/dict/all` - 获取所有字典数据 +- `POST /admin/dict/type` - 创建字典类型 +- `PUT /admin/dict/type/{id}` - 更新字典类型 + - 参数变化: `['@PathVariable id', '@RequestBody request', '@PathVariable id']` → `['@PathVariable id', '@RequestBody request']` +- `DELETE /admin/dict/type/{id}` - 删除字典类型 + - 参数变化: `['@PathVariable id', '@RequestParam page']` → `['@PathVariable id']` +- `GET /admin/dict/type` - 分页查询字典类型 +- `GET /admin/dict/type/{dictTypeId}` - 根据ID获取字典类型详情 +- `POST /admin/dict/data` - 创建字典数据 +- `PUT /admin/dict/data/{id}` - 更新字典数据 +- `DELETE /admin/dict/data/{id}` - 删除字典数据 +- `GET /admin/dict/data/detail/{dictDataId}` - 根据ID获取字典数据详情 +- `GET /admin/dict/data/tree/{dictTypeId}` - 按类型查询字典数据(树形结构) +- `GET /admin/dict/data/{dictType}` - 按类型查询字典数据 + +### ✏️ SysJob (修改) + +**修改接口:** + +- `GET /admin/job/admin/job` - + - 参数变化: `['@RequestBody request']` → `[]` +- `PUT /admin/job/{jobId}` - 更新定时任务 + - 返回类型: `Result` → `Result` + - 参数变化: `['@PathVariable jobId', '@RequestBody request', '@PathVariable jobId']` → `['@PathVariable jobId', '@RequestBody request']` +- `DELETE /admin/job/{jobId}` - 删除定时任务 + - 参数变化: `['@PathVariable jobId', '@RequestParam page']` → `['@PathVariable jobId']` +- `POST /admin/job/{jobId}/pause` - 暂停任务 + - 参数变化: `['@PathVariable jobId', '@PathVariable jobId']` → `['@PathVariable jobId']` +- `POST /admin/job/{jobId}/resume` - 恢复任务 + - 参数变化: `['@PathVariable jobId', '@PathVariable jobId']` → `['@PathVariable jobId']` +- `POST /admin/job/{jobId}/trigger` - 立即执行一次 + - 参数变化: `['@PathVariable jobId', '@PathVariable jobId']` → `['@PathVariable jobId']` +- `GET /admin/job/{jobId}/logs` - 查询任务日志 + - 返回类型: `Result>` → `Result>` + +### ✏️ SysMenu (修改) + +**修改接口:** + +- `GET /admin/menu/admin/menu` - + - 参数变化: `['@RequestBody request']` → `[]` +- `PUT /admin/menu/{menuId}` - 更新菜单 + - 参数变化: `['@PathVariable menuId', '@RequestBody request', '@PathVariable menuId']` → `['@PathVariable menuId', '@RequestBody request']` +- `DELETE /admin/menu/{menuId}` - 删除菜单 + - 参数变化: `['@PathVariable menuId', '@PathVariable menuId']` → `['@PathVariable menuId']` +- `GET /admin/menu/tree` - 获取完整菜单树 + - 参数变化: `['@PathVariable roleId']` → `[]` +- `GET /admin/menu/my` - 获取当前管理员菜单 + +### ✏️ SysRole (修改) + +**修改接口:** + +- `GET /admin/role/admin/role` - + - 参数变化: `['@RequestBody request']` → `[]` +- `PUT /admin/role/{roleId}` - 更新角色 + - 参数变化: `['@PathVariable roleId', '@RequestBody request', '@PathVariable roleId']` → `['@PathVariable roleId', '@RequestBody request']` +- `DELETE /admin/role/{roleId}` - 删除角色 + - 参数变化: `['@PathVariable roleId', '@PathVariable roleId']` → `['@PathVariable roleId']` +- `GET /admin/role/{roleId}` - 获取角色详情(含菜单ID) + - 参数变化: `['@PathVariable roleId', '@RequestParam page', '@RequestParam pageSize']` → `['@PathVariable roleId']` +- `GET /admin/role/all` - 获取所有角色(下拉) + - 参数变化: `['@PathVariable roleId', '@RequestBody request']` → `[]` +- `PUT /admin/role/{roleId}/menus` - 分配菜单权限 + +### ✏️ Traveler (修改) + +**修改接口:** + +- `GET /user/traveler/user/traveler` - + - 参数变化: `['@RequestBody travelerRequest']` → `[]` +- `GET /user/traveler/{travelerId}` - 出行人详情 +- `PUT /user/traveler/{travelerId}` - 更新出行人 +- `PUT /user/traveler/{travelerId}/default` - 设为默认出行人 + +### ✏️ User (修改) + +**修改接口:** + +- `POST /user/sms/send` - 发送短信验证码 + - 参数变化: `['@RequestBody request', '@RequestBody request']` → `['@RequestBody request']` +- `POST /user/login/sms` - 手机号验证码登录 + - 参数变化: `['@RequestBody request', '@RequestBody request']` → `['@RequestBody request']` +- `POST /user/login` - 微信登录 +- `GET /user/profile` - 获取用户信息 +- `PUT /user/profile` - 更新用户信息 +- `POST /user/logout` - 用户登出 +- `DELETE /user/account` - 注销账号 +- `GET /user/favorite/check` - 检查是否已收藏 + +### ✏️ WechatSync (修改) + +**修改接口:** + +- `POST /admin/wechat/sync/departments` - 手动同步部门 +- `POST /admin/wechat/sync/users` - 手动同步用户 +- `POST /admin/wechat/sync/all` - 手动同步全部(部门+用户) + - 参数变化: `['@RequestParam page']` → `[]` +- `GET /admin/wechat/users` - 查询企业微信用户(分页+搜索) +- `GET /admin/wechat/departments/tree` - 部门树(下拉筛选) + +### ✏️ AdminNotification (修改) + +**修改接口:** + +- `GET /admin/notification/config` - 获取通知配置列表(按分类分组) +- `PUT /admin/notification/config/{id}/toggle` - 切换通道开关 + - 参数变化: `['@PathVariable id', '@RequestBody request', '@PathVariable id']` → `['@PathVariable id', '@RequestBody request']` +- `GET /admin/notification/logs` - 查询发送日志 +- `GET /admin/notification/logs/stats` - 获取发送统计 + - 参数变化: `['@RequestBody request']` → `[]` + +## 监控服务 + +### ✏️ ApprovalLog (修改) + +**修改接口:** + +- `GET /admin/monitor/approval-logs/{id}` - 审批日志详情 + +### ✏️ DataRetention (修改) + +**修改接口:** + +- `POST /admin/monitor/data-retention/cleanup` - 手动触发数据清理 + +### ✏️ ErrorLog (修改) + +**修改接口:** + +- `GET /admin/monitor/error-logs/{id}` - 错误日志详情 + +### ✏️ InternalLog (修改) + +**修改接口:** + +- `POST /internal/monitor/operation-log` - 接收操作日志 + - 名称: ~~Receive operation log~~ → **接收操作日志** + - 返回类型: `` → `Result` +- `POST /internal/monitor/error-log` - 接收错误日志 + - 名称: ~~Receive error log~~ → **接收错误日志** + - 返回类型: `` → `Result` +- `POST /internal/monitor/notification-log` - 接收通知日志 + - 名称: ~~Receive notification log~~ → **接收通知日志** + - 返回类型: `` → `Result` +- `POST /internal/monitor/approval-log` - 接收审批日志 + - 名称: ~~Receive approval log~~ → **接收审批日志** + - 返回类型: `` → `Result` +- `GET /internal/monitor/notification-log/customer-stats` - 获取用户客户统计 + - 名称: ~~Get customer stats for a user (add/loss counts)~~ → **获取用户客户统计** + +### ✏️ MysqlMonitor (修改) + +**修改接口:** + +- `GET /admin/monitor/mysql/tables` - 表空间列表 +- `GET /admin/monitor/mysql/slow-queries` - 慢SQL查询统计 + +### ✏️ NotificationLog (修改) + +**修改接口:** + +- `GET /admin/monitor/notification-logs/{id}` - 消息通知日志详情 + +### ✏️ OperationLog (修改) + +**修改接口:** + +- `GET /admin/monitor/operation-logs/{id}` - 操作日志详情 + +### ✏️ RocketMqMonitor (修改) + +**修改接口:** + +- `GET /admin/monitor/rocketmq/topics` - Topic统计 +- `GET /admin/monitor/rocketmq/consumer-groups` - 消费者组统计 + +## 素材服务 + +### ✏️ InternalMaterial (修改) + +**修改接口:** + +- `POST /internal/material/ref/bind` - 绑定引用 +- `POST /internal/material/ref/batch-bind` - 批量绑定引用 +- `DELETE /internal/material/ref/unbind` - 解绑引用 +- `DELETE /internal/material/ref/batch-unbind` - 批量解绑引用 + +### ✏️ MaterialCategoryPermission (修改) + +**修改接口:** + +- `GET /admin/material/category/permissions/{roleCode}` - 获取角色的分类权限 +- `PUT /admin/material/category/permissions/{roleCode}` - 更新角色的分类权限 + +### ✏️ Material (修改) + +**修改接口:** + +- `POST /admin/material/upload/token` - 获取上传凭证 +- `POST /admin/material/upload/confirm` - 确认上传完成 +- `POST /admin/material/upload/folder` - 文件夹上传初始化(创建分类+批量获取凭证) +- `GET /admin/material/list` - 素材列表 +- `PUT /admin/material/{materialId}` - 更新素材信息 +- `DELETE /admin/material/{materialId}` - 删除素材 +- `DELETE /admin/material/batch` - 批量删除素材 +- `PUT /admin/material/{materialId}/tags` - 更新素材标签 +- `PUT /admin/material/batch/tags` - 批量更新标签 +- `GET /admin/material/{materialId}/refs` - 查看素材引用记录 +- `GET /admin/material/categories` - 获取有权限的分类列表(含素材数量) +- `POST /admin/material/category/sub` - 创建子分类 +- `DELETE /admin/material/category/sub/{categoryId}` - 删除子分类 + +### ✏️ MaterialTag (修改) + +**修改接口:** + +- `PUT /admin/material/tag/{tagId}` - 编辑标签 + - 参数变化: `['@PathVariable tagId', '@RequestBody request', '@PathVariable tagId']` → `['@PathVariable tagId', '@RequestBody request']` + +### ✏️ MpMaterial (修改) + +**修改接口:** + +- `GET /mp/material/miniprogram` - 获取小程序分类下的全部素材 + +## 订单服务 + +### ✏️ AdminAlbum (修改) + +**修改接口:** + +- `POST /admin/order/{orderId}/album/folder` - 创建相册文件夹 +- `PUT /admin/order/album/folder/{folderId}` - 编辑相册文件夹 +- `DELETE /admin/order/album/folder/{folderId}` - 删除相册文件夹 +- `POST /admin/order/album/folder/{folderId}/files` - 批量添加文件到文件夹 +- `PUT /admin/order/album/file/{albumFileId}` - 编辑文件信息 +- `GET /admin/order/album/folder/{folderId}/files` - 查询文件夹下的文件列表 +- `GET /admin/order/album/my-uploads` - 我的上传 + - 名称: ~~我的上传(当前管理员上传的所有相册文件)~~ → **我的上传** + +### ✏️ AdminEarlyBird (修改) + +**修改接口:** + +- `GET /admin/order/early-bird/list` - 早鸟优惠计划列表 +- `GET /admin/order/early-bird/{planId}` - 早鸟优惠计划详情 +- `PUT /admin/order/early-bird/{planId}` - 修改早鸟优惠计划 +- `DELETE /admin/order/early-bird/{planId}` - 删除早鸟优惠计划 +- `PUT /admin/order/early-bird/{planId}/toggle` - 启用/禁用早鸟优惠计划 + +### ✏️ AdminOrderConfig (修改) + +**修改接口:** + +- `GET /admin/order/config/expiry-minutes` - 获取订单过期配置 +- `PUT /admin/order/config/expiry-minutes` - 设置订单过期时间(分钟) + +### ✏️ AdminOrder (修改) + +**修改接口:** + +- `POST /admin/order/quote` - 报价预览 +- `GET /admin/order/list` - 订单列表 + - 参数变化: `['@PathVariable orderId']` → `[]` +- `GET /admin/order/{orderId}` - 订单详情 +- `POST /admin/order/{orderId}/remark` - 添加备注 +- `PUT /admin/order/{orderId}/deposit` - 修改定金金额 +- `PUT /admin/order/{orderId}` - 编辑订单 +- `POST /admin/order/{orderId}/discount` - 添加优惠项 +- `PUT /admin/order/{orderId}/discount/{discountId}` - 修改优惠项 +- `DELETE /admin/order/{orderId}/discount/{discountId}` - 删除优惠项 +- `POST /admin/order/{orderId}/vehicle-info/check-diff` - 检测车型一致性 + - 参数变化: `['@PathVariable orderId', '@RequestBody vehicleInfoJson', '@PathVariable orderId']` → `['@PathVariable orderId', '@RequestBody vehicleInfoJson']` +- `PUT /admin/order/{orderId}/vehicle-assignment` - 分配车辆信息 + - 参数变化: `['@PathVariable orderId', '@PathVariable orderId']` → `['@PathVariable orderId']` +- `PUT /admin/order/{orderId}/hotel-assignment` - 分配酒店信息 +- `PUT /admin/order/{orderId}/balance-pay-method` - 设置尾款支付方式 + +### ✏️ AdminOrderItinerary (修改) + +**修改接口:** + +- `POST /admin/order/{orderId}/itinerary/skip` - 跳过节点 +- `DELETE /admin/order/{orderId}/itinerary/skip/{editId}` - 恢复跳过的节点 +- `POST /admin/order/{orderId}/itinerary/add` - 新增节点 +- `DELETE /admin/order/{orderId}/itinerary/add/{editId}` - 删除新增的节点 +- `GET /admin/order/{orderId}/itinerary/merged` - 获取合并后的行程(原始+编辑) +- `GET /admin/order/{orderId}/itinerary/balance-summary` - 获取尾款调整汇总 + - 参数变化: `['@PathVariable orderId', '@PathVariable orderId']` → `['@PathVariable orderId']` +- `GET /admin/order/{orderId}/itinerary/edits` - 获取行程编辑记录列表 + - 参数变化: `['@PathVariable orderId', '@PathVariable orderId']` → `['@PathVariable orderId']` +- `POST /admin/order/{orderId}/itinerary/room-type-change/preview` - 房型切换差价预览 +- `POST /admin/order/{orderId}/itinerary/room-type-change` - 房型切换 +- `POST /admin/order/{orderId}/itinerary/vehicle-type-change/preview` - 车型切换差价预览 +- `POST /admin/order/{orderId}/itinerary/vehicle-type-change` - 车型切换 +- `POST /admin/order/{orderId}/itinerary/add-day` - 新增整天行程 +- `DELETE /admin/order/{orderId}/itinerary/day/{editId}` - 删除新增的整天行程 +- `PUT /admin/order/{orderId}/itinerary/edit/{editId}` - 修改编辑记录 +- `POST /admin/order/{orderId}/itinerary/confirm/{editId}` - 确认单条修改 +- `POST /admin/order/{orderId}/itinerary/confirm-all` - 批量确认所有待确认修改 +- `DELETE /admin/order/{orderId}/itinerary/pending/{editId}` - 撤回待确认的修改 + +### ✏️ AdminOrderTodo (修改) + +**修改接口:** + +- `GET /admin/order/{orderId}/todos` - 获取订单待办列表 + - 参数变化: `['@PathVariable orderId', '@PathVariable todoId']` → `['@PathVariable orderId']` +- `PUT /admin/order/todo/{todoId}/complete` - 完成待办 +- `GET /admin/order/todo/my-list` - 我的待办列表 +- `GET /admin/order/todo/my-count` - 我的待办数量 +- `GET /admin/order/todo/customizer-list` - 定制师列表 +- `PUT /admin/order/{orderId}/customizer` - 更换定制师 +- `GET /admin/order/todo/contract-eligible` - 可签合同订单列表(保险已完成) + +### ✏️ AdminRefund (修改) + +**修改接口:** + +- `GET /admin/order/refund/list` - 退款申请列表 +- `GET /admin/order/refund/{applicationId}` - 退款申请详情 + - 参数变化: `['@PathVariable applicationId', '@PathVariable applicationId']` → `['@PathVariable applicationId']` +- `GET /admin/order/refund/reason/list` - 退款原因列表 +- `POST /admin/order/refund/reason` - 创建退款原因 + - 参数变化: `['@RequestBody createRequest', '@PathVariable reasonId', '@RequestBody updateRequest']` → `['@RequestBody createRequest']` +- `PUT /admin/order/refund/reason/{reasonId}` - 修改退款原因 +- `DELETE /admin/order/refund/reason/{reasonId}` - 删除退款原因 + +### ✏️ AdminRefundPolicy (修改) + +**修改接口:** + +- `GET /admin/order/refund-policy/list` - 退款政策列表 +- `GET /admin/order/refund-policy/{policyId}` - 退款政策详情 +- `PUT /admin/order/refund-policy/{policyId}` - 修改退款政策 + +### ✏️ AdminWorkOrder (修改) + +**修改接口:** + +- `GET /admin/order/work-order/admin/order/work-order` - + - 参数变化: `['@RequestParam status']` → `[]` +- `GET /admin/order/work-order/list` - 工单列表 +- `GET /admin/order/work-order/{workOrderId}` - 工单详情 +- `GET /admin/order/work-order/stats` - 工单统计 + - 名称: ~~工单统计(待处理数等)~~ → **工单统计** + - 参数变化: `['@RequestBody body']` → `[]` +- `PUT /admin/order/work-order/{workOrderId}/process` - 处理工单(解决/驳回) + - 名称: ~~处理工单(解决/驳回)~~ → **处理工单(解决/驳回)** +- `PUT /admin/order/work-order/{workOrderId}/assign` - 指派工单 +- `POST /admin/order/work-order/{workOrderId}/comment` - 添加工单备注 + - 名称: ~~添加备注~~ → **添加工单备注** +- `GET /admin/order/work-order/count-by-order/{orderId}` - 按订单查工单数量 + +### ✏️ InternalAlbum (修改) + +**修改接口:** + +- `GET /internal/mp/album/orders` - 用户有相册的订单列表 + - 参数变化: `['@RequestParam userId', '@RequestParam userId', '@PathVariable orderId']` → `['@RequestParam userId', '@RequestParam userId']` +- `GET /internal/mp/album/folder/{folderId}/files` - 文件夹下的文件列表 +- `GET /internal/mp/album/file/{albumFileId}/download-url` - 获取文件下载链接 + +### ✏️ InternalDashboard (修改) + +**修改接口:** + +- `GET /internal/order/dashboard/internal/order/dashboard` - + - 参数变化: `['@RequestParam customizerId']` → `[]` +- `GET /internal/order/dashboard/overview-stats` - 概览统计 + - 名称: ~~概览统计(支持定制师/全局,支持今日/本周/本月)~~ → **概览统计** +- `GET /internal/order/dashboard/todo-summary` - 待办分类汇总 +- `GET /internal/order/dashboard/trend` - 数据趋势 + - 名称: ~~数据趋势(按天聚合)~~ → **数据趋势** +- `GET /internal/order/dashboard/funnel` - 转化漏斗 +- `GET /internal/order/dashboard/upcoming-trips` - 即将出行列表 +- `GET /internal/order/dashboard/ranking` - 业绩排行 + - 名称: ~~业绩排行(本月定制师排名)~~ → **业绩排行** +- `GET /internal/order/dashboard/calendar-events` - 日历事件 +- `GET /internal/order/dashboard/finance-stats` - 财务统计 +- `GET /internal/order/dashboard/refund-summary` - 退款汇总 + +### ✏️ InternalDesignerOrder (修改) + +**修改接口:** + +- `GET /internal/order/internal/order` - + - 参数变化: `['@RequestParam customizerId']` → `[]` +- `GET /internal/order/designer-stats` - 获取定制师订单统计 +- `GET /internal/order/global-stats` - 获取全局订单统计 + - 参数变化: `['@RequestParam customizerId', '@RequestParam page']` → `[]` +- `GET /internal/order/designer-list` - 定制师订单列表 + +### ✏️ InternalEarlyBird (修改) + +**修改接口:** + +- `GET /internal/mp/early-bird/active` - 获取当前有效的早鸟优惠计划列表 + - 参数变化: `['@RequestParam productType']` → `[]` +- `GET /internal/mp/early-bird/match` - 匹配最优早鸟优惠计划 + +### ✏️ InternalInvoice (修改) + +**修改接口:** + +- `GET /internal/mp/invoice/internal/mp/invoice` - + - 参数变化: `['@RequestParam userId', '@RequestBody request']` → `[]` +- `POST /internal/mp/invoice/apply` - 申请开票 + - 参数变化: `['@RequestParam userId', '@RequestBody request', '@RequestParam userId', '@PathVariable id']` → `['@RequestParam userId', '@RequestBody request']` +- `GET /internal/mp/invoice/{id}` - 发票详情 + - 参数变化: `['@RequestParam userId', '@PathVariable id', '@RequestParam userId', '@PathVariable orderId']` → `['@RequestParam userId', '@PathVariable id']` +- `GET /internal/mp/invoice/order/{orderId}` - 通过订单ID查询发票 + +### ✏️ InternalMpOrder (修改) + +**修改接口:** + +- `GET /internal/mp/order/internal/mp/order` - + - 参数变化: `['@RequestParam userId', '@RequestBody request']` → `[]` +- `POST /internal/mp/order/create` - 创建订单 +- `GET /internal/mp/order/list` - 订单列表 + - 参数变化: `['@RequestParam userId', '@RequestParam userId', '@PathVariable orderId']` → `['@RequestParam userId']` +- `GET /internal/mp/order/{orderId}` - 订单详情 + - 参数变化: `['@RequestParam userId', '@PathVariable orderId', '@RequestParam userId', '@PathVariable orderId']` → `['@RequestParam userId', '@PathVariable orderId', '@RequestParam userId']` +- `GET /internal/mp/order/lookup` - 通过联系人手机号+姓名查找订单 + - 名称: ~~通过联系人手机号+姓名查找订单(无需登录)~~ → **通过联系人手机号+姓名查找订单** + - 参数变化: `['@RequestParam contactPhone', '@RequestParam contactName', '@RequestParam userId']` → `['@RequestParam contactPhone', '@RequestParam contactName']` +- `POST /internal/mp/order/bind-by-contact` - 绑定未绑定的订单 + - 名称: ~~绑定未绑定的订单(通过联系人手机号+姓名)~~ → **绑定未绑定的订单** +- `POST /internal/mp/order/{orderId}/approve-unlock` - 客户同意解锁订单 +- `GET /internal/mp/order/count` - 各状态订单数量 +- `PUT /internal/mp/order/{orderId}/mark-reviewed` - 标记订单已评价 + - 名称: ~~标记订单已评价(评价服务回调)~~ → **标记订单已评价** + +### ✏️ InternalMpTrip (修改) + +**修改接口:** + +- `GET /internal/mp/trip/internal/mp/trip` - + - 参数变化: `['@RequestParam userId']` → `[]` +- `GET /internal/mp/trip/list` - 行程列表 + - 参数变化: `['@RequestParam userId', '@RequestParam userId', '@PathVariable orderId']` → `['@RequestParam userId']` +- `GET /internal/mp/trip/{orderId}` - 行程详情 + - 参数变化: `['@RequestParam userId', '@PathVariable orderId', '@RequestParam userId']` → `['@RequestParam userId', '@PathVariable orderId']` +- `GET /internal/mp/trip/today` - 今日行程 + +### ✏️ InternalOrderStats (修改) + +**修改接口:** + +- `GET /internal/mp/order/product-sold-count` - 获取产品已购出行人总数 +- `GET /internal/mp/order/participant-family-count` - 获取产品参与家庭数 +- `POST /internal/mp/order/invoice/reissue` - 发票换开 + +### ✏️ InternalOrderTraveler (修改) + +**修改接口:** + +- `GET /internal/order/traveler/internal/order/traveler` - + - 参数变化: `['@PathVariable orderId']` → `[]` +- `GET /internal/order/traveler/validate/{orderId}` - 验证订单出行人信息 + - 名称: ~~验证订单出行人信息(供支付服务调用)~~ → **验证订单出行人信息** + +### ✏️ InternalPaymentOrder (修改) + +**修改接口:** + +- `GET /internal/order/{orderId}/pay-info` - 获取订单支付信息 + - 参数变化: `['@PathVariable orderId', '@RequestBody dto']` → `['@PathVariable orderId']` +- `POST /internal/order/payment-result` - 通知支付成功 +- `POST /internal/order/refund-result` - 通知退款成功 + - 参数变化: `['@RequestBody dto', '@PathVariable orderId']` → `['@RequestBody dto']` +- `GET /internal/order/{orderId}/basic` - 获取订单基本信息(供合同服务调用) + +### ✏️ InternalRefund (修改) + +**修改接口:** + +- `GET /internal/mp/order/{orderId}/refund-preview` - 退款金额预览 +- `GET /internal/mp/order/refund-reasons` - 退款原因列表(C端) + - 名称: ~~退款原因列表~~ → **退款原因列表(C端)** + - 参数变化: `['@RequestParam userId', '@RequestParam userName', '@PathVariable orderId']` → `['@RequestParam userId']` +- `POST /internal/mp/order/{orderId}/refund` - 提交退款申请 +- `GET /internal/mp/order/refund/{applicationId}` - 退款申请详情(C端) + - 名称: ~~退款申请详情~~ → **退款申请详情(C端)** + - 参数变化: `['@RequestParam userId', '@PathVariable applicationId', '@RequestParam userId', '@PathVariable orderId']` → `['@RequestParam userId', '@PathVariable applicationId']` +- `GET /internal/mp/order/{orderId}/refund-detail` - 根据订单ID获取最新退款申请 + - 名称: ~~根据订单ID获取最新退款申请详情~~ → **根据订单ID获取最新退款申请** +- `POST /internal/mp/order/refund/{applicationId}/cancel` - 撤回退款申请 +- `POST /internal/order/refund-appeal-result` - 企微退款申诉审批结果回调 + - 返回类型: `` → `Result` +- `POST /internal/order/refund-application-result` - 企微退款申请审批结果回调 + - 返回类型: `` → `Result` + +### ✏️ MpOrder (修改) + +**修改接口:** + +- `GET /mp/order/list` - 我的订单列表 +- `GET /mp/order/{orderId}` - 订单详情 + +### ✏️ MpWeather (修改) + +**修改接口:** + +- `GET /internal/mp/weather/itinerary/{orderId}` - 获取订单行程天气 +- `GET /internal/mp/weather/live` - 获取指定城市实况天气 +- `GET /internal/mp/weather/forecast` - 获取指定城市天气预报 + +## 评价服务 + +### ✏️ AdminReview (修改) + +**修改接口:** + +- `GET /admin/review/list` - 评价列表(支持好中差评/有图/有视频筛选) +- `GET /admin/review/{reviewId}` - 评价详情 +- `POST /admin/review/{reviewId}/approve` - 通过评价 +- `POST /admin/review/{reviewId}/reject` - 拒绝评价 +- `POST /admin/review/{reviewId}/override-approve` - 覆盖通过(机器拒绝的) + +### ✏️ InternalMpReview (修改) + +**修改接口:** + +- `POST /internal/mp/review/create` - 创建评价(仅针对产品,每个订单仅可评价一次) + - 参数变化: `['@RequestBody body', '@PathVariable orderId']` → `['@RequestBody body']` +- `GET /internal/mp/review/my` - 我的评价列表 +- `GET /internal/mp/review/target` - 某目标的已通过评价(公开,支持好中差评/有图/有视频筛选) +- `GET /internal/mp/review/search` - 关键词搜索评价(公开) +- `GET /internal/mp/review/featured` - 首页精选评价 + - 参数变化: `['@RequestParam limit', '@PathVariable orderId']` → `['@RequestParam limit']` +- `GET /internal/mp/review/order/{orderId}/reviewable-targets` - 订单可评价目标列表 + - 参数变化: `['@PathVariable orderId', '@PathVariable reviewId']` → `['@PathVariable orderId']` +- `POST /internal/mp/review/{reviewId}/like` - 点赞/取消点赞评价 + - 参数变化: `['@PathVariable reviewId', '@PathVariable reviewId']` → `['@PathVariable reviewId']` +- `GET /internal/mp/review/{reviewId}/like/check` - 检查是否已点赞 + - 参数变化: `['@PathVariable reviewId', '@PathVariable reviewId']` → `['@PathVariable reviewId']` + +### ✏️ InternalReview (修改) + +**修改接口:** + +- `GET /internal/review/target-stats` - 目标评价统计(平均分,数量) +- `GET /internal/review/target-list` - 目标已通过评价列表 +- `GET /internal/review/stats-by-targets` - 批量目标评价统计(聚合多个targetId) +- `GET /internal/review/reviews-by-targets` - 批量目标已通过评价列表(聚合多个targetId) +- `GET /internal/review/product-highlights` - 产品精选评价(最高评分+最高点赞+统计) +- `GET /internal/review/customizer-reviews` - 定制师已通过评价列表 + +## 资源服务 + +### ✏️ Activity (修改) + +**修改接口:** + +- `POST /admin/activity/item` - 创建游玩项目 +- `GET /admin/activity/items` - 游玩项目列表 +- `GET /admin/activity/item/{activityId}` - 游玩项目详情 +- `PUT /admin/activity/item/{activityId}` - 更新游玩项目 +- `DELETE /admin/activity/item/{activityId}` - 删除游玩项目 +- `POST /admin/activity/item/{activityId}/submit-approval` - 提交启用/禁用审批 +- `PUT /admin/activity/item/{activityId}/status` - 启用/禁用切换 +- `PUT /admin/activity/items/batch/status` - 批量启用/禁用 +- `DELETE /admin/activity/items/batch` - 批量删除 + +### ✏️ ActivityPriceCalendar (修改) + +**修改接口:** + +- `GET /admin/activity/item/{activityId}/prices` - 查询价格日历 +- `PUT /admin/activity/item/{activityId}/prices` - 批量设置价格 +- `PUT /admin/activity/item/{activityId}/prices/batch-status` - 批量修改可接待状态 +- `DELETE /admin/activity/item/{activityId}/prices` - 批量清除价格 + +### ✏️ ActivityTag (修改) + +**修改接口:** + +- `GET /admin/activity/tags` - 获取管理标签列表(分页) +- `GET /admin/activity/tags/all` - 获取全部标签 +- `POST /admin/activity/tag` - 创建管理标签 +- `POST /admin/activity/tag/adhoc` - 解析自定义标签 +- `PUT /admin/activity/tag/{tagId}` - 编辑标签 +- `DELETE /admin/activity/tag/{tagId}` - 删除标签 +- `PUT /admin/activity/item/{activityId}/tags` - 更新项目标签 +- `PUT /admin/activity/items/batch/tags` - 批量打标签 + +### ✏️ InternalActivity (修改) + +**修改接口:** + +- `GET /internal/activity/item/{activityId}` - 获取项目简要信息 +- `GET /internal/activity/items/batch` - 批量获取项目简要信息 +- `POST /internal/activity/approval-result` - 处理审批回调结果 + - 返回类型: `` → `Result` + +### ✏️ InternalMpActivity (修改) + +**修改接口:** + +- `GET /internal/mp/activity/list` - C端活动列表 +- `GET /internal/mp/activity/{activityId}` - C端活动详情 + +### ✏️ InternalMpResourceBrief (修改) + +**修改接口:** + +- `GET /internal/mp/resource/scenic/brief` - 批量查询景区摘要 +- `GET /internal/mp/resource/restaurant/brief` - 批量查询餐厅摘要 +- `GET /internal/mp/resource/activity/brief` - 批量查询活动摘要 + +### ✏️ InternalResource (修改) + +**修改接口:** + +- `POST /internal/resource/approval-result` - 处理审批回调 - 分发到9个资源领域服务 + - 返回类型: `` → `Result` + +### ✏️ InternalResourceDetail (修改) + +**修改接口:** + +- `GET /internal/mp/resource/batch-details` - 批量查询资源详情(行程节点用) + +### ✏️ InternalResourceStats (修改) + +**修改接口:** + +- `GET /internal/resource/hotel/stats` - 获取酒店统计 +- `GET /internal/resource/vehicle/stats` - 获取车辆统计 + +### ✏️ CostItem (修改) + +**修改接口:** + +- `POST /admin/cost/item` - 创建费用项 +- `GET /admin/cost/items` - 费用项列表 +- `GET /admin/cost/item/{costId}` - 费用项详情 +- `PUT /admin/cost/item/{costId}` - 更新费用项 +- `DELETE /admin/cost/item/{costId}` - 删除费用项 +- `POST /admin/cost/item/{costId}/submit-approval` - 提交审批 +- `GET /admin/cost/items/enabled` - 启用的费用项列表 +- `GET /admin/cost/item/{costId}/price-logs` - 费用项价格变更记录 + +### ✏️ CostPriceCalendar (修改) + +**修改接口:** + +- `GET /admin/cost/item/{costId}/prices` - 查询价格日历 +- `PUT /admin/cost/item/{costId}/prices` - 批量设置价格 +- `DELETE /admin/cost/item/{costId}/prices` - 清除价格日历 + +### ✏️ InternalCost (修改) + +**修改接口:** + +- `POST /internal/cost/approval-result` - 处理审批回调结果 + - 返回类型: `` → `Result` +- `GET /internal/cost/items/batch` - 批量获取费用项 +- `GET /internal/cost/items/prices-by-date` - 按日期获取费用项价格 +- `POST /internal/cost/item/{costId}/ref-count` - 更新引用计数 + +### ✏️ Hotel (修改) + +**修改接口:** + +- `POST /admin/hotel/item` - 创建住宿 +- `GET /admin/hotel/items` - 住宿列表 +- `GET /admin/hotel/items/all-simple` - 所有启用的住宿(不分页,仅ID和名称) +- `GET /admin/hotel/item/{hotelId}` - 住宿详情 +- `PUT /admin/hotel/item/{hotelId}` - 更新住宿 +- `DELETE /admin/hotel/item/{hotelId}` - 删除住宿 +- `POST /admin/hotel/item/{hotelId}/submit-approval` - 提交启用/禁用审批 +- `PUT /admin/hotel/item/{hotelId}/status` - 启用/禁用切换 +- `PUT /admin/hotel/items/batch/status` - 批量启用/禁用 +- `DELETE /admin/hotel/items/batch` - 批量删除 + +### ✏️ HotelTag (修改) + +**修改接口:** + +- `GET /admin/hotel/tags` - 预设标签列表(分页) +- `GET /admin/hotel/tags/all` - 所有标签列表 +- `POST /admin/hotel/tag` - 创建标签 +- `POST /admin/hotel/tag/adhoc` - 查找或创建自定义标签 +- `PUT /admin/hotel/tag/{tagId}` - 更新标签 +- `DELETE /admin/hotel/tag/{tagId}` - 删除标签 +- `PUT /admin/hotel/item/{hotelId}/tags` - 设置住宿标签 +- `PUT /admin/hotel/items/batch/tags` - 批量添加/移除标签 + +### ✏️ InternalHotel (修改) + +**修改接口:** + +- `GET /internal/hotel/item/{hotelId}` - 获取住宿简要信息 +- `GET /internal/hotel/items/batch` - 批量获取住宿简要信息 +- `POST /internal/hotel/approval-result` - 处理审批回调结果 + - 返回类型: `` → `Result` + +### ✏️ InternalMpHotel (修改) + +**修改接口:** + +- `GET /internal/mp/hotel/list` - C端住宿列表 +- `GET /internal/mp/hotel/{hotelId}` - C端住宿详情 + +### ✏️ RoomPriceCalendar (修改) + +**修改接口:** + +- `GET /admin/hotel/room-type/{roomTypeId}/prices` - 查询价格日历 +- `PUT /admin/hotel/room-type/{roomTypeId}/prices` - 批量设置价格日历 +- `PUT /admin/hotel/room-type/{roomTypeId}/prices/batch-status` - 批量修改日期可售状态 +- `DELETE /admin/hotel/room-type/{roomTypeId}/prices` - 删除价格日历 + +### ✏️ RoomType (修改) + +**修改接口:** + +- `POST /admin/hotel/{hotelId}/room-type` - 创建房型 +- `GET /admin/hotel/{hotelId}/room-types` - 房型列表 +- `GET /admin/hotel/room-type/{roomTypeId}` - 房型详情 +- `PUT /admin/hotel/room-type/{roomTypeId}` - 更新房型 +- `DELETE /admin/hotel/room-type/{roomTypeId}` - 删除房型 +- `PUT /admin/hotel/room-type/{roomTypeId}/status` - 启用/禁用房型 +- `POST /admin/hotel/room-type/{roomTypeId}/submit-approval` - 提交房型启用/禁用审批 + +### ✏️ InternalMpRestaurant (修改) + +**修改接口:** + +- `GET /internal/mp/restaurant/list` - C端餐厅列表 +- `GET /internal/mp/restaurant/{restaurantId}` - C端餐厅详情 + +### ✏️ InternalRestaurant (修改) + +**修改接口:** + +- `GET /internal/restaurant/item/{restaurantId}` - \u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f +- `GET /internal/restaurant/items/batch` - \u6279\u91cf\u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f +- `POST /internal/restaurant/approval-result` - \u5904\u7406\u5ba1\u6279\u56de\u8c03\u7ed3\u679c + - 返回类型: `` → `Result` + +### ✏️ Restaurant (修改) + +**修改接口:** + +- `POST /admin/restaurant/item` - 创建餐厅 +- `GET /admin/restaurant/items` - 餐厅列表 +- `GET /admin/restaurant/item/{restaurantId}` - 餐厅详情 +- `PUT /admin/restaurant/item/{restaurantId}` - 更新餐厅 +- `DELETE /admin/restaurant/item/{restaurantId}` - 删除餐厅 +- `POST /admin/restaurant/item/{restaurantId}/submit-approval` - 提交启用/禁用审批 +- `PUT /admin/restaurant/item/{restaurantId}/status` - 上下架切换 +- `PUT /admin/restaurant/items/batch/status` - 批量上下架 +- `DELETE /admin/restaurant/items/batch` - 批量删除 + +### ✏️ RestaurantTag (修改) + +**修改接口:** + +- `GET /admin/restaurant/tags` - \u83b7\u53d6\u7ba1\u7406\u6807\u7b7e\u5217\u8868\uff08\u5206\u9875\uff09 +- `GET /admin/restaurant/tags/all` - \u83b7\u53d6\u5168\u90e8\u6807\u7b7e +- `POST /admin/restaurant/tag` - \u521b\u5efa\u7ba1\u7406\u6807\u7b7e +- `POST /admin/restaurant/tag/adhoc` - \u89e3\u6790\u81ea\u5b9a\u4e49\u6807\u7b7e +- `PUT /admin/restaurant/tag/{tagId}` - \u7f16\u8f91\u6807\u7b7e +- `DELETE /admin/restaurant/tag/{tagId}` - \u5220\u9664\u6807\u7b7e +- `PUT /admin/restaurant/item/{restaurantId}/tags` - \u66f4\u65b0\u9910\u5385\u6807\u7b7e +- `PUT /admin/restaurant/items/batch/tags` - \u6279\u91cf\u6253\u6807\u7b7e + +### ✏️ InternalMpScenic (修改) + +**修改接口:** + +- `GET /internal/mp/scenic/list` - C端景区列表 +- `GET /internal/mp/scenic/{scenicId}` - C端景区详情 +- `GET /internal/mp/scenic/{scenicId}/nearby` - C端附近景区 + +### ✏️ InternalScenic (修改) + +**修改接口:** + +- `GET /internal/scenic/spot/{scenicId}` - 获取景区简要信息 +- `GET /internal/scenic/spots/batch` - 批量获取景区简要信息 +- `GET /internal/scenic/spot/{scenicId}/price/{date}` - 查询某日价格 +- `GET /internal/scenic/spot/{scenicId}/available/{date}` - 判断某日是否可售 +- `PUT /internal/scenic/spot/{scenicId}/stock/deduct` - 扣减库存 +- `PUT /internal/scenic/spot/{scenicId}/stock/restore` - 恢复库存 +- `POST /internal/scenic/approval-result` - 处理审批回调结果 + - 返回类型: `` → `Result` + +### ✏️ ScenicPriceCalendar (修改) + +**修改接口:** + +- `GET /admin/scenic/spot/{scenicId}/prices` - 查询价格日历 +- `PUT /admin/scenic/spot/{scenicId}/prices` - 批量设置价格 +- `PUT /admin/scenic/spot/{scenicId}/prices/status` - 批量修改可售状态 +- `DELETE /admin/scenic/spot/{scenicId}/prices` - 批量清除价格 + +### ✏️ ScenicSeason (修改) + +**修改接口:** + +- `GET /admin/scenic/spot/{scenicId}/seasons` - 获取景区全部季节内容 +- `PUT /admin/scenic/spot/{scenicId}/season/{seasonType}` - 保存/更新季节内容 +- `DELETE /admin/scenic/spot/{scenicId}/season/{seasonType}` - 删除季节内容 + +### ✏️ ScenicSpot (修改) + +**修改接口:** + +- `POST /admin/scenic/spot` - 创建景区 +- `GET /admin/scenic/spots` - 景区列表 +- `GET /admin/scenic/spot/{scenicId}` - 景区详情 +- `PUT /admin/scenic/spot/{scenicId}` - 更新景区 +- `DELETE /admin/scenic/spot/{scenicId}` - 删除景区 +- `POST /admin/scenic/spot/{scenicId}/submit-approval` - 提交启用/禁用审批 +- `PUT /admin/scenic/spot/{scenicId}/status` - 上下架切换 +- `PUT /admin/scenic/spots/batch/status` - 批量上下架 +- `DELETE /admin/scenic/spots/batch` - 批量删除 + +### ✏️ ScenicTag (修改) + +**修改接口:** + +- `GET /admin/scenic/tags` - 获取管理标签列表(分页) +- `GET /admin/scenic/tags/all` - 获取全部标签 +- `POST /admin/scenic/tag` - 创建管理标签 +- `POST /admin/scenic/tag/adhoc` - 解析自定义标签 +- `PUT /admin/scenic/tag/{tagId}` - 编辑标签 +- `DELETE /admin/scenic/tag/{tagId}` - 删除标签 +- `PUT /admin/scenic/spot/{scenicId}/tags` - 更新景区标签 +- `PUT /admin/scenic/spots/batch/tags` - 批量打标签 + +### ✏️ InternalService (修改) + +**修改接口:** + +- `GET /internal/service/item/{serviceId}` - 获取服务简要信息 +- `GET /internal/service/items/batch` - 批量获取服务简要信息 +- `POST /internal/service/approval-result` - 处理审批回调结果 + - 返回类型: `` → `Result` + +### ✏️ ServiceItem (修改) + +**修改接口:** + +- `POST /admin/service/item` - 创建增值服务 + - 名称: ~~创建服务~~ → **创建增值服务** +- `GET /admin/service/items` - 增值服务列表 + - 名称: ~~服务列表~~ → **增值服务列表** +- `GET /admin/service/item/{serviceId}` - 增值服务详情 + - 名称: ~~服务详情~~ → **增值服务详情** +- `PUT /admin/service/item/{serviceId}` - 更新增值服务 + - 名称: ~~更新服务~~ → **更新增值服务** +- `DELETE /admin/service/item/{serviceId}` - 删除增值服务 + - 名称: ~~删除服务~~ → **删除增值服务** +- `POST /admin/service/item/{serviceId}/submit-approval` - 提交启用/禁用审批 +- `PUT /admin/service/item/{serviceId}/status` - 启用/禁用切换 +- `PUT /admin/service/items/batch/status` - 批量启用/禁用 +- `DELETE /admin/service/items/batch` - 批量删除 + +### ✏️ ServicePriceCalendar (修改) + +**修改接口:** + +- `GET /admin/service/item/{serviceId}/prices` - 查询价格日历 +- `PUT /admin/service/item/{serviceId}/prices` - 批量设置价格 +- `PUT /admin/service/item/{serviceId}/prices/batch-status` - 批量修改可售状态 +- `DELETE /admin/service/item/{serviceId}/prices` - 批量清除价格 + +### ✏️ ServiceTag (修改) + +**修改接口:** + +- `GET /admin/service/tags` - 获取管理标签列表(分页) +- `GET /admin/service/tags/all` - 获取全部标签 +- `POST /admin/service/tag` - 创建管理标签 +- `POST /admin/service/tag/adhoc` - 解析自定义标签 +- `PUT /admin/service/tag/{tagId}` - 编辑标签 +- `DELETE /admin/service/tag/{tagId}` - 删除标签 +- `PUT /admin/service/item/{serviceId}/tags` - 更新服务标签 +- `PUT /admin/service/items/batch/tags` - 批量打标签 + +### ✏️ InternalStaff (修改) + +**修改接口:** + +- `GET /internal/staff/{staffId}` - 获取人员简要信息 +- `GET /internal/staff/batch` - 批量获取人员简要信息 +- `GET /internal/staff/by-type/{staffType}` - 按人员类型查询 +- `POST /internal/staff/approval-result` - 处理审批回调结果 + - 返回类型: `` → `Result` +- `GET /internal/staff/batch-basic` - 批量获取人员基本信息(逗号分隔ID) +- `GET /internal/staff/list-available` - 列出可用人员(用于下拉选择) + +### ✏️ Staff (修改) + +**修改接口:** + +- `GET /admin/staff/list` - 服务人员列表 +- `GET /admin/staff/{staffId}` - 服务人员详情 +- `PUT /admin/staff/{staffId}` - 更新服务人员 +- `DELETE /admin/staff/{staffId}` - 删除服务人员 +- `POST /admin/staff/{staffId}/submit-approval` - 提交审批 +- `PUT /admin/staff/{staffId}/status` - 更新状态 +- `PUT /admin/staff/batch/status` - 批量更新状态 +- `DELETE /admin/staff/batch` - 批量删除 + +### ✏️ StaffPriceCalendar (修改) + +**修改接口:** + +- `GET /admin/staff/type/{staffType}/prices` - 查询价格日历(按人员类型) +- `PUT /admin/staff/type/{staffType}/prices` - 批量设置价格(按人员类型) +- `PUT /admin/staff/type/{staffType}/prices/batch-status` - 批量修改调度状态(按人员类型) +- `DELETE /admin/staff/type/{staffType}/prices` - 清除价格日历(按人员类型) + +### ✏️ StaffTag (修改) + +**修改接口:** + +- `GET /admin/staff/tags` - 预设标签列表(分页) +- `GET /admin/staff/tags/all` - 全部标签列表 +- `POST /admin/staff/tag` - 创建标签 +- `POST /admin/staff/tag/adhoc` - 解析自定义标签 +- `PUT /admin/staff/tag/{tagId}` - 更新标签 +- `DELETE /admin/staff/tag/{tagId}` - 删除标签 +- `PUT /admin/staff/{staffId}/tags` - 设置人员标签 +- `PUT /admin/staff/batch/tags` - 批量添加/移除标签 + +### ✏️ InternalSupplies (修改) + +**修改接口:** + +- `GET /internal/supplies/item/{suppliesId}` - 获取备品简要信息 +- `GET /internal/supplies/items/batch` - 批量获取备品简要信息 +- `POST /internal/supplies/approval-result` - 处理审批回调结果 + - 返回类型: `` → `Result` + +### ✏️ Supplies (修改) + +**修改接口:** + +- `POST /admin/supplies/item` - 创建备品 +- `GET /admin/supplies/items` - 备品列表 +- `GET /admin/supplies/item/{suppliesId}` - 备品详情 +- `PUT /admin/supplies/item/{suppliesId}` - 更新备品 +- `DELETE /admin/supplies/item/{suppliesId}` - 删除备品 +- `POST /admin/supplies/item/{suppliesId}/submit-approval` - 提交启用/禁用审批 +- `PUT /admin/supplies/item/{suppliesId}/status` - 上下架切换 +- `PUT /admin/supplies/items/batch/status` - 批量上下架 +- `DELETE /admin/supplies/items/batch` - 批量删除 + +### ✏️ SuppliesTag (修改) + +**修改接口:** + +- `GET /admin/supplies/tags` - 获取管理标签列表(分页) +- `GET /admin/supplies/tags/all` - 获取全部标签 +- `POST /admin/supplies/tag` - 创建管理标签 +- `POST /admin/supplies/tag/adhoc` - 解析自定义标签 +- `PUT /admin/supplies/tag/{tagId}` - 编辑标签 +- `DELETE /admin/supplies/tag/{tagId}` - 删除标签 +- `PUT /admin/supplies/item/{suppliesId}/tags` - 更新备品标签 +- `PUT /admin/supplies/items/batch/tags` - 批量打标签 + +### ✏️ InternalVehicle (修改) + +**修改接口:** + +- `GET /internal/vehicle/model/{vehicleId}` - 获取车型简要信息 +- `GET /internal/vehicle/models/batch` - 批量获取车型简要信息 +- `GET /internal/vehicle/model/by-type/{vehicleType}` - 按车辆类型查询车辆 +- `GET /internal/vehicle/model/by-name/{name}` - 按名称查询车辆 +- `POST /internal/vehicle/approval-result` - 处理审批回调结果 + - 返回类型: `` → `Result` + +### ✏️ VehicleModel (修改) + +**修改接口:** + +- `POST /admin/vehicle/model` - 创建车型 +- `GET /admin/vehicle/models` - 车型列表 +- `GET /admin/vehicle/models/all` - 车型全量列表(不分页,用于下拉选择) +- `GET /admin/vehicle/model/{vehicleId}` - 车型详情 +- `PUT /admin/vehicle/model/{vehicleId}` - 更新车型 +- `DELETE /admin/vehicle/model/{vehicleId}` - 删除车型 +- `POST /admin/vehicle/model/{vehicleId}/submit-approval` - 提交审批 +- `PUT /admin/vehicle/model/{vehicleId}/status` - 更新状态 +- `PUT /admin/vehicle/models/batch/status` - 批量更新状态 +- `DELETE /admin/vehicle/models/batch` - 批量删除 + +### ✏️ VehiclePriceCalendar (修改) + +**修改接口:** + +- `GET /admin/vehicle/model/{vehicleId}/prices` - 查询价格日历 +- `PUT /admin/vehicle/model/{vehicleId}/prices` - 批量设置价格 +- `PUT /admin/vehicle/model/{vehicleId}/prices/batch-status` - 批量修改调度状态 +- `DELETE /admin/vehicle/model/{vehicleId}/prices` - 清除价格日历 + +### ✏️ VehicleTag (修改) + +**修改接口:** + +- `GET /admin/vehicle/tags` - 预设标签列表(分页) +- `GET /admin/vehicle/tags/all` - 全部标签列表 +- `POST /admin/vehicle/tag` - 创建标签 +- `POST /admin/vehicle/tag/adhoc` - 解析自定义标签 +- `PUT /admin/vehicle/tag/{tagId}` - 更新标签 +- `DELETE /admin/vehicle/tag/{tagId}` - 删除标签 +- `PUT /admin/vehicle/model/{vehicleId}/tags` - 设置车型标签 +- `PUT /admin/vehicle/models/batch/tags` - 批量添加/移除标签 + +## 📦 请求/响应对象变更 + +- **hl-common** + - ✏️ **AdminBasicDTO** (修改5字段) + - ✏️ **DepartmentDTO** (修改3字段) + - ✏️ **ExternalContactEventDTO** (修改3字段) + - ✏️ **FileBindRefsDTO** (修改3字段) + - ✏️ **FileUnbindRefsDTO** (修改2字段) + - ✏️ **OrderPayInfoDTO** (修改12字段) + - ✏️ **PaymentResultDTO** (修改4字段) + - ✏️ **RefundResultDTO** (修改3字段) + - ✏️ **ResourceDetailDTO** (修改14字段) + - ✏️ **TravelerValidationDTO** (修改6字段) + - ✏️ **WechatDeptSyncDTO** (修改4字段) + - ✏️ **WechatMessageDTO** (修改2字段) + - ✏️ **WechatUserSyncDTO** (修改9字段) +- **产品服务** + - ✏️ **FormulaStepRequest** (修改1字段) + - ✏️ **GroupBatchCreateRequest** (修改5字段) + - ✏️ **GroupBatchDisbandRequest** (修改1字段) + - ✏️ **GroupBatchStaffRequest** (修改3字段) + - ✏️ **GroupBatchUpdateRequest** (修改7字段) + - ✏️ **NodeCreateRequest** (修改3字段) + - ✏️ **PriceCalendarRequest** (修改3字段) + - ✏️ **PricingRequest** (修改13字段) + - ✏️ **ProductStatusRequest** (修改2字段) + - ✏️ **BatchMaterialIdsRequest** (修改1字段) + - ✏️ **RefBatchBindRequest** (修改1字段) + - ✏️ **RefBatchUnbindRequest** (修改1字段) + - ✏️ **RefBindRequest** (修改5字段) + - ✏️ **RefUnbindRequest** (修改4字段) + - ✏️ **ResourceCoverQuery** (修改2字段) + - ✏️ **ResourcePriceQuery** (修改5字段) + - ✏️ **MaterialVO** (修改5字段) + - ✏️ **ResourcePriceVO** (修改5字段) +- **企微回调服务** + - ✏️ **ChatMessageVO** (修改8字段) +- **用户服务** + - ✏️ **ContactRequest** (修改2字段) + - ✏️ **CreateJobRequest** (修改4字段) + - ✏️ **FavoriteRequest** (修改1字段) + - ✏️ **FootprintRequest** (修改1字段) + - ✏️ **TravelerRequest** (修改3字段) + - ✏️ **UpdateJobRequest** (修改4字段) + - ✏️ **CustomPushRequest** (修改7字段) + - ✏️ **CustomPushResultVO** (修改3字段) + - ✏️ **EventConfigVO** (修改6字段) + - ✏️ **SendLogVO** (修改2字段) + - ✏️ **UserSimpleVO** (修改4字段) + - ✏️ **ContactVO** (修改2字段) + - ✏️ **CustomerVO** (修改1字段) + - ✏️ **LoginLogVO** (修改2字段) + - 🆕 **SysJobLogVO** (9 个字段) + - 🆕 **SysJobVO** (11 个字段) + - ✏️ **UserVO** (修改3字段) +- **素材服务** + - ✏️ **ChunkUploadCancelRequest** (修改1字段) + - ✏️ **ChunkUploadCompleteRequest** (修改1字段) + - ✏️ **ChunkUploadInitRequest** (修改5字段) + - ✏️ **FileBatchIdsRequest** (修改1字段) + - ✏️ **FileUploadConfirmRequest** (修改1字段) + - ✏️ **FileUploadTokenRequest** (修改5字段) + - ✏️ **ChunkUploadInitVO** (修改4字段) + - ✏️ **ChunkUploadPartVO** (修改1字段) + - ✏️ **FileUploadTokenVO** (修改14字段) + - ✏️ **FileVO** (修改13字段) +- **订单服务** + - ✏️ **AdminCreateOrderRequest** (修改2字段) + - ✏️ **AdminRefundReviewRequest** (修改2字段) + - ✏️ **AdminUpdateOrderRequest** (修改1字段) + - ✏️ **CreateWorkOrderRequest** (修改3字段) + - ✏️ **EarlyBirdPlanRequest** (修改2字段) + - ✏️ **MpOrderQueryRequest** (修改1字段) + - ✏️ **MpUpdateOrderRequest** (修改1字段) + - ✏️ **RefundApplyRequest** (修改2字段) + - ✏️ **RefundPolicyRequest** (修改2字段) + - ✏️ **UpdateOrderStatusRequest** (修改1字段) + - ✏️ **WorkOrderVO** (修改6字段) +- **资源服务** + - ✏️ **RestaurantCreateRequest** (修改1字段) + - ✏️ **RestaurantQueryRequest** (修改1字段) + - ✏️ **RestaurantUpdateRequest** (修改1字段) + - ✏️ **RestaurantListVO** (修改1字段) + - ✏️ **RestaurantVO** (修改1字段) + +#### hl-common + +### ✏️ AdminBasicDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `adminId` | `Long` | `Long` 管理员ID | +| `username` | `String` | `String` 用户名 | +| `avatarUrl` | `String` | `String` 头像URL | +| `wechatUserid` | `String` | `String` 企微用户ID | +| `wechatName` | `String` | `String` 企微用户名称 | + +### ✏️ DepartmentDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `deptId` | `Long` | `Long` 部门ID | +| `deptName` | `String` | `String` 部门名称 | +| `parentId` | `Long` | `Long` 上级部门ID | + +### ✏️ ExternalContactEventDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `changeType` | `String` | `String` 变更类型: add_external_contact/del_follow_user/del_external_contact/edit_external_contact | +| `userId` | `String` | `String` 员工企微用户ID | +| `externalUserId` | `String` | `String` 外部联系人ID | + +### ✏️ FileBindRefsDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `bizType` | `String` | `String` 业务类型 | +| `bizId` | `Long` | `Long` 业务ID | +| `fileIds` | `List` | `List` 文件ID列表 | + +### ✏️ FileUnbindRefsDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `bizType` | `String` | `String` 业务类型 | +| `bizId` | `Long` | `Long` 业务ID | + +### ✏️ OrderPayInfoDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `orderId` | `Long` | `Long` 订单ID | +| `orderNo` | `String` | `String` 订单编号 | +| `userId` | `Long` | `Long` 用户ID | +| `mchId` | `String` | `String` 商户号 | +| `totalPrice` | `BigDecimal` | `BigDecimal` 总价 | +| `discountAmount` | `BigDecimal` | `BigDecimal` 优惠金额 | +| `depositAmount` | `BigDecimal` | `BigDecimal` 定金金额 | +| `paidAmount` | `BigDecimal` | `BigDecimal` 已支付金额 | +| `paymentMode` | `String` | `String` 支付模式: FULL=全款, DEPOSIT=定金+尾款 | +| `status` | `String` | `String` 订单状态 | +| `productName` | `String` | `String` 产品名称 | +| `isBooking` | `Boolean` | `Boolean` 是否预定产品: true=预定(定金可不填出行人), false=非预定(支付前必须填出行人) | + +### ✏️ PaymentResultDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `orderId` | `Long` | `Long` 订单ID | +| `payType` | `String` | `String` 支付类型: FULL=全款, DEPOSIT=定金, BALANCE=尾款 | +| `paidAmount` | `BigDecimal` | `BigDecimal` 支付金额 | +| `transactionIdWx` | `String` | `String` 微信支付交易号 | + +### ✏️ RefundResultDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `orderId` | `Long` | `Long` 订单ID | +| `refundAmount` | `BigDecimal` | `BigDecimal` 退款金额 | +| `refundIdWx` | `String` | `String` 微信退款单号 | + +### ✏️ ResourceDetailDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `resourceId` | `String` | `String` 资源ID | +| `resourceType` | `String` | `String` 资源类型: SCENIC_SPOT/HOTEL/RESTAURANT/ACTIVITY | +| `name` | `String` | `String` 资源名称 | +| `subtitle` | `String` | `String` 副标题 | +| `description` | `String` | `String` 简介/描述 | +| `cover` | `String` | `String` 封面图URL | +| `images` | `List` | `List` 图片URL列表(轮播图) | +| `address` | `String` | `String` 地址 | +| `longitude` | `BigDecimal` | `BigDecimal` 经度 | +| `latitude` | `BigDecimal` | `BigDecimal` 纬度 | +| `tags` | `List` | `List` 标签列表 | +| `featureIntro` | `String` | `String` 图文详情(featureIntro JSON) | +| `rating` | `BigDecimal` | `BigDecimal` 评分 | +| `city` | `String` | `String` 所在城市 | + +### ✏️ TravelerValidationDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `orderId` | `Long` | `Long` 订单ID | +| `requiredCount` | `Integer` | `Integer` 需要的出行人数量 | +| `actualCount` | `Integer` | `Integer` 实际填写的出行人数量 | +| `isComplete` | `Boolean` | `Boolean` 是否完整(数量足够且信息完整) | +| `incompleteTravelerIds` | `List` | `List` 信息不完整的出行人ID列表 | +| `message` | `String` | `String` 验证消息 | + +### ✏️ WechatDeptSyncDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `id` | `Long` | `Long` 部门ID | +| `name` | `String` | `String` 部门名称 | +| `parentId` | `Long` | `Long` 上级部门ID | +| `order` | `Integer` | `Integer` 排序值 | + +### ✏️ WechatMessageDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `toUserIds` | `List` | `List` 接收用户ID列表 | +| `content` | `String` | `String` 消息内容 | + +### ✏️ WechatUserSyncDTO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `userid` | `String` | `String` 企微用户ID | +| `name` | `String` | `String` 用户名称 | +| `department` | `String` | `String` 所属部门ID(逗号分隔) | +| `position` | `String` | `String` 职位 | +| `mobile` | `String` | `String` 手机号 | +| `gender` | `Integer` | `Integer` 性别: 1=男, 2=女, 0=未定义 | +| `email` | `String` | `String` 邮箱 | +| `avatar` | `String` | `String` 头像URL | +| `status` | `Integer` | `Integer` 状态: 1=已激活, 2=已禁用, 4=未激活, 5=退出企业 | + +#### 产品服务 + +### ✏️ FormulaStepRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `expression` | `String` 表达式 | `String` Aviator表达式(支持数学运算、条件判断、内置函数;可引用前置步骤的输出变量和公式变量表中的变量) | + +### ✏️ GroupBatchCreateRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `batchName` | `String` batch name | `String` 批次名称 | +| `departureDate` | `LocalDate` departure date | `LocalDate` 出发日期 | +| `enrollmentDeadline` | `LocalDate` enrollment deadline | `LocalDate` 报名截止日期,必须早于出发日期 | +| `maxParticipants` | `int` max participants | `int` 最大参团人数(报名人数达到上限后自动关闭报名) | +| `remark` | `String` remark | `String` 备注说明 | + +### ✏️ GroupBatchDisbandRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `reason` | `String` disband reason | `String` 解散原因(如:报名人数不足、行程调整等) | + +### ✏️ GroupBatchStaffRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `staffId` | `Long` staff ID (from resource-service) | `Long` 人员ID(来自资源服务的人员库) | +| `staffRole` | `String` role in this batch: LEADER/PHOTOGRAPHER/DRIVER/OTHER | `String` 在该批次中的角色:LEADER(领队)/PHOTOGRAPHER(摄影师)/DRIVER(司机)/OTHER(其他) | +| `remark` | `String` remark | `String` 备注(如:主导游、备用摄影师等) | + +### ✏️ GroupBatchUpdateRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `batchName` | `String` batch name | `String` 批次名称 | +| `departureDate` | `LocalDate` departure date | `LocalDate` 出发日期 | +| `enrollmentDeadline` | `LocalDate` enrollment deadline | `LocalDate` 报名截止日期 | +| `minParticipants` | `Integer` min participants | `Integer` 最低成团人数(0=不限制) | +| `maxParticipants` | `Integer` max participants | `Integer` 最大参团人数(不能低于已报名人数) | +| `remark` | `String` remark | `String` 备注说明 | +| `sortOrder` | `Integer` sort order | `Integer` 排序序号 | + +### ✏️ NodeCreateRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `resourceType` | `String` 关联资源类型:SCENIC_SPOT/HOTEL/RESTAURANT/ACTIVITY/VEHICLE/SERVICE | `String` 关联资源类型(关联后可从资源服务获取价格参与成本计算):SCENIC/HOTEL/RESTAURANT/ACTIVITY/VEHICLE/SERVICE | +| `resourceId` | `String` 关联资源ID | `String` 关联资源ID(来自资源服务,关联后节点名称和图片可自动同步) | +| `familyIds` | `List` 所属家庭ID列表(定制产品按家庭分配) | `List` 所属家庭ID列表(仅CUSTOM定制产品使用,实现按家庭分配行程节点) | + +### ✏️ PriceCalendarRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `costAutoCalc` | `Boolean` 是否自动计算成本 | `Boolean` 是否自动计算成本(true时重新测算会自动更新此日期的价格) | +| `stock` | `Integer` 库存数量 | `Integer` 库存数量(CORE/GROUP按人头扣减,CUSTOM/ROUTE按单扣减) | +| `status` | `String` 状态:OPEN=开放 CLOSED=关闭 | `String` 状态:OPEN=开放预订 CLOSED=关闭(不可预订) | + +### ✏️ PricingRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `pricingMode` | `String` 定价模式:AUTO=自动计算 MANUAL=手动定价 CUSTOM=定制定价 | `String` 定价模式:AUTO=根据行程资源价格自动计算 MANUAL=手动在价格日历设置每日价格 CUSTOM=定制产品整单定价 | +| `profitMode` | `String` 利润模式:FIXED=固定金额 PERCENT=百分比 | `String` 利润模式(AUTO模式下生效):FIXED=在成本基础上加固定金额 PERCENT=在成本基础上按百分比加价 | +| `childWithBed` | `BigDecimal` 儿童占床价 | `BigDecimal` 儿童加床费(childNeedBed=true时额外加收的费用) | +| `childNoBed` | `BigDecimal` 儿童不占床价 | `BigDecimal` 儿童不占床价(暂未使用,预留字段) | +| `babyPrice` | `BigDecimal` 婴儿价 | `BigDecimal` 婴儿固定价格(不随日期变化) | +| `childDiscountPercent` | `BigDecimal` 儿童折扣百分比 | `BigDecimal` 小童折扣百分比(小童价=儿童价×此百分比/100,如70表示打7折) | +| `customTotalPrice` | `BigDecimal` 定制产品总价(CUSTOM模式下使用) | `BigDecimal` 定制产品总价(CUSTOM定价模式下使用,代表整单总价) | +| `minGroupSize` | `Integer` 最小成团人数 | `Integer` 最小成团人数(CORE/GROUP产品用,影响均摊成本计算) | +| `maxGroupSize` | `Integer` 最大成团人数 | `Integer` 最大成团人数(CORE/GROUP产品用) | +| `paymentType` | `String` 支付方式:FULL=全款 DEPOSIT=定金+尾款 | `String` 支付方式:FULL=全款支付 DEPOSIT=定金+尾款分期支付 | +| `depositRatio` | `Integer` 定金比例(百分比) | `Integer` 定金比例(百分比,如30代表30%。与depositAmount二选一,优先使用比例) | +| `depositAmount` | `BigDecimal` 定金金额 | `BigDecimal` 定金金额(固定金额,与depositRatio二选一) | +| `balanceDueDays` | `Integer` 尾款支付截止天数(出发前N天) | `Integer` 尾款支付截止天数(出发前N天必须支付尾款,超时可能取消订单) | + +### ✏️ ProductStatusRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `status` | `String` 目标状态:DRAFT/PENDING_REVIEW/REVIEWED/REJECTED/PUBLISHED/UNPUBLISHED/COMPLETED | `String` 目标状态。核心/小蒙马:DRAFT/PENDING_REVIEW/REVIEWED/REJECTED/PUBLISHED/UNPUBLISHED;定制产品:COMPLETED | +| `reason` | `String` 状态变更原因(驳回时必填) | `String` 状态变更原因(驳回时必填;上架/下架审批时可填) | + +### ✏️ BatchMaterialIdsRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `materialIds` | `List` | `List` 素材ID列表 | + +### ✏️ RefBatchBindRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `refs` | `List` | `List` 引用绑定列表 | + +### ✏️ RefBatchUnbindRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `refs` | `List` | `List` 引用解绑列表 | + +### ✏️ RefBindRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `materialId` | `Long` | `Long` 素材ID | +| `bizType` | `String` | `String` 业务类型 | +| `bizId` | `Long` | `Long` 业务ID | +| `bizName` | `String` | `String` 业务名称 | +| `usageType` | `String` | `String` 用途类型 | + +### ✏️ RefUnbindRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `materialId` | `Long` | `Long` 素材ID | +| `bizType` | `String` | `String` 业务类型 | +| `bizId` | `Long` | `Long` 业务ID | +| `usageType` | `String` | `String` 用途类型 | + +### ✏️ ResourceCoverQuery (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `resourceType` | `String` | `String` 资源类型 | +| `resourceId` | `String` | `String` 资源ID | + +### ✏️ ResourcePriceQuery (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `resourceIds` | `List` | `List` 资源ID列表 | +| `staffTypes` | `List` | `List` 人员类型列表 | +| `startDate` | `LocalDate` | `LocalDate` 开始日期 | +| `endDate` | `LocalDate` | `LocalDate` 结束日期 | +| `subType` | `String` | `String` 资源子类型(如酒店房型ID、车辆类别) | + +### ✏️ MaterialVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `materialId` | `String` | `String` 素材ID | +| `ossUrl` | `String` | `String` OSS访问URL | +| `thumbnailUrl` | `String` | `String` 缩略图URL | +| `materialName` | `String` | `String` 素材名称 | +| `fileType` | `String` | `String` 文件类型 | + +### ✏️ ResourcePriceVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `resourceId` | `Long` | `Long` 资源ID | +| `staffType` | `String` | `String` 人员类型 | +| `date` | `LocalDate` | `LocalDate` 日期 | +| `price` | `BigDecimal` | `BigDecimal` 价格 | +| `resourceName` | `String` | `String` 资源名称 | + +#### 企微回调服务 + +### ✏️ ChatMessageVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `msgId` | `String` | `String` 消息ID | +| `fromUser` | `String` | `String` 发送人ID | +| `fromUserName` | `String` | `String` 发送人姓名 | +| `fromUserAvatar` | `String` | `String` 发送人头像 | +| `roomId` | `String` | `String` 群聊ID | +| `msgTime` | `Long` | `Long` 消息时间戳 | +| `msgType` | `String` | `String` 消息类型 | +| `content` | `String` | `String` 消息内容 | + +#### 用户服务 + +### ✏️ ContactRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `channelType` | `String` 渠道类型:ABOUT=关于我们 ONLINE_CS=在线客服 PHONE=电话咨询 | `String` 渠道类型,关联字典contact_channel_type:ABOUT=关于我们, ONLINE_CS=在线客服, PHONE=电话咨询 | +| `status` | `Integer` 状态:0=下线 1=上线 | `Integer` 状态,关联字典common_status:0=下线, 1=上线 | + +### ✏️ CreateJobRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `jobGroup` | `String` 任务分组 | `String` 任务分组,字典类型:job_group(DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步) | +| `invokeTarget` | `String` 调用目标(Bean名称.方法名) | `String` 调用目标(Bean名称.方法名),方法必须是无参公开方法 | +| `cronExpression` | `String` Cron表达式 | `String` Cron表达式,标准6位(秒 分 时 日 月 周) | +| `misfirePolicy` | `String` 计划执行策略:0=默认 1=立即触发 2=触发一次 3=不触发 | `String` 计划执行策略,字典类型:job_misfire_policy(DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发) | + +### ✏️ FavoriteRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `targetType` | `String` 收藏类型 | `String` 收藏类型,关联字典favorite_resource_type | + +### ✏️ FootprintRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `resourceType` | `String` 资源类型 | `String` 资源类型,关联字典footprint_resource_type | + +### ✏️ TravelerRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `travelerType` | `String` 出行人类型(无需传入,后端根据出生日期自动判断) | `String` 出行人类型,关联字典traveler_type:ADULT=成人, CHILD=儿童, INFANT=婴儿(无需传入,后端根据birthday自动判断) | +| `idCardType` | `String` 证件类型:ID_CARD=身份证 PASSPORT=护照 | `String` 证件类型,关联字典id_card_type:ID_CARD=身份证, PASSPORT=护照 | +| `gender` | `Integer` 性别:0=女 1=男 | `Integer` 性别,关联字典gender:0=女, 1=男 | + +### ✏️ UpdateJobRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `jobGroup` | `String` 任务分组 | `String` 任务分组,字典类型:job_group(DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步) | +| `invokeTarget` | `String` 调用目标(Bean名称.方法名) | `String` 调用目标(Bean名称.方法名),方法必须是无参公开方法 | +| `cronExpression` | `String` Cron表达式 | `String` Cron表达式,标准6位(秒 分 时 日 月 周) | +| `misfirePolicy` | `String` 计划执行策略:0=默认 1=立即触发 2=触发一次 3=不触发 | `String` 计划执行策略,字典类型:job_misfire_policy(DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发) | + +### ✏️ CustomPushRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `title` | `String` | `String` 推送标题 | +| `content` | `String` | `String` 推送内容 | +| `channel` | `String` | `String` 推送通道: INAPP/SMS/WECHAT_WORK | +| `targetType` | `String` | `String` 目标类型: ALL_USERS/SPECIFIC_USERS | +| `userIds` | `List` | `List` 目标用户ID列表(目标类型为SPECIFIC_USERS时必填) | +| `categoryCode` | `String` | `String` 消息分类编码,默认SYSTEM | +| `link` | `String` | `String` 跳转链接(站内信时使用) | + +### ✏️ CustomPushResultVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `totalCount` | `int` | `int` 推送总数 | +| `successCount` | `int` | `int` 成功数 | +| `failCount` | `int` | `int` 失败数 | + +### ✏️ EventConfigVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `inappEnabled` | `Integer` 站内信开关 | `Integer` 站内信开关(0=关闭, 1=开启) | +| `smsEnabled` | `Integer` 短信开关 | `Integer` 短信开关(0=关闭, 1=开启) | +| `miniappEnabled` | `Integer` 小程序订阅消息开关 | `Integer` 小程序订阅消息开关(0=关闭, 1=开启) | +| `oaEnabled` | `Integer` 公众号模板消息开关 | `Integer` 公众号模板消息开关(0=关闭, 1=开启) | +| `weworkEnabled` | `Integer` 企微通知开关 | `Integer` 企微通知开关(0=关闭, 1=开启) | +| `weworkReceiverType` | `String` 企微接收人类型 | `String` 企微接收人类型(ROLE=按角色, DEPT=按部门, SPECIFIC=指定人员) | + +### ✏️ SendLogVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `channel` | `String` 通道: INAPP/SMS/MINIAPP/OA/WEWORK | `String` 通道,关联字典notification_channel:INAPP=站内信, SMS=短信, MINIAPP=小程序订阅, OA=公众号模板, WEWORK=企业微信 | +| `status` | `Integer` 发送状态: 0成功 1失败 2跳过 | `Integer` 发送状态,关联字典notification_send_status:0=成功, 1=失败, 2=跳过 | + +### ✏️ UserSimpleVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `id` | `Long` | `Long` 用户ID | +| `realName` | `String` | `String` 真实姓名 | +| `phone` | `String` | `String` 手机号 | +| `avatarUrl` | `String` | `String` 头像URL | + +### ✏️ ContactVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `channelType` | `String` 渠道类型:ABOUT=关于我们 ONLINE_CS=在线客服 PHONE=电话咨询 | `String` 渠道类型,关联字典contact_channel_type:ABOUT=关于我们, ONLINE_CS=在线客服, PHONE=电话咨询 | +| `status` | `Integer` 状态:0=下线 1=上线 | `Integer` 状态,关联字典common_status:0=下线, 1=上线 | + +### ✏️ CustomerVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `status` | `String` 状态:ACTIVE=正常 DISABLED=禁用 | `String` 状态,关联字典user_status:ACTIVE=正常, BANNED=已封禁 | + +### ✏️ LoginLogVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `loginMethod` | `String` 登录方式:PASSWORD=密码 WECHAT=企微扫码 TWO_FA=二次验证 | `String` 登录方式,关联字典login_method:PASSWORD=密码登录, WECHAT_QR=企微扫码登录, TWO_FA=二次验证登录 | +| `status` | `String` 登录状态:SUCCESS=成功 FAILED=失败 | `String` 登录状态,关联字典login_status:SUCCESS=成功, FAILED=失败 | + +### 🆕 SysJobLogVO (新增) + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| `jobLogId` | `Long` | 日志ID | +| `jobId` | `Long` | 任务ID | +| `jobName` | `String` | 任务名称 | +| `invokeTarget` | `String` | 调用目标 | +| `status` | `String` | 执行状态 | +| `message` | `String` | 执行结果/异常信息 | +| `startTime` | `LocalDateTime` | 开始时间 | +| `endTime` | `LocalDateTime` | 结束时间 | +| `createdAt` | `LocalDateTime` | 创建时间 | + +### 🆕 SysJobVO (新增) + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| `jobId` | `Long` | 任务ID | +| `jobName` | `String` | 任务名称 | +| `jobGroup` | `String` | 任务分组 | +| `invokeTarget` | `String` | 调用目标(Bean名称.方法名) | +| `cronExpression` | `String` | Cron表达式 | +| `misfirePolicy` | `String` | 计划执行策略 | +| `concurrent` | `Boolean` | 是否允许并发执行 | +| `status` | `String` | 任务状态 | +| `remark` | `String` | 备注 | +| `createdAt` | `LocalDateTime` | 创建时间 | +| `updatedAt` | `LocalDateTime` | 更新时间 | + +### ✏️ UserVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `status` | `String` 状态:ACTIVE=正常 DISABLED=禁用 | `String` 状态,关联字典user_status:ACTIVE=正常, BANNED=已封禁 | +| `idCardType` | `String` 证件类型:ID_CARD=身份证 PASSPORT=护照 | `String` 证件类型,关联字典id_card_type:ID_CARD=身份证, PASSPORT=护照 | +| `gender` | `Integer` 性别:0=女 1=男 | `Integer` 性别,关联字典gender:0=女, 1=男 | + +#### 素材服务 + +### ✏️ ChunkUploadCancelRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `uploadId` | `String` | `String` 上传ID | + +### ✏️ ChunkUploadCompleteRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `uploadId` | `String` | `String` 上传ID | + +### ✏️ ChunkUploadInitRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `filename` | `String` | `String` 文件名 | +| `fileSize` | `Long` | `Long` 文件大小(字节) | +| `contentType` | `String` | `String` 文件MIME类型 | +| `groupKey` | `String` | `String` 分组标识 | +| `fileHash` | `String` | `String` 文件哈希值 | + +### ✏️ FileBatchIdsRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `fileIds` | `List` | `List` 文件ID列表 | + +### ✏️ FileUploadConfirmRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `fileId` | `String` | `String` 文件ID | + +### ✏️ FileUploadTokenRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `fileName` | `String` | `String` 文件名 | +| `fileSize` | `Long` | `Long` 文件大小(字节) | +| `fileHash` | `String` | `String` 文件哈希值 | +| `groupKey` | `String` | `String` 分组标识 | +| `forcePresigned` | `boolean` | `boolean` 是否强制使用预签名URL | + +### ✏️ ChunkUploadInitVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `uploadId` | `String` | `String` 上传ID | +| `chunkSize` | `int` | `int` 分片大小(字节) | +| `fileId` | `String` | `String` 文件ID | +| `ossKey` | `String` | `String` OSS对象Key | + +### ✏️ ChunkUploadPartVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `etag` | `String` | `String` 分片ETag标识 | + +### ✏️ FileUploadTokenVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `fileId` | `String` | `String` 文件ID | +| `contentType` | `String` | `String` 文件MIME类型 | +| `uploadMode` | `String` | `String` 上传模式 | +| `presignedUrl` | `String` | `String` 预签名上传URL | +| `ossKey` | `String` | `String` OSS对象Key | +| `expireAt` | `LocalDateTime` | `LocalDateTime` 过期时间 | +| `stsToken` | `StsTokenInfo` | `StsTokenInfo` STS临时凭证 | +| `bucket` | `String` | `String` OSS存储桶名称 | +| `region` | `String` | `String` OSS区域 | +| `file` | `FileVO` | `FileVO` 文件信息(秒传时返回) | +| `accessKeyId` | `String` | `String` 访问密钥ID | +| `accessKeySecret` | `String` | `String` 访问密钥Secret | +| `securityToken` | `String` | `String` 安全令牌 | +| `expiration` | `String` | `String` 过期时间 | + +### ✏️ FileVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `fileId` | `String` | `String` 文件ID | +| `fileName` | `String` | `String` 文件名 | +| `fileType` | `String` | `String` 文件类型 | +| `mimeType` | `String` | `String` MIME类型 | +| `fileSize` | `Long` | `Long` 文件大小(字节) | +| `fileHash` | `String` | `String` 文件哈希值 | +| `ossUrl` | `String` | `String` OSS访问URL | +| `thumbnailUrl` | `String` | `String` 缩略图URL | +| `previewUrl` | `String` | `String` 预览URL | +| `groupKey` | `String` | `String` 分组标识 | +| `status` | `String` | `String` 文件状态 | +| `refCount` | `Integer` | `Integer` 引用次数 | +| `createdAt` | `LocalDateTime` | `LocalDateTime` 创建时间 | + +#### 订单服务 + +### ✏️ AdminCreateOrderRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `userPhone` | `String` 用户手机号(可选,用于关联C端用户) | `String` 用户手机号(可选,用于关联C端用户)。如匹配到已注册用户则自动绑定订单 | +| `expiryMinutes` | `Integer` 支付时限(分钟),不传则使用全局默认值 | `Integer` 支付时限(分钟),不传则使用全局默认值。超时未支付订单自动取消 | + +### ✏️ AdminRefundReviewRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `action` | `String` 审批结果(APPROVE/REJECT) | `String` 审批结果:APPROVE=通过(自动调起微信退款)、REJECT=拒绝(用户可发起申诉) | +| `actualAmount` | `BigDecimal` 实际退款金额(审批通过时可调整) | `BigDecimal` 实际退款金额(审批通过时可调整,不传则使用申请金额)。不能超过订单已付金额 | + +### ✏️ AdminUpdateOrderRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `mchId` | `String` 商户号 | `String` 商户号(微信支付商户号,多商户场景使用) | + +### ✏️ CreateWorkOrderRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `type` | `String` 工单类型: ROOM_CHANGE/ROOM_ADD/CHECKOUT_CHANGE/HOTEL_ISSUE/VEHICLE_CHANGE/SCENIC_ADD/SCENIC_REMOVE/OTHER | `String` 工单类型: ROOM_CHANGE(换房)/ROOM_ADD(加房)/CHECKOUT_CHANGE(改退房日期)/ | +| `priority` | `String` 优先级: URGENT/NORMAL | `String` 优先级: URGENT(紧急,如当天出发需处理)/NORMAL(普通) | +| `costDifference` | `BigDecimal` 差价(正数=加价, 负数=退费) | `BigDecimal` 差价(正数=客户需补差价, 负数=需退费给客户) | + +### ✏️ EarlyBirdPlanRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `minPeople` | `Integer` 最低人数 | `Integer` 最低出行人数(含成人+儿童),订单人数>=此值才能享受优惠 | +| `discountAmount` | `BigDecimal` 优惠金额 | `BigDecimal` 优惠金额(从订单总价中扣减的固定金额) | + +### ✏️ MpOrderQueryRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `status` | `String` 订单状态 | `String` 订单状态(不传则查全部)。可选值:PENDING_PAY/DEPOSIT_PAID/PAID/CONFIRMED/PENDING_BALANCE/PENDING_DEPARTURE/TRAVELLING/COMPLETED/AFTER_SALE/REFUNDING/REFUNDED/CANCELLED | + +### ✏️ MpUpdateOrderRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `departureDate` | `LocalDate` 出发日期 | `LocalDate` 出发日期(修改出发日期会触发价格重算) | + +### ✏️ RefundApplyRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `refundType` | `String` 退款类型(字典:refund_type) | `String` 退款类型:FULL=全额退款、PARTIAL=部分退款 | +| `reasonId` | `Long` 退款原因ID | `Long` 退款原因ID(从退款原因列表接口获取) | + +### ✏️ RefundPolicyRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `minDays` | `Integer` 距出发最少天数 | `Integer` 距出发最少天数(含当天)。例如:minDays=7表示出发前7天及以上适用此规则 | +| `refundRatio` | `Integer` 退款比例(百分比) | `Integer` 退款比例(百分比,0-100)。例如:80表示退已付金额的80% | + +### ✏️ UpdateOrderStatusRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `status` | `String` 目标状态(字典:order_status) | `String` 目标状态。可选值:PENDING_PAY(待支付)/DEPOSIT_PAID(已付定金)/PAID(已全额支付)/ | + +### ✏️ WorkOrderVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `logId` | `String` | `String` 日志ID | +| `action` | `String` | `String` 操作动作 | +| `actionLabel` | `String` | `String` 操作动作标签 | +| `content` | `String` | `String` 操作内容 | +| `operatorName` | `String` | `String` 操作人姓名 | +| `createdAt` | `LocalDateTime` | `LocalDateTime` 操作时间 | + +#### 资源服务 + +### ✏️ RestaurantCreateRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `cityName` | `String` 城市标签 | `String` 城市名称(纯文本输入) | + +### ✏️ RestaurantQueryRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `cityName` | `String` 城市标签 | `String` 城市名称筛选(纯文本) | + +### ✏️ RestaurantUpdateRequest (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `cityName` | `String` 城市标签 | `String` 城市名称(纯文本输入) | + +### ✏️ RestaurantListVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `cityName` | `String` 城市标签 | `String` 城市名称(纯文本) | + +### ✏️ RestaurantVO (修改) + +**修改字段:** + +| 字段 | 变更前 | 变更后 | +| --- | --- | --- | +| `cityName` | `String` 城市标签 | `String` 城市名称(纯文本) | + +## 🗄️ 数据库变更 + +### `add_customer_service_role.sql` (新增) + +```sql +-- 新增客服角色 +-- 权限:查看全部订单、全部产品(含定制产品)、配置保险、配置合同、查看素材 + +-- 1. 创建角色 +INSERT INTO sys_role (role_id, role_name, role_key, sort_order, status) +VALUES (8, '客服', 'CUSTOMER_SERVICE', 8, 'ACTIVE'); + +-- 2. 分配菜单权限 +INSERT INTO sys_role_menu (role_id, menu_id) VALUES +-- 订单管理(查看,不含创建) +(8, 700), -- 订单管理(目录) +(8, 710), -- 订单列表 +(8, 730), -- 订单详情 +(8, 740), -- 早鸟优惠 +(8, 750), -- 工单管理 +-- 退款管理(查看) +(8, 6001), -- 退款管理(目录) +(8, 6010), -- 退款申请 +(8, 6020), -- 退款政策 +(8, 6030), -- 退款原因 +-- 产品管理(查看全部,含定制产品,不含增删改按钮) +(8, 500), -- 产品管理(目录) +(8, 510), -- 产品列表 +(8, 520), -- 产品线管理 +(8, 530), -- 团期管理 +-- 保险管理(配置) +(8, 800), -- 保险管理(目录) +(8, 810), -- 保险产品 +(8, 820), -- 保险订单 +(8, 830), -- 保险方案 +-- 合同管理(配置) +(8, 850), -- 合同管理(目录) +(8, 851), -- 合同列表 +(8, 852), -- 补充约定模板 +-- 素材库(查看) +(8, 1890000000000000100); -- 素材库 +``` + +### `dict_data_seed.sql` (修改) + +```sql +-- Dict Types (9 types) + (7, '任务日志状态', 'job_log_status', 'BASE', 'ACTIVE', NULL, NOW(), NOW()), + (8, '任务状态', 'job_status', 'BASE', 'ACTIVE', NULL, NOW(), NOW()), + (9, '任务分组', 'job_group', 'BASE', 'ACTIVE', NULL, NOW(), NOW()); +-- job_status +INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status, remark, created_at, updated_at) +VALUES + (801, 'job_status', '启用', 'ACTIVE', 1, 'ACTIVE', 'success', NOW(), NOW()), + (802, 'job_status', '已暂停', 'PAUSED', 2, 'ACTIVE', 'info', NOW(), NOW()); + +-- job_group +INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status, remark, created_at, updated_at) +VALUES + (901, 'job_group', '默认分组', 'DEFAULT', 1, 'ACTIVE', '', NOW(), NOW()), + (902, 'job_group', '系统任务', 'SYSTEM', 2, 'ACTIVE', 'primary', NOW(), NOW()), + (903, 'job_group', '企微同步', 'WECHAT', 3, 'ACTIVE', 'success', NOW(), NOW()), + (904, 'job_group', '保险同步', 'INSURANCE', 4, 'ACTIVE', 'warning', NOW(), NOW()); + +``` + +### `dict_fix_frontend.sql` (新增) + +```sql +-- ============================================================ +-- 前端缺失的字典类型和字典数据补齐 +-- 对比前端 hl-ui 代码 vs 后端 sys_dict_type 表 +-- ============================================================ + +-- 1. cities - 城市(树形字典,MobilePreview/useLocation用) +INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) +VALUES (1900000001, '城市', 'cities', 'BASE', 'ACTIVE'); + +INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) +VALUES +(1900100001, 'cities', '海拉尔', 'hailar', 1, 'ACTIVE'), +(1900100002, 'cities', '满洲里', 'manzhouli', 2, 'ACTIVE'), +(1900100003, 'cities', '额尔古纳', 'eergu', 3, 'ACTIVE'), +(1900100004, 'cities', '根河', 'genhe', 4, 'ACTIVE'), +(1900100005, 'cities', '牙克石', 'yakeshi', 5, 'ACTIVE'), +(1900100006, 'cities', '扎兰屯', 'zhalantun', 6, 'ACTIVE'), +(1900100007, 'cities', '阿尔山', 'aershan', 7, 'ACTIVE'), +(1900100008, 'cities', '室韦', 'shiwei', 8, 'ACTIVE'), +(1900100009, 'cities', '恩和', 'enhe', 9, 'ACTIVE'), +(1900100010, 'cities', '黑山头', 'heishantou', 10, 'ACTIVE'), +(1900100011, 'cities', '陈巴尔虎旗', 'chenbaerhu', 11, 'ACTIVE'), +(1900100012, 'cities', '新巴尔虎左旗', 'xinbaerhuzuo', 12, 'ACTIVE'), +(1900100013, 'cities', '新巴尔虎右旗', 'xinbaerhuyou', 13, 'ACTIVE'), +(1900100014, 'cities', '鄂温克旗', 'ewenke', 14, 'ACTIVE'), +(1900100015, 'cities', '莫尔道嘎', 'moerdaoga', 15, 'ACTIVE'); + +-- 2. city - 城市筛选(产品行程资源面板用) +INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) +VALUES (1900000002, '城市筛选', 'city', 'BASE', 'ACTIVE'); + +INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) +VALUES +(1900200001, 'city', '海拉尔', 'hailar', 1, 'ACTIVE'), +(1900200002, 'city', '满洲里', 'manzhouli', 2, 'ACTIVE'), +(1900200003, 'city', '额尔古纳', 'eergu', 3, 'ACTIVE'), +(1900200004, 'city', '根河', 'genhe', 4, 'ACTIVE'), +(1900200005, 'city', '阿尔山', 'aershan', 5, 'ACTIVE'), +(1900200006, 'city', '室韦', 'shiwei', 6, 'ACTIVE'), +(1900200007, 'city', '恩和', 'enhe', 7, 'ACTIVE'), +(1900200008, 'city', '黑山头', 'heishantou', 8, 'ACTIVE'); + +-- 3. city_label - 城市标签(餐厅列表筛选用) +INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) +VALUES (1900000003, '城市标签', 'city_label', 'BASE', 'ACTIVE'); + +INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) +VALUES +(1900300001, 'city_label', '海拉尔', 'hailar', 1, 'ACTIVE'), +(1900300002, 'city_label', '满洲里', 'manzhouli', 2, 'ACTIVE'), +(1900300003, 'city_label', '额尔古纳', 'eergu', 3, 'ACTIVE'), +(1900300004, 'city_label', '根河', 'genhe', 4, 'ACTIVE'), +(1900300005, 'city_label', '阿尔山', 'aershan', 5, 'ACTIVE'), +(1900300006, 'city_label', '室韦', 'shiwei', 6, 'ACTIVE'), +(1900300007, 'city_label', '恩和', 'enhe', 7, 'ACTIVE'), +(1900300008, 'city_label', '黑山头', 'heishantou', 8, 'ACTIVE'); + +-- 4. environment_type - 环境类型(餐厅编辑用,前端key是environment_type) +INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) +VALUES (1900000004, '环境类型', 'environment_type +``` + +
+📁 全部变更文件列表(点击展开) ``` A design-01-mengma-detail.jpg @@ -360,32871 +3543,4 @@ M sql/dict_data_seed.sql A sql/dict_fix_frontend.sql ``` -## Controller 接口变更 - -### `hl-callback-service/src/main/java/com/hulalv/callback/controller/MsgAuditCallbackController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/controller/MsgAuditCallbackController.java b/hl-callback-service/src/main/java/com/hulalv/callback/controller/MsgAuditCallbackController.java -index a9d6ea9..adf49be 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/controller/MsgAuditCallbackController.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/controller/MsgAuditCallbackController.java -@@ -21,7 +21,7 @@ import java.util.concurrent.Executors; - * 路径: /callback/msg-audit - */ - @Slf4j --@Api(tags = "【回调接口】会话内容存档") -+@Api(tags = "【回调接口】会话内容存档", hidden = true) - @RestController - @RequestMapping("/callback") - public class MsgAuditCallbackController { -@@ -59,7 +59,8 @@ public class MsgAuditCallbackController { - * URL 验证端点。 - * 企业微信配置回调 URL 时发送 GET 请求验证,需解密 echostr 并返回明文。 - */ -- @ApiOperation("会话内容存档回调URL验证") -+ @ApiOperation(value = "会话内容存档回调URL验证", -+ notes = "企业微信会话内容存档的回调URL验证端点。使用独立的Token/AESKey,在企微后台配置会话存档回调URL时进行验证。") - @GetMapping(value = "/msg-audit", produces = MediaType.TEXT_PLAIN_VALUE) - public String verifyUrl( - @RequestParam("msg_signature") String msgSignature, -@@ -89,7 +90,8 @@ public class MsgAuditCallbackController { - * 企业微信在有新的存档消息时 POST 加密 XML 事件通知。 - * 通知仅表示"有新消息可拉取",具体消息内容需通过 API 主动拉取。 - */ -- @ApiOperation("接收会话内容存档事件通知") -+ @ApiOperation(value = "接收会话内容存档事件通知", -+ notes = "企业微信在有新的存档消息时推送事件通知到此端点。通知仅表示'有新消息可拉取',收到后异步触发消息拉取任务(通过Finance SDK API主动拉取具体内容并存储)。必须5秒内返回'success'。") - @PostMapping(value = "/msg-audit", - consumes = {MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_XML_VALUE}, - produces = MediaType.TEXT_PLAIN_VALUE) -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/controller/WxCallbackController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/controller/WxCallbackController.java b/hl-callback-service/src/main/java/com/hulalv/callback/controller/WxCallbackController.java -index cad043a..0b1d68b 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/controller/WxCallbackController.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/controller/WxCallbackController.java -@@ -27,7 +27,7 @@ import java.io.StringReader; - * No JWT auth required - uses WeChat's own signature verification. - */ - @Slf4j --@Api(tags = "【回调接口】企业微信回调") -+@Api(tags = "【回调接口】企业微信回调", hidden = true) - @RestController - @RequestMapping("/wx/callback") - public class WxCallbackController { -@@ -88,7 +88,8 @@ public class WxCallbackController { - * WeChat sends GET request to verify the callback URL. - * Must decrypt echostr and return it as plain text. - */ -- @ApiOperation("Callback URL verification") -+ @ApiOperation(value = "回调URL验证", -+ notes = "企业微信自建应用的回调URL验证端点。企微在配置回调URL时发送GET请求,需解密echostr并返回明文以完成验证。无需JWT认证,使用企微自有的签名校验机制。") - @GetMapping(value = "/app", produces = MediaType.TEXT_PLAIN_VALUE) - public String verifyUrl( - @RequestParam("msg_signature") String msgSignature, -@@ -118,7 +119,8 @@ public class WxCallbackController { - * WeChat POSTs encrypted XML for all event types. - * We decrypt, parse, dispatch to handler, and return "success". - */ -- @ApiOperation("Receive callback events") -+ @ApiOperation(value = "接收回调事件", -+ notes = "企业微信自建应用的事件接收端点。接收加密XML格式的事件通知(审批变更、消息等),解密后按事件类型分发:change_contact→通讯录变更,change_external_contact→外部联系人变更,open_approval_change→审批状态变更。必须5秒内返回'success'。") - @PostMapping(value = "/app", - consumes = {MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_XML_VALUE}, - produces = MediaType.TEXT_PLAIN_VALUE) -@@ -162,7 +164,8 @@ public class WxCallbackController { - // Contact Sync Callback Endpoints - // ========================================== - -- @ApiOperation("Contact sync URL verification") -+ @ApiOperation(value = "联系人同步URL验证", -+ notes = "企业微信通讯录同步的回调URL验证端点。使用独立的Token/AESKey(与应用回调不同),用于接收通讯录变更事件的回调URL配置验证。") - @GetMapping(value = "/contacts", produces = MediaType.TEXT_PLAIN_VALUE) - public String verifyContactsUrl( - @RequestParam("msg_signature") String msgSignature, -@@ -187,7 +190,8 @@ public class WxCallbackController { - return result; - } - -- @ApiOperation("Receive contact sync events") -+ @ApiOperation(value = "接收联系人同步事件", -+ notes = "企业微信通讯录变更事件接收端点。接收员工创建/更新/删除、部门变更等事件,解密后转发给ContactChangeHandler处理,同步更新本地管理员数据。必须5秒内返回'success'。") - @PostMapping(value = "/contacts", - consumes = {MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_XML_VALUE}, - produces = MediaType.TEXT_PLAIN_VALUE) -``` - -### `hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminClauseTemplateController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminClauseTemplateController.java b/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminClauseTemplateController.java -index f955c57..91ac6ed 100644 ---- a/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminClauseTemplateController.java -+++ b/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminClauseTemplateController.java -@@ -21,31 +21,33 @@ public class AdminClauseTemplateController { - - private final ClauseTemplateService clauseTemplateService; - -- @ApiOperation("获取启用的补充约定模板列表(创建合同用)") -+ @ApiOperation(value = "获取启用的补充约定模板列表(创建合同用)", -+ notes = "返回所有启用状态的补充约定模板,创建合同时选择需要附加的补充约定条款。\n\n**权限**:需管理员登录。") - @GetMapping("/list") - public Result> listActive() { - return Result.success(clauseTemplateService.listActive()); - } - -- @ApiOperation("获取全部补充约定模板(管理页用)") -+ @ApiOperation(value = "获取全部补充约定模板(管理页用)", notes = "**关联字典**:\n- common_status:通用状态(列表显示,ACTIVE=启用/INACTIVE=停用)") - @GetMapping("/list-all") - public Result> listAll() { - return Result.success(clauseTemplateService.listAll()); - } - -- @ApiOperation("切换模板启用/停用状态") -+ @ApiOperation(value = "切换模板启用/停用状态", notes = "**关联字典**:\n- common_status:通用状态(状态切换,ACTIVE=启用/INACTIVE=停用)") - @PutMapping("/{id}/toggle-status") - public Result toggleStatus(@ApiParam("模板ID") @PathVariable("id") Long templateId) { - return Result.success(clauseTemplateService.toggleStatus(templateId)); - } - -- @ApiOperation("创建补充约定模板") -+ @ApiOperation(value = "创建补充约定模板", notes = "创建合同补充约定的模板,支持变量占位符。创建后默认启用") - @PostMapping - public Result create(@Valid @RequestBody ClauseTemplateRequest request) { - return Result.success(clauseTemplateService.create(request)); - } - -- @ApiOperation("更新补充约定模板") -+ @ApiOperation(value = "更新补充约定模板", -+ notes = "更新模板的标题和内容。已被合同引用的模板更新不影响已创建的合同(合同记录的是快照内容)。\n\n**权限**:需管理员登录。") - @PutMapping("/{id}") - public Result update( - @ApiParam("模板ID") @PathVariable("id") Long templateId, -@@ -53,7 +55,7 @@ public class AdminClauseTemplateController { - return Result.success(clauseTemplateService.update(templateId, request)); - } - -- @ApiOperation("删除补充约定模板") -+ @ApiOperation(value = "删除补充约定模板", notes = "软删除模板。已被合同引用的模板仍可删除,不影响已创建的合同") - @DeleteMapping("/{id}") - public Result delete(@ApiParam("模板ID") @PathVariable("id") Long templateId) { - clauseTemplateService.delete(templateId); -``` - -### `hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminContractController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminContractController.java b/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminContractController.java -index a6a6dbe..437717e 100644 ---- a/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminContractController.java -+++ b/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminContractController.java -@@ -30,19 +30,20 @@ public class AdminContractController { - - private final ContractService contractService; - -- @ApiOperation("可用旅行社列表") -+ @ApiOperation(value = "可用旅行社列表", notes = "返回系统配置的旅行社列表,创建合同时选择签约旅行社") - @GetMapping("/agencies") - public Result> listAgencies() { - return Result.success(contractService.listAgencies()); - } - -- @ApiOperation("合同模板列表") -+ @ApiOperation(value = "合同模板列表", notes = "返回合同平台可用的合同模板列表,创建合同时选择模板") - @GetMapping("/templates") - public Result> listTemplates() { - return Result.success(contractService.listTemplates()); - } - -- @ApiOperation("创建合同(标准模式)") -+ @ApiOperation(value = "创建合同(标准模式)", notes = "标准电子签约流程:创建合同 → 平台生成合同PDF → 发送签署短信给出行人 → 出行人在线签署 → 回调更新状态。" -+ + "状态流转:CREATED → SIGNING → SIGNED") - @PostMapping("/create") - public Result createContract( - @ApiParam("创建合同请求") @Valid @RequestBody CreateContractRequest request, -@@ -51,7 +52,8 @@ public class AdminContractController { - return Result.success(contractService.createContract(request, adminId)); - } - -- @ApiOperation("报备合同(同步模式)") -+ @ApiOperation(value = "报备合同(同步模式)", notes = "线下签约模式:创建合同记录 → 管理员上传已签署的PDF → 同步到12301报备平台。" -+ + "状态流转:CREATED → UPLOADED → REPORTED") - @PostMapping("/report") - public Result reportContract( - @ApiParam("报备合同请求") @Valid @RequestBody ReportContractRequest request, -@@ -60,49 +62,51 @@ public class AdminContractController { - return Result.success(contractService.reportContract(request, adminId)); - } - -- @ApiOperation("合同列表") -+ @ApiOperation(value = "合同列表", notes = "分页查询合同记录,支持按订单号、合同状态、旅行社筛选\n\n**关联字典**:\n- contract_status:合同状态(列表筛选+显示)") - @GetMapping("/list") - public Result> listContracts(@ApiParam("合同查询条件") ContractQueryRequest request) { - return Result.success(contractService.listContracts(request)); - } - -- @ApiOperation("合同详情") -+ @ApiOperation(value = "合同详情", notes = "**关联字典**:\n- contract_status:合同状态(显示)") - @GetMapping("/{id}") - public Result getContractDetail(@ApiParam("合同ID") @PathVariable("id") Long contractId) { - return Result.success(contractService.getContractDetail(contractId)); - } - -- @ApiOperation("按订单查询合同") -+ @ApiOperation(value = "按订单查询合同", -+ notes = "查询指定订单下的所有合同记录(含已作废),按创建时间倒序排列。用于订单详情页展示合同历史。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- contract_status:合同状态(列表显示)") - @GetMapping("/by-order/{orderId}") - public Result> getByOrder(@ApiParam("订单ID") @PathVariable Long orderId) { - return Result.success(contractService.getByOrderId(orderId)); - } - -- @ApiOperation("获取订单有效合同") -+ @ApiOperation(value = "获取订单有效合同", -+ notes = "返回订单当前有效的合同(非作废状态的最新合同),用于检查订单是否已有签署中或已签署的合同。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- contract_status:合同状态(显示)") - @GetMapping("/active-by-order/{orderId}") - public Result getActiveByOrder(@ApiParam("订单ID") @PathVariable Long orderId) { - return Result.success(contractService.getActiveContractByOrderId(orderId)); - } - -- @ApiOperation("刷新合同状态(从平台同步)") -+ @ApiOperation(value = "刷新合同状态(从平台同步)", notes = "主动查询合同平台的最新签署状态并同步到本地,适用于回调未到达的场景") - @GetMapping("/{id}/status") - public Result refreshStatus(@ApiParam("合同ID") @PathVariable("id") Long contractId) { - return Result.success(contractService.refreshStatus(contractId)); - } - -- @ApiOperation("作废合同") -+ @ApiOperation(value = "作废合同", notes = "将合同标记为作废状态(不可恢复)。作废后该合同不再有效,可重新为订单创建新合同") - @PostMapping("/{id}/invalidate") - public Result invalidateContract(@ApiParam("合同ID") @PathVariable("id") Long contractId) { - return Result.success(contractService.invalidateContract(contractId)); - } - -- @ApiOperation("重发签署短信") -+ @ApiOperation(value = "重发签署短信", notes = "重新发送签署短信给出行人,用于签署短信过期或未收到的场景。仅SIGNING状态的合同可操作") - @PostMapping("/{id}/resend-sms") - public Result resendSms(@ApiParam("合同ID") @PathVariable("id") Long contractId) { - return Result.success(contractService.resendSms(contractId)); - } - -- @ApiOperation("上传已签署PDF(同步模式)") -+ @ApiOperation(value = "上传已签署PDF(同步模式)", notes = "同步模式专用:上传线下签署完成的合同PDF文件,上传后合同状态变为UPLOADED,可进一步报备") - @PostMapping("/{id}/upload-pdf") - public Result uploadPdf( - @ApiParam("合同ID") @PathVariable("id") Long contractId, -``` - -### `hl-contract-service/src/main/java/com/hulalv/contract/controller/ContractCallbackController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-contract-service/src/main/java/com/hulalv/contract/controller/ContractCallbackController.java b/hl-contract-service/src/main/java/com/hulalv/contract/controller/ContractCallbackController.java -index 8415d27..bad13a5 100644 ---- a/hl-contract-service/src/main/java/com/hulalv/contract/controller/ContractCallbackController.java -+++ b/hl-contract-service/src/main/java/com/hulalv/contract/controller/ContractCallbackController.java -@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.*; - - import javax.validation.Valid; - --@Api(tags = "【回调接口】合同回调") -+@Api(tags = "【回调接口】合同回调", hidden = true) - @Slf4j - @RestController - @RequestMapping("/contract/callback") -@@ -20,7 +20,7 @@ public class ContractCallbackController { - - private final ContractCallbackService callbackService; - -- @ApiOperation("12301合同状态回调") -+ @ApiOperation(value = "12301合同状态回调", notes = "接收12301全国旅游监管平台的合同签署状态回调。出行人签署完成后平台推送状态变更到此接口,自动更新本地合同状态") - @PostMapping("/12301") - public ResponseEntity handle12301Callback(@Valid @RequestBody ContractCallbackPayload payload) { - log.info("Received 12301 callback: contractNumber={}, state={}", -``` - -### `hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalContractController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalContractController.java b/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalContractController.java -index 8929f18..3c25a33 100644 ---- a/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalContractController.java -+++ b/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalContractController.java -@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "【内部接口】合同(Feign调用)") -+@Api(tags = "【内部接口】合同(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/contract") - @RequiredArgsConstructor -@@ -19,19 +19,19 @@ public class InternalContractController { - - private final ContractService contractService; - -- @ApiOperation("按订单查询合同(内部调用)") -+ @ApiOperation(value = "按订单查询合同(内部调用)", notes = "**关联字典**:\n- contract_status:合同状态(返回字段)") - @GetMapping("/by-order/{orderId}") - public Result> getByOrder(@PathVariable Long orderId) { - return Result.success(contractService.getByOrderId(orderId)); - } - -- @ApiOperation("按订单批量查询合同(内部调用)") -+ @ApiOperation(value = "按订单批量查询合同(内部调用)", notes = "**关联字典**:\n- contract_status:合同状态(返回字段)") - @PostMapping("/by-orders") - public Result>> getByOrders(@RequestBody List orderIds) { - return Result.success(contractService.getByOrderIds(orderIds)); - } - -- @ApiOperation("检查订单是否有已签署合同(内部调用)") -+ @ApiOperation(value = "检查订单是否有已签署合同(内部调用)", notes = "检查订单是否存在有效签署的合同(SIGNED/REPORTED/UPLOADED状态),用于订单流程中的合同校验") - @GetMapping("/has-signed/{orderId}") - public Result hasSigned(@PathVariable Long orderId) { - List contracts = contractService.getByOrderId(orderId); -@@ -41,7 +41,7 @@ public class InternalContractController { - return Result.success(signed); - } - -- @ApiOperation("按订单作废所有有效合同(级联调用)") -+ @ApiOperation(value = "按订单作废所有有效合同(级联调用)", notes = "订单取消或退款时级联作废该订单下所有有效合同,reason参数记录作废原因") - @PostMapping("/invalidate/{orderId}") - public Result invalidateByOrder(@PathVariable Long orderId, - @RequestParam(value = "reason", required = false) String reason) { -``` - -### `hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalMpContractController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalMpContractController.java b/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalMpContractController.java -index 90d323c..bbb5883 100644 ---- a/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalMpContractController.java -+++ b/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalMpContractController.java -@@ -16,7 +16,7 @@ import java.util.Map; - * C端合同内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "【内部接口】小程序合同(Feign调用)") -+@Api(tags = "【内部接口】小程序合同(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/contract") - @RequiredArgsConstructor -@@ -24,7 +24,7 @@ public class InternalMpContractController { - - private final ContractService contractService; - -- @ApiOperation("用户合同列表") -+ @ApiOperation(value = "用户合同列表", notes = "**关联字典**:\n- contract_status:合同状态(列表筛选+显示)") - @GetMapping("/list") - public Result> listContracts( - @RequestParam Long userId, -@@ -34,7 +34,7 @@ public class InternalMpContractController { - return Result.success(contractService.listUserContracts(userId, status, page, pageSize)); - } - -- @ApiOperation("用户合同详情") -+ @ApiOperation(value = "用户合同详情", notes = "**关联字典**:\n- contract_status:合同状态(显示)") - @GetMapping("/{id}") - public Result getContractDetail( - @PathVariable("id") Long contractId, -@@ -42,7 +42,7 @@ public class InternalMpContractController { - return Result.success(contractService.getUserContractDetail(contractId, userId)); - } - -- @ApiOperation("按订单查合同(返回最新有效合同)") -+ @ApiOperation(value = "按订单查合同(返回最新有效合同)", notes = "**关联字典**:\n- contract_status:合同状态(显示)") - @GetMapping("/by-order/{orderId}") - public Result getContractByOrder( - @PathVariable Long orderId, -@@ -50,7 +50,7 @@ public class InternalMpContractController { - return Result.success(contractService.getUserContractByOrderId(orderId, userId)); - } - -- @ApiOperation("按订单查所有有效合同(TOUR+INSURANCE各一条)") -+ @ApiOperation(value = "按订单查所有有效合同(TOUR+INSURANCE各一条)", notes = "**关联字典**:\n- contract_status:合同状态(显示)") - @GetMapping("/by-order/{orderId}/all") - public Result> getContractsByOrder( - @PathVariable Long orderId, -@@ -58,7 +58,8 @@ public class InternalMpContractController { - return Result.success(contractService.getUserContractsByOrderId(orderId, userId)); - } - -- @ApiOperation("重新发送合同签署短信") -+ @ApiOperation(value = "重新发送合同签署短信", -+ notes = "内部服务间调用。小程序端用户请求重发签署短信,用于签署链接过期或短信未收到的场景。仅SIGNING状态的合同可操作。\n\n**关联字典**:\n- contract_status:合同状态(仅SIGNING可操作)") - @PostMapping("/{contractId}/resend-sms") - public Result resendContractSms( - @PathVariable("contractId") Long contractId, -``` - -### `hl-file-service/src/main/java/com/hulalv/file/controller/FileController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-file-service/src/main/java/com/hulalv/file/controller/FileController.java b/hl-file-service/src/main/java/com/hulalv/file/controller/FileController.java -index 5b04b02..c78b2d2 100644 ---- a/hl-file-service/src/main/java/com/hulalv/file/controller/FileController.java -+++ b/hl-file-service/src/main/java/com/hulalv/file/controller/FileController.java -@@ -33,7 +33,7 @@ public class FileController { - private final FileService fileService; - private final FileRefService fileRefService; - -- @ApiOperation("请求上传凭证") -+ @ApiOperation(value = "请求上传凭证", notes = "上传流程第一步:前端请求上传凭证 → 获取OSS预签名URL和临时凭证 → 前端直传OSS → 调用确认上传接口。凭证有效期有限,过期需重新请求") - @OperationLog(value = "请求上传凭证", module = "文件管理") - @PostMapping("/upload/token") - public Result requestUploadToken( -@@ -44,7 +44,7 @@ public class FileController { - return Result.success(vo); - } - -- @ApiOperation("确认上传完成") -+ @ApiOperation(value = "确认上传完成", notes = "上传流程第二步:前端直传OSS完成后调用此接口,系统验证文件存在性并创建文件记录。支持MD5去重,相同文件不会重复存储") - @OperationLog(value = "确认上传", module = "文件管理") - @PostMapping("/upload/confirm") - public Result confirmUpload( -@@ -55,21 +55,21 @@ public class FileController { - return Result.success(vo); - } - -- @ApiOperation("文件列表(分页)") -+ @ApiOperation(value = "文件列表(分页)", notes = "支持按文件类型、分组、上传者等条件筛选,按上传时间倒序分页返回\n\n**关联字典**:\n- file_type:文件类型(列表筛选+显示)\n- file_status:文件状态(显示)") - @GetMapping("/list") - public Result> listFiles(@ApiParam("文件查询条件") @Valid FileQueryRequest request) { - IPage page = fileService.listFiles(request); - return Result.success(page); - } - -- @ApiOperation("文件详情") -+ @ApiOperation(value = "文件详情", notes = "**关联字典**:\n- file_type:文件类型(显示)\n- file_status:文件状态(显示)") - @GetMapping("/{fileId}") - public Result getFileDetail(@ApiParam("文件ID") @PathVariable Long fileId) { - FileVO vo = fileService.getFileDetail(fileId); - return Result.success(vo); - } - -- @ApiOperation("删除文件") -+ @ApiOperation(value = "删除文件", notes = "软删除文件记录,如果文件存在引用关系则不允许删除。OSS上的物理文件由定时任务清理") - @OperationLog(value = "删除文件", module = "文件管理") - @DeleteMapping("/{fileId}") - public Result deleteFile(@ApiParam("文件ID") @PathVariable Long fileId) { -@@ -77,21 +77,21 @@ public class FileController { - return Result.success(null); - } - -- @ApiOperation("文件引用列表") -+ @ApiOperation(value = "文件引用列表", notes = "查看文件被哪些业务实体引用(如景区封面、酒店图片等),用于判断文件是否可安全删除") - @GetMapping("/{fileId}/refs") - public Result> getFileRefs(@ApiParam("文件ID") @PathVariable Long fileId) { - List refs = fileRefService.getRefsByFileId(fileId); - return Result.success(refs); - } - -- @ApiOperation("存储统计") -+ @ApiOperation(value = "存储统计", notes = "返回文件总数、总存储空间、各类型文件占比等统计信息") - @GetMapping("/stats") - public Result getStats() { - FileStatsVO stats = fileService.getStats(); - return Result.success(stats); - } - -- @ApiOperation("文件内容流式预览") -+ @ApiOperation(value = "文件内容流式预览", notes = "流式输出文件内容,设置正确的Content-Type头,支持浏览器直接预览图片和PDF等文件") - @GetMapping("/{fileId}/preview") - public void previewContent(@ApiParam("文件ID") @PathVariable Long fileId, HttpServletResponse response) throws IOException { - fileService.streamContent(fileId, response); -``` - -### `hl-file-service/src/main/java/com/hulalv/file/controller/InternalFileController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-file-service/src/main/java/com/hulalv/file/controller/InternalFileController.java b/hl-file-service/src/main/java/com/hulalv/file/controller/InternalFileController.java -index cf46b6b..3690ff3 100644 ---- a/hl-file-service/src/main/java/com/hulalv/file/controller/InternalFileController.java -+++ b/hl-file-service/src/main/java/com/hulalv/file/controller/InternalFileController.java -@@ -30,7 +30,7 @@ import org.springframework.web.multipart.MultipartFile; - import javax.validation.Valid; - import java.util.List; - --@Api(tags = "【内部接口】文件(Feign调用)") -+@Api(tags = "【内部接口】文件(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/file") - @RequiredArgsConstructor -@@ -40,28 +40,30 @@ public class InternalFileController { - private final FileRefService fileRefService; - private final ChunkUploadService chunkUploadService; - -- @ApiOperation("绑定文件到业务实体") -+ @ApiOperation(value = "绑定文件到业务实体", notes = "将文件与业务实体建立引用关系(如景区ID+封面图),同一文件可被多个业务实体引用") - @PostMapping("/bindRefs") - public Result bindRefs(@Valid @RequestBody BindRefsRequest request) { - fileRefService.bindRefs(request.getBizType(), request.getBizId(), request.getFileIds()); - return Result.success(null); - } - -- @ApiOperation("解绑业务实体的所有文件") -+ @ApiOperation(value = "解绑业务实体的所有文件", notes = "删除指定业务类型+业务ID下的所有文件引用关系,常用于业务实体删除时的级联清理") - @PostMapping("/unbindRefs") - public Result unbindRefs(@Valid @RequestBody UnbindRefsRequest request) { - fileRefService.unbindRefs(request.getBizType(), request.getBizId()); - return Result.success(null); - } - -- @ApiOperation("批量获取文件信息") -+ @ApiOperation(value = "批量获取文件信息", -+ notes = "内部服务间调用。根据文件ID列表批量查询文件信息(含OSS URL、文件名、类型等),用于其他服务获取关联文件的详细数据。") - @PostMapping("/byIds") - public Result> getFilesByIds(@Valid @RequestBody BatchFileRequest request) { - List files = fileService.getFilesByIds(request.getFileIds()); - return Result.success(files); - } - -- @ApiOperation("内部上传凭证(素材服务调用)") -+ @ApiOperation(value = "内部上传凭证(素材服务调用)", -+ notes = "内部服务间调用。素材服务代理调用,为指定管理员生成OSS上传预签名URL和临时凭证,用于素材库的文件上传流程。") - @PostMapping("/upload/token") - public Result requestUploadTokenInternal( - @Valid @RequestBody UploadTokenRequest request, -@@ -69,7 +71,7 @@ public class InternalFileController { - return Result.success(fileService.requestUploadToken(request, adminId)); - } - -- @ApiOperation("内部直接上传文件(服务间调用)") -+ @ApiOperation(value = "内部直接上传文件(服务间调用)", notes = "服务间直接上传文件到OSS,跳过预签名流程。返回OSS公开访问URL,适用于后端生成的文件(如路线地图截图)") - @PostMapping("/upload/direct") - public Result uploadDirect( - @RequestParam("file") MultipartFile file, -@@ -78,7 +80,8 @@ public class InternalFileController { - return Result.success(vo.getOssUrl()); - } - -- @ApiOperation("内部确认上传(素材服务调用)") -+ @ApiOperation(value = "内部确认上传(素材服务调用)", -+ notes = "内部服务间调用。素材服务代理调用,确认文件已上传至OSS并创建文件记录。支持MD5去重。") - @PostMapping("/upload/confirm") - public Result confirmUploadInternal( - @Valid @RequestBody UploadConfirmRequest request, -@@ -88,7 +91,7 @@ public class InternalFileController { - - // ==================== 分片上传 ==================== - -- @ApiOperation("分片上传-初始化") -+ @ApiOperation(value = "分片上传-初始化", notes = "大文件上传第一步:初始化分片上传任务,返回uploadId和每个分片的预签名URL。前端按分片并发上传后调用complete接口合并") - @PostMapping("/upload/chunk/init") - public Result chunkUploadInit( - @Valid @RequestBody ChunkUploadInitRequest request, -@@ -96,7 +99,7 @@ public class InternalFileController { - return Result.success(chunkUploadService.initChunkUpload(request, adminId)); - } - -- @ApiOperation("分片上传-上传分片") -+ @ApiOperation(value = "分片上传-上传分片", notes = "大文件上传第二步:逐个上传分片,返回分片的ETag用于后续合并校验。支持断点续传,已上传的分片无需重传") - @PostMapping("/upload/chunk") - public Result chunkUploadPart( - @RequestParam("uploadId") String uploadId, -@@ -105,14 +108,14 @@ public class InternalFileController { - return Result.success(chunkUploadService.uploadChunk(uploadId, chunkIndex, chunk)); - } - -- @ApiOperation("分片上传-完成合并") -+ @ApiOperation(value = "分片上传-完成合并", notes = "大文件上传第三步:所有分片上传完成后调用,OSS端合并分片为完整文件并创建文件记录") - @PostMapping("/upload/chunk/complete") - public Result chunkUploadComplete( - @Valid @RequestBody ChunkUploadCompleteRequest request) { - return Result.success(chunkUploadService.completeChunkUpload(request.getUploadId())); - } - -- @ApiOperation("分片上传-取消") -+ @ApiOperation(value = "分片上传-取消", notes = "取消分片上传任务,清理已上传的分片数据和OSS临时文件") - @PostMapping("/upload/chunk/cancel") - public Result chunkUploadCancel( - @Valid @RequestBody ChunkUploadCancelRequest request) { -``` - -### `hl-file-service/src/main/java/com/hulalv/file/controller/MpFileController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-file-service/src/main/java/com/hulalv/file/controller/MpFileController.java b/hl-file-service/src/main/java/com/hulalv/file/controller/MpFileController.java -index b78e094..73b8a70 100644 ---- a/hl-file-service/src/main/java/com/hulalv/file/controller/MpFileController.java -+++ b/hl-file-service/src/main/java/com/hulalv/file/controller/MpFileController.java -@@ -23,7 +23,7 @@ public class MpFileController { - - private final FileService fileService; - -- @ApiOperation("上传文件(C端用户)") -+ @ApiOperation(value = "上传文件(C端用户)", notes = "小程序端直接上传文件,支持头像、评价图片等场景。groupKey决定存储路径和文件策略,默认为avatar") - @PostMapping("/upload") - public Result upload( - @ApiParam("上传文件") @RequestParam("file") MultipartFile file, -@@ -34,7 +34,8 @@ public class MpFileController { - return Result.success(vo); - } - -- @ApiOperation("文件内容流式预览") -+ @ApiOperation(value = "文件内容流式预览", -+ notes = "流式输出文件内容,设置正确的Content-Type头。用于小程序端通过web-view直接预览图片和PDF等文件。") - @GetMapping("/{fileId}/preview") - public void previewContent(@ApiParam("文件ID") @PathVariable Long fileId, HttpServletResponse response) throws IOException { - fileService.streamContent(fileId, response); -``` - -### `hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideArticleController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideArticleController.java b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideArticleController.java -index a96b208..10fe073 100644 ---- a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideArticleController.java -+++ b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideArticleController.java -@@ -22,19 +22,20 @@ public class AdminGuideArticleController { - - private final GuideArticleService articleService; - -- @ApiOperation("文章列表") -+ @ApiOperation(value = "文章列表", notes = "分页查询攻略文章,支持按分类、状态、关键词筛选\n\n**关联字典**:\n- wiki_status:文章状态(列表筛选+显示)") - @GetMapping("/list") - public Result> listArticles(@Valid ArticleQueryRequest query) { - return Result.success(articleService.listArticles(query)); - } - -- @ApiOperation("文章详情") -+ @ApiOperation(value = "文章详情", notes = "**关联字典**:\n- wiki_status:文章状态(显示)") - @GetMapping("/{articleId}") - public Result getArticle(@PathVariable Long articleId) { - return Result.success(articleService.getArticle(articleId)); - } - -- @ApiOperation("创建文章") -+ @ApiOperation(value = "创建文章", -+ notes = "创建攻略文章,需指定分类。创建后默认为草稿状态,需手动发布后小程序端才可见。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- wiki_status:文章状态(创建后默认DRAFT)") - @PostMapping - public Result createArticle( - @Valid @RequestBody ArticleCreateRequest request, -@@ -43,7 +44,8 @@ public class AdminGuideArticleController { - return Result.success(articleService.createArticle(request, adminId)); - } - -- @ApiOperation("更新文章") -+ @ApiOperation(value = "更新文章", -+ notes = "更新攻略文章的标题、内容、封面图、分类等信息。已发布的文章更新后立即生效。\n\n**权限**:需管理员登录。") - @PutMapping("/{articleId}") - public Result updateArticle( - @PathVariable Long articleId, -@@ -51,14 +53,15 @@ public class AdminGuideArticleController { - return Result.success(articleService.updateArticle(articleId, request)); - } - -- @ApiOperation("删除文章") -+ @ApiOperation(value = "删除文章", -+ notes = "软删除攻略文章,同时清除文章的标签关联。\n\n**权限**:需管理员登录。") - @DeleteMapping("/{articleId}") - public Result deleteArticle(@PathVariable Long articleId) { - articleService.deleteArticle(articleId); - return Result.success(); - } - -- @ApiOperation("发布/下架") -+ @ApiOperation(value = "发布/下架", notes = "切换文章发布状态。发布后小程序端可见,下架后小程序端不再展示但管理端仍可查看\n\n**关联字典**:\n- wiki_status:文章状态(状态切换)") - @PutMapping("/{articleId}/status") - public Result updateStatus( - @PathVariable Long articleId, -@@ -67,7 +70,7 @@ public class AdminGuideArticleController { - return Result.success(); - } - -- @ApiOperation("设置推荐") -+ @ApiOperation(value = "设置推荐", notes = "设置/取消文章推荐。推荐文章会在小程序首页和推荐列表中优先展示") - @PutMapping("/{articleId}/recommend") - public Result updateRecommend( - @PathVariable Long articleId, -@@ -76,7 +79,7 @@ public class AdminGuideArticleController { - return Result.success(); - } - -- @ApiOperation("设置置顶") -+ @ApiOperation(value = "设置置顶", notes = "设置/取消文章置顶。置顶文章在分类列表中始终排在最前面") - @PutMapping("/{articleId}/top") - public Result updateTop( - @PathVariable Long articleId, -``` - -### `hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideCategoryController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideCategoryController.java b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideCategoryController.java -index 8b849da..0eddd64 100644 ---- a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideCategoryController.java -+++ b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideCategoryController.java -@@ -24,19 +24,20 @@ public class AdminGuideCategoryController { - - private final GuideCategoryService categoryService; - -- @ApiOperation("分类列表") -+ @ApiOperation(value = "分类列表", notes = "返回全部攻略分类(含启用和停用),按排序值升序排列\n\n**关联字典**:\n- common_status:通用状态(列表显示,ACTIVE=启用/INACTIVE=停用)") - @GetMapping("/list") - public Result> listCategories() { - return Result.success(categoryService.listCategories()); - } - -- @ApiOperation("启用的分类列表") -+ @ApiOperation(value = "启用的分类列表", notes = "仅返回状态为启用的分类,创建文章时用于选择分类") - @GetMapping("/enabled") - public Result> listEnabledCategories() { - return Result.success(categoryService.listEnabledCategories()); - } - -- @ApiOperation("创建分类") -+ @ApiOperation(value = "创建分类", -+ notes = "创建攻略分类,分类名称不可重复。创建后默认启用,排序值越小越靠前。\n\n**权限**:需管理员登录。") - @PostMapping - public Result createCategory( - @Valid @RequestBody CategoryCreateRequest request, -@@ -45,7 +46,8 @@ public class AdminGuideCategoryController { - return Result.success(categoryService.createCategory(request, adminId)); - } - -- @ApiOperation("更新分类") -+ @ApiOperation(value = "更新分类", -+ notes = "更新攻略分类的名称、图标、描述等信息。\n\n**权限**:需管理员登录。") - @PutMapping("/{categoryId}") - public Result updateCategory( - @PathVariable Long categoryId, -@@ -53,14 +55,14 @@ public class AdminGuideCategoryController { - return Result.success(categoryService.updateCategory(categoryId, request)); - } - -- @ApiOperation("删除分类") -+ @ApiOperation(value = "删除分类", notes = "删除分类前需确保分类下无文章,否则删除失败") - @DeleteMapping("/{categoryId}") - public Result deleteCategory(@PathVariable Long categoryId) { - categoryService.deleteCategory(categoryId); - return Result.success(); - } - -- @ApiOperation("更新分类状态") -+ @ApiOperation(value = "更新分类状态", notes = "启用或停用分类。停用后该分类下的文章不会在小程序端展示,但不影响已有文章\n\n**关联字典**:\n- common_status:通用状态(状态切换,ACTIVE=启用/INACTIVE=停用)") - @PutMapping("/{categoryId}/status") - public Result updateStatus( - @PathVariable Long categoryId, -@@ -69,7 +71,8 @@ public class AdminGuideCategoryController { - return Result.success(); - } - -- @ApiOperation("更新分类排序") -+ @ApiOperation(value = "更新分类排序", -+ notes = "更新分类的排序值,排序值越小越靠前。影响小程序端分类导航的展示顺序。\n\n**权限**:需管理员登录。") - @PutMapping("/{categoryId}/sort") - public Result updateSort( - @PathVariable Long categoryId, -``` - -### `hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideTagController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideTagController.java b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideTagController.java -index acd32b1..d747ae4 100644 ---- a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideTagController.java -+++ b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideTagController.java -@@ -23,19 +23,20 @@ public class AdminGuideTagController { - - private final GuideTagService tagService; - -- @ApiOperation("系统标签列表") -+ @ApiOperation(value = "系统标签列表", notes = "返回管理员创建的系统标签(不含用户自定义标签),用于标签管理页") - @GetMapping("/managed") - public Result> listManagedTags() { - return Result.success(tagService.listManagedTags()); - } - -- @ApiOperation("所有标签列表") -+ @ApiOperation(value = "所有标签列表", notes = "返回全部标签(含系统标签和用户自定义标签),用于文章编辑时的标签选择器") - @GetMapping("/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建标签") -+ @ApiOperation(value = "创建标签", -+ notes = "创建攻略系统标签,标签名称不可重复。创建后可用于文章分类和筛选。\n\n**权限**:需管理员登录。") - @PostMapping - public Result createTag( - @Valid @RequestBody TagCreateRequest request, -@@ -44,7 +45,8 @@ public class AdminGuideTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("更新标签") -+ @ApiOperation(value = "更新标签", -+ notes = "更新标签名称。标签名称不可与其他已有标签重复。\n\n**权限**:需管理员登录。") - @PutMapping("/{tagId}") - public Result updateTag( - @PathVariable Long tagId, -@@ -52,14 +54,15 @@ public class AdminGuideTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", -+ notes = "删除标签并自动解除与所有文章的关联关系。\n\n**权限**:需管理员登录。") - @DeleteMapping("/{tagId}") - public Result deleteTag(@PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("更新文章标签") -+ @ApiOperation(value = "更新文章标签", notes = "全量替换文章的标签关联,传入新的标签ID列表(空数组表示清除所有标签)") - @PutMapping("/article/{articleId}") - public Result updateArticleTags( - @PathVariable Long articleId, -``` - -### `hl-guide-service/src/main/java/com/hulalv/guide/controller/InternalWikiController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-guide-service/src/main/java/com/hulalv/guide/controller/InternalWikiController.java b/hl-guide-service/src/main/java/com/hulalv/guide/controller/InternalWikiController.java -index 42c16dd..62838a6 100644 ---- a/hl-guide-service/src/main/java/com/hulalv/guide/controller/InternalWikiController.java -+++ b/hl-guide-service/src/main/java/com/hulalv/guide/controller/InternalWikiController.java -@@ -16,7 +16,7 @@ import java.util.Map; - /** - * 内部接口 - 供 mp-service Feign 调用 - */ --@Api(tags = "【内部接口】攻略百科(Feign调用)") -+@Api(tags = "【内部接口】攻略百科(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/wiki") - @RequiredArgsConstructor -@@ -25,13 +25,14 @@ public class InternalWikiController { - private final GuideCategoryService categoryService; - private final GuideArticleService articleService; - -- @ApiOperation("查询已启用的攻略分类列表") -+ @ApiOperation(value = "查询已启用的攻略分类列表", -+ notes = "内部服务间调用。返回所有状态为启用的攻略分类,供小程序端展示分类导航。\n\n**关联字典**:\n- common_status:通用状态(仅返回ACTIVE状态的分类)") - @GetMapping("/categories") - public Result> listEnabledCategories() { - return Result.success(categoryService.listEnabledCategories()); - } - -- @ApiOperation("分页查询指定分类下的已发布文章") -+ @ApiOperation(value = "分页查询指定分类下的已发布文章", notes = "**关联字典**:\n- wiki_status:文章状态(返回字段)") - @GetMapping("/category/{categoryId}/articles") - public Result>> listCategoryArticles( - @PathVariable Long categoryId, -@@ -40,13 +41,14 @@ public class InternalWikiController { - return Result.success(articleService.listPublishedArticlesByCategory(categoryId, page, pageSize)); - } - -- @ApiOperation("查询已发布文章详情") -+ @ApiOperation(value = "查询已发布文章详情", notes = "**关联字典**:\n- wiki_status:文章状态(返回字段)") - @GetMapping("/article/{articleId}") - public Result> getArticle(@PathVariable Long articleId) { - return Result.success(articleService.getPublishedArticle(articleId)); - } - -- @ApiOperation("查询推荐文章列表") -+ @ApiOperation(value = "查询推荐文章列表", -+ notes = "内部服务间调用。返回已发布且标记为推荐的文章列表,用于小程序首页推荐位展示。默认返回5条。") - @GetMapping("/recommend-articles") - public Result>> listRecommendArticles( - @RequestParam(defaultValue = "5") Integer limit) { -``` - -### `hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceController.java b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceController.java -index 852da1c..1505c2c 100644 ---- a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceController.java -+++ b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceController.java -@@ -48,7 +48,8 @@ public class AdminInsuranceController { - private final InsuranceEntityProperties entityProperties; - private final PolicyShareService policyShareService; - -- @ApiOperation("保险产品列表") -+ @ApiOperation(value = "保险产品列表", -+ notes = "分页查询已同步的保险产品,支持按是否境外筛选。产品数据来源于保游网同步。\n\n**权限**:需管理员登录。") - @GetMapping("/products") - public Result> listProducts( - @ApiParam("页码") @RequestParam(defaultValue = "1") Integer page, -@@ -57,26 +58,30 @@ public class AdminInsuranceController { - return Result.success(orderService.listProducts(page, pageSize, isOverseas)); - } - -- @ApiOperation("保险产品详情") -+ @ApiOperation(value = "保险产品详情", -+ notes = "返回保险产品完整信息,包含产品名称、保险公司、保障范围、适用地区等。\n\n**权限**:需管理员登录。") - @GetMapping("/products/{id}") - public Result getProduct(@ApiParam("保险产品ID") @PathVariable("id") Long productId) { - return Result.success(orderService.getProductDetail(productId)); - } - -- @ApiOperation("保险产品计划及费率") -+ @ApiOperation(value = "保险产品计划及费率", -+ notes = "返回指定保险产品的所有投保计划及对应费率表,包含不同天数区间的保费价格。投保下单前需选择具体计划。\n\n**权限**:需管理员登录。") - @GetMapping("/products/{id}/plans") - public Result> getProductPlans(@ApiParam("保险产品ID") @PathVariable("id") Long productId) { - return Result.success(orderService.getProductPlans(productId)); - } - -- @ApiOperation("从保游网同步产品数据") -+ @ApiOperation(value = "从保游网同步产品数据", -+ notes = "手动触发从保游网API拉取最新保险产品数据(含计划和费率),同步到本地数据库。返回同步的产品数量。\n\n**权限**:需管理员登录。") - @PostMapping("/sync-products") - public Result syncProducts() { - int count = syncService.syncAll(); - return Result.success(count); - } - -- @ApiOperation("投保公司主体列表") -+ @ApiOperation(value = "投保公司主体列表", -+ notes = "返回系统配置的投保公司主体列表(来自Nacos配置),投保下单时选择以哪个公司主体投保。每个主体包含编码、公司名称和商户ID。\n\n**权限**:需管理员登录。") - @GetMapping("/entities") - public Result>> listEntities() { - List> list = entityProperties.getList().stream().map(e -> { -@@ -91,7 +96,7 @@ public class AdminInsuranceController { - return Result.success(list); - } - -- @ApiOperation("投保下单(每人独立保单)") -+ @ApiOperation(value = "投保下单(每人独立保单)", notes = "**关联字典**:\n- gender:性别(被保人信息)\n- id_card_type:证件类型(被保人信息)") - @PostMapping("/purchase") - public Result> purchase( - @ApiParam("投保请求") @Valid @RequestBody PurchaseInsuranceRequest request, -@@ -100,43 +105,48 @@ public class AdminInsuranceController { - return Result.success(orderService.purchase(request, adminId)); - } - -- @ApiOperation("退保") -+ @ApiOperation(value = "退保", -+ notes = "对单个保险订单发起退保,调用保游网退保API。退保成功后保险状态变为CANCELLED。\n\n**权限**:需管理员登录。\n**注意**:已生效的保单退保可能产生手续费。\n\n**关联字典**:\n- insurance_status:保险状态(状态流转)") - @PostMapping("/cancel/{id}") - public Result cancel(@ApiParam("保险订单ID") @PathVariable("id") Long insuranceOrderId) { - return Result.success(orderService.cancel(insuranceOrderId)); - } - -- @ApiOperation("保险订单列表") -+ @ApiOperation(value = "保险订单列表", notes = "**关联字典**:\n- insurance_status:保险状态(列表筛选+显示)") - @GetMapping("/orders") - public Result> listOrders(@ApiParam("查询条件") InsuranceQueryRequest request) { - return Result.success(orderService.listOrders(request)); - } - -- @ApiOperation("保险订单详情(含被保人)") -+ @ApiOperation(value = "保险订单详情(含被保人)", notes = "**关联字典**:\n- insurance_status:保险状态(显示)\n- gender:性别(被保人信息显示)\n- id_card_type:证件类型(被保人信息显示)") - @GetMapping("/orders/{id}") - public Result getOrderDetail(@ApiParam("保险订单ID") @PathVariable("id") Long insuranceOrderId) { - return Result.success(orderService.getOrderDetail(insuranceOrderId)); - } - -- @ApiOperation("按旅行订单查询保险单") -+ @ApiOperation(value = "按旅行订单查询保险单", -+ notes = "根据旅行订单ID查询关联的所有保险订单列表。在订单详情页展示保险购买情况。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- insurance_status:保险状态(列表显示)") - @GetMapping("/orders/by-order/{orderId}") - public Result> getByOrder(@ApiParam("旅行订单ID") @PathVariable Long orderId) { - return Result.success(orderService.getByOrderId(orderId)); - } - -- @ApiOperation("查询订单保险保障(含被保人详情)") -+ @ApiOperation(value = "查询订单保险保障(含被保人详情)", -+ notes = "返回订单维度的保险保障汇总信息,包含覆盖人数、保障期间、每位被保人的保单明细。用于订单详情页的保险保障展示。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- insurance_status:保险状态(显示)\n- gender:性别(被保人信息显示)\n- id_card_type:证件类型(被保人信息显示)") - @GetMapping("/coverage/{orderId}") - public Result getCoverage(@ApiParam("旅行订单ID") @PathVariable Long orderId) { - return Result.success(orderService.getCoverageByOrderId(orderId)); - } - -- @ApiOperation("保费试算(本地费率)") -+ @ApiOperation(value = "保费试算(本地费率)", -+ notes = "根据保险计划、投保天数和人数,使用本地同步的费率表试算保费。不调用保游网API,用于投保前的费用预估。\n\n**权限**:需管理员登录。") - @PostMapping("/trial-price") - public Result> trialPrice(@ApiParam("试算请求") @Valid @RequestBody TrialPriceRequest request) { - return Result.success(orderService.trialPrice(request)); - } - -- @ApiOperation("查询保游网账户余额") -+ @ApiOperation(value = "查询保游网账户余额", -+ notes = "查询保游网平台的账户余额,用于管理端展示当前可用投保额度。查询失败时返回null(非关键信息,不影响业务)。\n\n**权限**:需管理员登录。") - @GetMapping("/balance") - public Result getBalance() { - try { -@@ -152,13 +162,15 @@ public class AdminInsuranceController { - return Result.success(null); - } - -- @ApiOperation("下载保单PDF(Base64)") -+ @ApiOperation(value = "下载保单PDF(Base64)", -+ notes = "从保游网下载指定保险订单的电子保单PDF,以Base64编码返回。前端可解码后展示或提供下载。\n\n**权限**:需管理员登录。") - @GetMapping("/policy/{id}/download") - public Result downloadPolicy(@ApiParam("保险订单ID") @PathVariable("id") Long insuranceOrderId) { - return Result.success(orderService.downloadPolicy(insuranceOrderId)); - } - -- @ApiOperation("获取保游网充值链接(旧接口,保留兼容)") -+ @ApiOperation(value = "获取保游网充值链接(旧接口,保留兼容)", -+ notes = "返回保游网平台的充值页面URL。此为旧版接口,保留用于向后兼容,推荐使用在线充值接口。\n\n**权限**:需管理员登录。") - @GetMapping("/recharge-url") - public Result getRechargeUrl() { - String url = baoyouProperties.getRechargeUrl(); -@@ -168,13 +180,15 @@ public class AdminInsuranceController { - return Result.success(url); - } - -- @ApiOperation("在线充值(调用保游网支付API)") -+ @ApiOperation(value = "在线充值(调用保游网支付API)", -+ notes = "调用保游网在线充值API,生成充值支付链接。支持选择支付方式(支付宝/微信),充值完成后账户余额自动更新。\n\n**权限**:需管理员登录。") - @PostMapping("/recharge") - public Result> recharge(@ApiParam("充值请求") @Valid @RequestBody RechargeRequest request) { - return Result.success(orderService.recharge(request.getMoney(), request.getPayType(), request.getBackUrl())); - } - -- @ApiOperation("分享保单(合并某出行人所有有效保单PDF,上传OSS返回链接)") -+ @ApiOperation(value = "分享保单(合并某出行人所有有效保单PDF,上传OSS返回链接)", -+ notes = "合并指定出行人的所有有效保单PDF为一个文件,上传至OSS后返回公开访问链接。用于管理端分享保单给出行人。\n\n**权限**:需管理员登录。") - @PostMapping("/share-policy") - public Result sharePolicy( - @ApiParam("分享保单请求") @Valid @RequestBody SharePolicyRequest request) { -``` - -### `hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceSchemeController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceSchemeController.java b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceSchemeController.java -index 9497720..04db6d6 100644 ---- a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceSchemeController.java -+++ b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceSchemeController.java -@@ -24,26 +24,30 @@ public class AdminInsuranceSchemeController { - - private final InsuranceSchemeService schemeService; - -- @ApiOperation("活跃方案列表(下拉选择用)") -+ @ApiOperation(value = "活跃方案列表(下拉选择用)", -+ notes = "返回所有状态为启用的保险方案模板,用于投保下单时的方案下拉选择。\n\n**权限**:需管理员登录。") - @GetMapping("/list") - public Result> listActiveSchemes() { - return Result.success(schemeService.listActiveSchemes()); - } - -- @ApiOperation("全部方案列表(管理用)") -+ @ApiOperation(value = "全部方案列表(管理用)", -+ notes = "返回所有保险方案模板(含启用和停用),用于方案管理页面展示和编辑。\n\n**权限**:需管理员登录。") - @GetMapping("/list-all") - public Result> listAllSchemes() { - return Result.success(schemeService.listAllSchemes()); - } - -- @ApiOperation("方案详情") -+ @ApiOperation(value = "方案详情", -+ notes = "返回单个保险方案模板的完整信息,包含方案名称、保险产品关联、天数规则、费率配置等。\n\n**权限**:需管理员登录。") - @GetMapping("/{id}") - public Result getSchemeDetail( - @ApiParam("方案ID") @PathVariable("id") Long schemeId) { - return Result.success(schemeService.getSchemeDetail(schemeId)); - } - -- @ApiOperation("创建方案") -+ @ApiOperation(value = "创建方案", -+ notes = "创建保险方案模板,配置关联保险产品、投保天数规则和费率。创建后默认启用。\n\n**权限**:需管理员登录。") - @PostMapping - public Result createScheme( - @ApiParam("方案请求") @Valid @RequestBody InsuranceSchemeRequest request, -@@ -52,7 +56,8 @@ public class AdminInsuranceSchemeController { - return Result.success(schemeService.createScheme(request, adminId)); - } - -- @ApiOperation("更新方案") -+ @ApiOperation(value = "更新方案", -+ notes = "更新保险方案模板的配置信息,包括方案名称、关联产品、天数规则、费率等。\n\n**权限**:需管理员登录。") - @PutMapping("/{id}") - public Result updateScheme( - @ApiParam("方案ID") @PathVariable("id") Long schemeId, -@@ -62,14 +67,16 @@ public class AdminInsuranceSchemeController { - return Result.success(schemeService.updateScheme(schemeId, request, adminId)); - } - -- @ApiOperation("切换方案状态(启用/停用)") -+ @ApiOperation(value = "切换方案状态(启用/停用)", -+ notes = "切换保险方案模板的启用/停用状态。停用后不会出现在投保下单的方案选择列表中。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- common_status:通用状态(ACTIVE=启用/INACTIVE=停用)") - @PutMapping("/{id}/toggle-status") - public Result toggleStatus( - @ApiParam("方案ID") @PathVariable("id") Long schemeId) { - return Result.success(schemeService.toggleStatus(schemeId)); - } - -- @ApiOperation("删除方案(软删除)") -+ @ApiOperation(value = "删除方案(软删除)", -+ notes = "软删除保险方案模板。已使用该方案创建的保险订单不受影响。\n\n**权限**:需管理员登录。") - @DeleteMapping("/{id}") - public Result deleteScheme( - @ApiParam("方案ID") @PathVariable("id") Long schemeId) { -@@ -77,7 +84,8 @@ public class AdminInsuranceSchemeController { - return Result.success(null); - } - -- @ApiOperation("预览应用方案(解析日期+估算保费)") -+ @ApiOperation(value = "预览应用方案(解析日期+估算保费)", -+ notes = "根据方案模板和行程日期预览投保效果:解析实际投保起止日期、计算每人保费和总保费。用于投保前确认费用。\n\n**权限**:需管理员登录。") - @PostMapping("/preview-apply") - public Result previewApply( - @ApiParam("预览请求") @Valid @RequestBody ApplySchemeRequest request) { -``` - -### `hl-insurance-service/src/main/java/com/hulalv/insurance/controller/InternalInsuranceController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/InternalInsuranceController.java b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/InternalInsuranceController.java -index 828cc04..d77d99e 100644 ---- a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/InternalInsuranceController.java -+++ b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/InternalInsuranceController.java -@@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "【内部接口】保险(Feign调用)") -+@Api(tags = "【内部接口】保险(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/insurance") - @RequiredArgsConstructor -@@ -26,19 +26,22 @@ public class InternalInsuranceController { - private final InsuranceProductSyncService syncService; - private final PolicyShareService policyShareService; - -- @ApiOperation("按旅行订单查询保险单(内部调用)") -+ @ApiOperation(value = "按旅行订单查询保险单(内部调用)", -+ notes = "内部服务间调用。根据旅行订单ID查询关联的所有保险订单,返回保险状态、保费、保障期间等信息。\n\n**关联字典**:\n- insurance_status:保险状态(返回字段)") - @GetMapping("/by-order/{orderId}") - public Result> getByOrder(@ApiParam("旅行订单ID") @PathVariable Long orderId) { - return Result.success(orderService.getByOrderId(orderId)); - } - -- @ApiOperation("按订单批量查询保险单(内部调用)") -+ @ApiOperation(value = "按订单批量查询保险单(内部调用)", -+ notes = "内部服务间调用。批量查询多个旅行订单的保险订单,返回Map结构(key=订单ID,value=保险单列表),用于订单列表页展示保险状态。") - @PostMapping("/by-orders") - public Result>> getByOrders(@RequestBody List orderIds) { - return Result.success(orderService.getByOrderIds(orderIds)); - } - -- @ApiOperation("检查保险是否全覆盖(内部调用)") -+ @ApiOperation(value = "检查保险是否全覆盖(内部调用)", -+ notes = "内部服务间调用。根据出行人数和行程天数计算所需的人日数,与已投保的有效保单覆盖人日数对比,判断保险是否已全覆盖。") - @GetMapping("/coverage-complete/{orderId}") - public Result isCoverageComplete( - @ApiParam("旅行订单ID") @PathVariable Long orderId, -@@ -57,7 +60,8 @@ public class InternalInsuranceController { - return Result.success(coveredPersonDays >= requiredPersonDays); - } - -- @ApiOperation("按订单批量退保(级联失效调用)") -+ @ApiOperation(value = "按订单批量退保(级联失效调用)", -+ notes = "内部服务间调用。旅行订单取消或退款时级联调用,将该订单下所有有效保险单批量退保(调用保游网退保API),记录退保原因。") - @PostMapping("/invalidate/{orderId}") - public Result invalidateInsurance( - @ApiParam("旅行订单ID") @PathVariable Long orderId, -@@ -66,19 +70,22 @@ public class InternalInsuranceController { - return Result.success(null); - } - -- @ApiOperation("分享保单PDF(内部调用,返回base64)") -+ @ApiOperation(value = "分享保单PDF(内部调用,返回base64)", -+ notes = "内部服务间调用。合并指定出行人的所有有效保单PDF为一个文件,上传至OSS后返回下载链接和Base64内容,用于小程序端分享保单。") - @PostMapping("/share-policy") - public Result sharePolicy(@RequestBody SharePolicyRequest request) { - return Result.success(policyShareService.sharePolicy(request)); - } - -- @ApiOperation("按订单获取所有保单PDF(内部调用,合并所有出行人)") -+ @ApiOperation(value = "按订单获取所有保单PDF(内部调用,合并所有出行人)", -+ notes = "内部服务间调用。将指定订单下所有出行人的有效保单PDF合并为一个文件,上传至OSS后返回下载链接,用于订单维度的保单查看。") - @GetMapping("/share-policy-by-order/{orderId}") - public Result sharePolicyByOrder(@PathVariable Long orderId) { - return Result.success(policyShareService.sharePolicyByOrder(orderId)); - } - -- @ApiOperation("触发保险产品同步(内部调用/定时任务)") -+ @ApiOperation(value = "触发保险产品同步(内部调用/定时任务)", -+ notes = "内部服务间调用。从保游网API拉取最新保险产品数据(含计划和费率),同步到本地数据库。返回同步的产品数量。") - @PostMapping("/sync-products") - public Result syncProducts() { - int count = syncService.syncAll(); -``` - -### `hl-material-service/src/main/java/com/hulalv/material/controller/InternalMaterialController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/controller/InternalMaterialController.java b/hl-material-service/src/main/java/com/hulalv/material/controller/InternalMaterialController.java -index 08122a4..686a577 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/controller/InternalMaterialController.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/controller/InternalMaterialController.java -@@ -22,7 +22,7 @@ import java.util.List; - * Internal endpoints for Feign calls from other services (scenic, hotel, etc.). - * Not exposed through gateway. - */ --@Api(tags = "素材内部接口(Feign调用)") -+@Api(tags = "素材内部接口(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/material") - @RequiredArgsConstructor -@@ -31,7 +31,7 @@ public class InternalMaterialController { - private final MaterialRefService refService; - private final MaterialService materialService; - -- @ApiOperation("绑定引用") -+ @ApiOperation(value = "绑定引用", notes = "将素材与业务实体建立引用关系(如景区ID+封面图),记录引用类型(COVER/GALLERY/DETAIL等)") - @PostMapping("/ref/bind") - public Result bindRef( - @Valid @RequestBody RefBindRequest request, -@@ -40,7 +40,7 @@ public class InternalMaterialController { - return Result.success(); - } - -- @ApiOperation("批量绑定引用") -+ @ApiOperation(value = "批量绑定引用", notes = "批量建立素材与业务实体的引用关系,常用于保存包含多张图片的业务数据") - @PostMapping("/ref/batch-bind") - public Result batchBindRefs( - @Valid @RequestBody RefBatchBindRequest request, -@@ -49,7 +49,7 @@ public class InternalMaterialController { - return Result.success(); - } - -- @ApiOperation("解绑引用") -+ @ApiOperation(value = "解绑引用", notes = "删除单个素材与业务实体的引用关系") - @DeleteMapping("/ref/unbind") - public Result unbindRef(@Valid @RequestBody RefUnbindRequest request) { - refService.unbindRef(request.getMaterialId(), request.getBizType(), -@@ -57,14 +57,15 @@ public class InternalMaterialController { - return Result.success(); - } - -- @ApiOperation("批量解绑引用") -+ @ApiOperation(value = "批量解绑引用", notes = "批量删除素材引用关系,常用于业务实体更新时先清除旧引用再绑定新引用") - @DeleteMapping("/ref/batch-unbind") - public Result batchUnbindRefs(@Valid @RequestBody RefBatchUnbindRequest request) { - refService.batchUnbindRefs(request.getRefs()); - return Result.success(); - } - -- @ApiOperation("批量查询素材信息") -+ @ApiOperation(value = "批量查询素材信息", -+ notes = "内部服务间调用。根据素材ID列表批量查询素材信息,用于其他服务获取素材详情(如产品、景区等关联的素材数据)。") - @PostMapping("/by-ids") - public Result> getMaterialsByIds(@Valid @RequestBody BatchMaterialIdsRequest request) { - return Result.success(materialService.getMaterialsByIds(request.getMaterialIds())); -``` - -### `hl-material-service/src/main/java/com/hulalv/material/controller/MaterialCategoryPermissionController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialCategoryPermissionController.java b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialCategoryPermissionController.java -index 03566eb..77fa5a6 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialCategoryPermissionController.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialCategoryPermissionController.java -@@ -23,7 +23,7 @@ public class MaterialCategoryPermissionController { - - private final MaterialCategoryPermissionService permissionService; - -- @ApiOperation("获取角色的分类权限") -+ @ApiOperation(value = "获取角色的分类权限", notes = "仅超级管理员可操作。返回指定角色可访问的素材分类编码列表") - @GetMapping("/{roleCode}") - public Result> getPermissions( - @ApiParam("角色编码") @PathVariable String roleCode, -@@ -32,7 +32,7 @@ public class MaterialCategoryPermissionController { - return Result.success(permissionService.getPermissionsByRoleCode(roleCode)); - } - -- @ApiOperation("更新角色的分类权限") -+ @ApiOperation(value = "更新角色的分类权限", notes = "仅超级管理员可操作。全量替换指定角色的素材分类访问权限,传入允许访问的分类编码列表") - @PutMapping("/{roleCode}") - public Result updatePermissions( - @ApiParam("角色编码") @PathVariable String roleCode, -``` - -### `hl-material-service/src/main/java/com/hulalv/material/controller/MaterialController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialController.java b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialController.java -index 0fa7c7e..d79def9 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialController.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialController.java -@@ -47,7 +47,7 @@ public class MaterialController { - - // ==================== Upload ==================== - -- @ApiOperation("获取上传凭证") -+ @ApiOperation(value = "获取上传凭证", notes = "上传素材第一步:获取OSS预签名URL和凭证。前端使用凭证直传OSS后调用确认上传。支持基于角色的分类权限校验") - @PostMapping("/upload/token") - public Result requestUploadToken( - @ApiParam("上传凭证请求") @Valid @RequestBody MaterialUploadTokenRequest request, -@@ -57,7 +57,7 @@ public class MaterialController { - return Result.success(materialService.requestUploadToken(request, adminId, role)); - } - -- @ApiOperation("确认上传完成") -+ @ApiOperation(value = "确认上传完成", notes = "上传素材第二步:前端直传OSS完成后调用此接口创建素材记录,支持MD5去重\n\n**关联字典**:\n- material_tag:素材标签(上传时可选标签)") - @PostMapping("/upload/confirm") - public Result confirmUpload( - @ApiParam("确认上传请求") @Valid @RequestBody MaterialUploadConfirmRequest request, -@@ -66,7 +66,7 @@ public class MaterialController { - return Result.success(materialService.confirmUpload(request, adminId)); - } - -- @ApiOperation("文件夹上传初始化(创建分类+批量获取凭证)") -+ @ApiOperation(value = "文件夹上传初始化(创建分类+批量获取凭证)", notes = "支持整个文件夹上传:自动根据文件夹名创建子分类,为每个文件批量获取上传凭证,前端逐一上传后批量确认") - @PostMapping("/upload/folder") - public Result folderUploadInit( - @ApiParam("文件夹上传初始化请求") @Valid @RequestBody FolderUploadInitRequest request, -@@ -79,7 +79,8 @@ public class MaterialController { - - // ==================== Chunk Upload (分片上传) ==================== - -- @ApiOperation("分片上传-初始化") -+ @ApiOperation(value = "分片上传-初始化", -+ notes = "大文件上传第一步:初始化分片上传任务,返回uploadId和每个分片的预签名URL。前端按分片并发上传后调用完成合并接口。\n\n**权限**:需管理员登录,受角色分类权限限制。") - @PostMapping("/upload/chunk/init") - public Result chunkUploadInit( - @ApiParam("分片上传初始化请求") @Valid @RequestBody ChunkUploadInitRequest request, -@@ -89,7 +90,8 @@ public class MaterialController { - return Result.success(chunkUploadService.initChunkUpload(request, adminId, role)); - } - -- @ApiOperation("分片上传-上传分片") -+ @ApiOperation(value = "分片上传-上传分片", -+ notes = "大文件上传第二步:逐个上传分片数据,分片索引从0开始。支持断点续传,已上传的分片无需重传。") - @PostMapping("/upload/chunk") - public Result chunkUploadPart( - @ApiParam("上传ID") @RequestParam("uploadId") String uploadId, -@@ -99,7 +101,8 @@ public class MaterialController { - return Result.success(chunkUploadService.uploadChunk(uploadId, chunkIndex, chunk)); - } - -- @ApiOperation("分片上传-完成合并") -+ @ApiOperation(value = "分片上传-完成合并", -+ notes = "大文件上传第三步:所有分片上传完成后调用,OSS端合并分片为完整文件并创建素材记录。") - @PostMapping("/upload/chunk/complete") - public Result chunkUploadComplete( - @ApiParam("分片上传完成请求") @Valid @RequestBody ChunkUploadCompleteRequest request, -@@ -108,7 +111,8 @@ public class MaterialController { - return Result.success(chunkUploadService.completeChunkUpload(request.getUploadId(), adminId)); - } - -- @ApiOperation("分片上传-取消") -+ @ApiOperation(value = "分片上传-取消", -+ notes = "取消分片上传任务,清理已上传的分片数据和OSS临时文件。仅上传发起者可取消。") - @PostMapping("/upload/chunk/cancel") - public Result chunkUploadCancel( - @ApiParam("分片上传取消请求") @Valid @RequestBody ChunkUploadCancelRequest request, -@@ -120,7 +124,7 @@ public class MaterialController { - - // ==================== CRUD ==================== - -- @ApiOperation("素材列表") -+ @ApiOperation(value = "素材列表", notes = "分页查询素材,支持按分类、标签、文件类型、关键词筛选。返回结果受角色分类权限限制\n\n**关联字典**:\n- file_type:文件类型(列表筛选+显示)") - @GetMapping("/list") - public Result> listMaterials( - @ApiParam("素材查询条件") @Valid MaterialQueryRequest query, -@@ -131,7 +135,8 @@ public class MaterialController { - return Result.success(materialService.listMaterials(query, adminId, role, categoryMap)); - } - -- @ApiOperation("素材详情") -+ @ApiOperation(value = "素材详情", -+ notes = "返回素材完整信息,包含文件名、URL、分类、标签、文件大小、上传者等。受角色分类权限限制。\n\n**关联字典**:\n- file_type:文件类型(显示)") - @GetMapping("/{materialId}") - public Result getMaterial( - @ApiParam("素材ID") @PathVariable Long materialId, -@@ -141,7 +146,7 @@ public class MaterialController { - return Result.success(materialService.getMaterial(materialId, role, categoryMap)); - } - -- @ApiOperation("更新素材信息") -+ @ApiOperation(value = "更新素材信息", notes = "**关联字典**:\n- material_tag:素材标签(编辑时选择标签)") - @PutMapping("/{materialId}") - public Result updateMaterial( - @ApiParam("素材ID") @PathVariable Long materialId, -@@ -153,7 +158,7 @@ public class MaterialController { - return Result.success(materialService.updateMaterial(materialId, request, adminId, role, categoryMap)); - } - -- @ApiOperation("删除素材") -+ @ApiOperation(value = "删除素材", notes = "删除素材记录。如果素材存在引用关系(被景区、酒店等使用),则不允许删除") - @DeleteMapping("/{materialId}") - public Result deleteMaterial( - @ApiParam("素材ID") @PathVariable Long materialId, -@@ -164,7 +169,7 @@ public class MaterialController { - return Result.success(); - } - -- @ApiOperation("批量删除素材") -+ @ApiOperation(value = "批量删除素材", notes = "批量删除素材,返回删除结果(成功数/失败数/失败原因)。有引用关系的素材会跳过并记录失败原因") - @DeleteMapping("/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -@@ -179,7 +184,7 @@ public class MaterialController { - - // ==================== Tags on Materials ==================== - -- @ApiOperation("更新素材标签") -+ @ApiOperation(value = "更新素材标签", notes = "全量替换单个素材的标签,传入新的标签ID列表") - @PutMapping("/{materialId}/tags") - public Result updateMaterialTags( - @ApiParam("素材ID") @PathVariable Long materialId, -@@ -192,7 +197,7 @@ public class MaterialController { - return Result.success(); - } - -- @ApiOperation("批量更新标签") -+ @ApiOperation(value = "批量更新标签", notes = "对多个素材同时添加和/或移除标签,支持增量操作(addTagIds新增,removeTagIds移除)") - @PutMapping("/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签更新请求") @Valid @RequestBody BatchTagRequest request, -@@ -212,7 +217,7 @@ public class MaterialController { - - // ==================== References ==================== - -- @ApiOperation("查看素材引用记录") -+ @ApiOperation(value = "查看素材引用记录", notes = "查看素材被哪些业务实体引用(如景区封面、酒店轮播图等),用于判断素材是否可安全删除") - @GetMapping("/{materialId}/refs") - public Result> getMaterialRefs(@ApiParam("素材ID") @PathVariable Long materialId) { - return Result.success(refService.getRefsByMaterialId(materialId)); -@@ -220,7 +225,7 @@ public class MaterialController { - - // ==================== Categories ==================== - -- @ApiOperation("获取有权限的分类列表(含素材数量)") -+ @ApiOperation(value = "获取有权限的分类列表(含素材数量)", notes = "返回当前角色有权限查看的素材分类树,每个分类包含素材数量统计。超级管理员可见全部分类") - @GetMapping("/categories") - public Result> getCategories(HttpServletRequest httpRequest) { - String role = getRole(httpRequest); -@@ -230,7 +235,7 @@ public class MaterialController { - - // ==================== Sub-categories ==================== - -- @ApiOperation("创建子分类") -+ @ApiOperation(value = "创建子分类", notes = "在一级分类下创建子分类,分类编码自动生成。子分类用于更细粒度的素材归档") - @PostMapping("/category/sub") - public Result createSubCategory( - @ApiParam("子分类创建请求") @Valid @RequestBody SubCategoryCreateRequest request, -@@ -241,7 +246,8 @@ public class MaterialController { - return Result.success(categoryService.createSubCategory(request, adminId, role, categoryMap)); - } - -- @ApiOperation("更新子分类") -+ @ApiOperation(value = "更新子分类", -+ notes = "更新子分类的名称或排序值。仅有该分类权限的管理员可操作。") - @PutMapping("/category/sub/{categoryId}") - public Result updateSubCategory( - @ApiParam("子分类ID") @PathVariable Long categoryId, -@@ -252,7 +258,7 @@ public class MaterialController { - return Result.success(categoryService.updateSubCategory(categoryId, request, adminId, role)); - } - -- @ApiOperation("删除子分类") -+ @ApiOperation(value = "删除子分类", notes = "删除子分类前需确保分类下无素材,否则删除失败") - @DeleteMapping("/category/sub/{categoryId}") - public Result deleteSubCategory( - @ApiParam("子分类ID") @PathVariable Long categoryId, -``` - -### `hl-material-service/src/main/java/com/hulalv/material/controller/MaterialTagController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialTagController.java b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialTagController.java -index a90884f..31d53b5 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialTagController.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialTagController.java -@@ -23,19 +23,22 @@ public class MaterialTagController { - - private final MaterialTagService tagService; - -- @ApiOperation("获取管理标签(标签管理用)") -+ @ApiOperation(value = "获取管理标签(标签管理用)", -+ notes = "返回管理员创建的系统标签列表(不含用户自定义标签),用于标签管理页的CRUD操作。") - @GetMapping("/tags") - public Result> listManagedTags() { - return Result.success(tagService.listManagedTags()); - } - -- @ApiOperation("获取全部标签(选择器用,含自定义标签)") -+ @ApiOperation(value = "获取全部标签(选择器用,含自定义标签)", -+ notes = "返回所有标签(含系统标签和用户自定义标签),用于素材上传/编辑时的标签选择器。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建管理标签") -+ @ApiOperation(value = "创建管理标签", -+ notes = "创建系统级素材标签,标签名称不可重复。创建后可用于素材分类和筛选。\n\n**权限**:需管理员登录。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("创建标签请求") @Valid @RequestBody TagCreateRequest request, -@@ -44,7 +47,8 @@ public class MaterialTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签(按名称查找或创建)") -+ @ApiOperation(value = "解析自定义标签(按名称查找或创建)", -+ notes = "按标签名称查找已有标签,不存在则自动创建为用户自定义标签。用于素材上传时输入自由标签文本的场景。\n\n**权限**:需管理员登录。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("自定义标签请求") @RequestBody TagCreateRequest request, -@@ -53,7 +57,8 @@ public class MaterialTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("编辑标签") -+ @ApiOperation(value = "编辑标签", -+ notes = "更新标签名称。标签名称不可与其他已有标签重复。\n\n**权限**:需管理员登录。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -61,7 +66,8 @@ public class MaterialTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", -+ notes = "删除标签并自动解除与所有素材的关联关系。\n\n**权限**:需管理员登录。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); -``` - -### `hl-material-service/src/main/java/com/hulalv/material/controller/MpMaterialController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/controller/MpMaterialController.java b/hl-material-service/src/main/java/com/hulalv/material/controller/MpMaterialController.java -index a595577..17f64ac 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/controller/MpMaterialController.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/controller/MpMaterialController.java -@@ -20,7 +20,7 @@ public class MpMaterialController { - - private final MaterialService materialService; - -- @ApiOperation("获取小程序分类下的全部素材") -+ @ApiOperation(value = "获取小程序分类下的全部素材", notes = "返回miniprogram分类下的所有素材,用于小程序端展示公共素材资源(如引导页图片、默认头像等)") - @GetMapping("/miniprogram") - public Result> listMiniprogramMaterials() { - return Result.success(materialService.listMaterialsByCategoryCode("miniprogram")); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ApprovalLogController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ApprovalLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ApprovalLogController.java -index 6c26fc1..04d1ebd 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ApprovalLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ApprovalLogController.java -@@ -19,7 +19,7 @@ public class ApprovalLogController { - - private final ApprovalLogService approvalLogService; - -- @ApiOperation("审批日志分页查询") -+ @ApiOperation(value = "审批日志分页查询", notes = "查询企微OA审批流程记录,支持按审批状态(1-审批中/2-已通过/3-已驳回/4-已撤销)、申请人、模板名称筛选\n\n**关联字典**:\n- approval_sp_status:审批状态(列表筛选+显示)") - @GetMapping - public Result> list( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -32,7 +32,7 @@ public class ApprovalLogController { - return Result.success(approvalLogService.queryPage(page, pageSize, spStatus, applyUserName, spName, startTime, endTime)); - } - -- @ApiOperation("审批日志详情") -+ @ApiOperation(value = "审批日志详情", notes = "**关联字典**:\n- approval_sp_status:审批状态(显示)") - @GetMapping("/{id}") - public Result detail(@ApiParam("日志ID") @PathVariable Long id) { - ApprovalLog approvalLog = approvalLogService.getById(id); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/DataRetentionController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/DataRetentionController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/DataRetentionController.java -index 43d56d8..12117da 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/DataRetentionController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/DataRetentionController.java -@@ -19,7 +19,7 @@ public class DataRetentionController { - - private final DataRetentionService dataRetentionService; - -- @ApiOperation("手动触发数据清理") -+ @ApiOperation(value = "手动触发数据清理", notes = "仅超级管理员可操作。按数据保留策略清理过期日志(操作日志/错误日志/通知日志等),返回各类型清理的记录数") - @PostMapping("/cleanup") - public Result> cleanup(HttpServletRequest request) { - requireSuperAdmin(request); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ErrorLogController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ErrorLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ErrorLogController.java -index 77046be..06bbdf5 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ErrorLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ErrorLogController.java -@@ -19,7 +19,7 @@ public class ErrorLogController { - - private final ErrorLogService errorLogService; - -- @ApiOperation("错误日志分页查询") -+ @ApiOperation(value = "错误日志分页查询", notes = "查询各微服务的异常记录,支持按服务名称、异常类名、时间范围筛选。堆栈信息仅保留com.hulalv包内的调用帧") - @GetMapping - public Result> list( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -31,7 +31,8 @@ public class ErrorLogController { - return Result.success(errorLogService.queryPage(page, pageSize, serviceName, exceptionClass, startTime, endTime)); - } - -- @ApiOperation("错误日志详情") -+ @ApiOperation(value = "错误日志详情", -+ notes = "返回单条错误日志的完整信息,包含异常类名、错误消息、过滤后的堆栈信息(仅com.hulalv包内调用帧)、请求URL、请求参数等。") - @GetMapping("/{id}") - public Result detail(@ApiParam("日志ID") @PathVariable Long id) { - ErrorLog errorLog = errorLogService.getById(id); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/InternalLogController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/InternalLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/InternalLogController.java -index 51e3999..44d463e 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/InternalLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/InternalLogController.java -@@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.*; - * Internal endpoints for receiving logs from other services. - * NOT exposed via gateway. - */ --@Api(tags = "【内部接口】日志接收(Feign调用)") -+@Api(tags = "【内部接口】日志接收(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/monitor") - @RequiredArgsConstructor -@@ -29,35 +29,35 @@ public class InternalLogController { - private final NotificationLogService notificationLogService; - private final ApprovalLogService approvalLogService; - -- @ApiOperation("Receive operation log") -+ @ApiOperation(value = "接收操作日志", notes = "各微服务通过AOP拦截@OperationLog注解的方法,异步发送操作日志到此接口存储") - @PostMapping("/operation-log") -- public Result receiveOperationLog(@RequestBody OperationLogDTO dto) { -+ public Result receiveOperationLog(@RequestBody OperationLogDTO dto) { - operationLogService.saveFromDTO(dto); - return Result.success(); - } - -- @ApiOperation("Receive error log") -+ @ApiOperation(value = "接收错误日志", notes = "各微服务的GlobalExceptionHandler捕获异常后,异步发送错误日志到此接口存储") - @PostMapping("/error-log") -- public Result receiveErrorLog(@RequestBody ErrorLogDTO dto) { -+ public Result receiveErrorLog(@RequestBody ErrorLogDTO dto) { - errorLogService.saveFromDTO(dto); - return Result.success(); - } - -- @ApiOperation("Receive notification log") -+ @ApiOperation(value = "接收通知日志", notes = "通知服务发送消息(短信/站内信/企微等)后,记录发送结果到此接口") - @PostMapping("/notification-log") -- public Result receiveNotificationLog(@RequestBody NotificationLogDTO dto) { -+ public Result receiveNotificationLog(@RequestBody NotificationLogDTO dto) { - notificationLogService.saveFromDTO(dto); - return Result.success(); - } - -- @ApiOperation("Receive approval log") -+ @ApiOperation(value = "接收审批日志", notes = "企微回调服务接收审批事件后,发送审批日志到此接口。同一审批单号会更新已有记录(按thirdNo去重)") - @PostMapping("/approval-log") -- public Result receiveApprovalLog(@RequestBody ApprovalLogDTO dto) { -+ public Result receiveApprovalLog(@RequestBody ApprovalLogDTO dto) { - approvalLogService.saveOrUpdateByThirdNo(dto); - return Result.success(); - } - -- @ApiOperation("Get customer stats for a user (add/loss counts)") -+ @ApiOperation(value = "获取用户客户统计", notes = "统计指定用户的客户增减数据(新增客户数/流失客户数),用于客户管理看板") - @GetMapping("/notification-log/customer-stats") - public Result> getCustomerStats( - @RequestParam("userId") String userId) { -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/LoginLogController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/LoginLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/LoginLogController.java -index 52c9e86..bc58580 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/LoginLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/LoginLogController.java -@@ -19,7 +19,7 @@ public class LoginLogController { - - private final UserServiceClient userServiceClient; - -- @ApiOperation("登录日志分页查询") -+ @ApiOperation(value = "登录日志分页查询", notes = "查询管理员登录记录(代理到user-service),包含登录IP、设备信息、登录方式和登录结果\n\n**关联字典**:\n- login_status:登录状态(列表筛选+显示)") - @GetMapping - public Result list( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/MysqlMonitorController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/MysqlMonitorController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/MysqlMonitorController.java -index 029e317..0d29b88 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/MysqlMonitorController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/MysqlMonitorController.java -@@ -21,20 +21,20 @@ public class MysqlMonitorController { - - private final MysqlMonitorService mysqlMonitorService; - -- @ApiOperation("MySQL实时监控数据") -+ @ApiOperation(value = "MySQL实时监控数据", notes = "返回MySQL实时状态:连接数、QPS、缓冲池命中率、线程状态、慢查询计数等核心指标") - @GetMapping - public Result> overview() { - return Result.success(mysqlMonitorService.getOverview()); - } - -- @ApiOperation("表空间列表") -+ @ApiOperation(value = "表空间列表", notes = "查询各数据库表的空间占用情况,包含数据大小、索引大小、行数等信息。可指定schema筛选,仅允许查询hl_前缀的数据库") - @GetMapping("/tables") - public Result>> tables( - @ApiParam("数据库名") @RequestParam(required = false) String schema) { - return Result.success(mysqlMonitorService.getTableSpaces(schema)); - } - -- @ApiOperation("慢SQL查询统计") -+ @ApiOperation(value = "慢SQL查询统计", notes = "仅超级管理员可操作。查询慢SQL统计信息,返回执行时间最长的SQL语句及其执行次数、平均耗时等") - @GetMapping("/slow-queries") - public Result>> slowQueries( - HttpServletRequest request, -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/NotificationLogController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/NotificationLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/NotificationLogController.java -index 7e55cae..46d7b72 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/NotificationLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/NotificationLogController.java -@@ -19,7 +19,7 @@ public class NotificationLogController { - - private final NotificationLogService notificationLogService; - -- @ApiOperation("消息通知日志分页查询") -+ @ApiOperation(value = "消息通知日志分页查询", notes = "查询各渠道(短信/站内信/企微/公众号)的通知发送记录,支持按通知类型、用户、发送状态筛选\n\n**关联字典**:\n- notification_send_status:发送状态(列表筛选+显示,0=待发送/1=成功/2=失败)") - @GetMapping - public Result> list( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -32,7 +32,8 @@ public class NotificationLogController { - return Result.success(notificationLogService.queryPage(page, pageSize, notificationType, userName, sendStatus, startTime, endTime)); - } - -- @ApiOperation("消息通知日志详情") -+ @ApiOperation(value = "消息通知日志详情", -+ notes = "返回单条通知发送日志的完整信息,包含通知类型、接收用户、发送渠道、发送状态、失败原因(如有)、消息内容等。") - @GetMapping("/{id}") - public Result detail(@ApiParam("日志ID") @PathVariable Long id) { - NotificationLog notificationLog = notificationLogService.getById(id); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/OperationLogController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/OperationLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/OperationLogController.java -index 43516e4..f620a50 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/OperationLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/OperationLogController.java -@@ -19,7 +19,7 @@ public class OperationLogController { - - private final OperationLogService operationLogService; - -- @ApiOperation("操作日志分页查询") -+ @ApiOperation(value = "操作日志分页查询", notes = "查询管理员的操作记录,支持按模块、管理员、状态、时间范围筛选。记录包含请求参数、响应结果和耗时信息\n\n**关联字典**:\n- operation_log_status:操作状态(列表筛选+显示,0=成功/1=失败)") - @GetMapping - public Result> list( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -32,7 +32,8 @@ public class OperationLogController { - return Result.success(operationLogService.queryPage(page, pageSize, module, adminId, status, startTime, endTime)); - } - -- @ApiOperation("操作日志详情") -+ @ApiOperation(value = "操作日志详情", -+ notes = "返回单条操作日志的完整信息,包含操作模块、操作描述、请求参数、响应结果、操作耗时、操作人信息、IP地址等。") - @GetMapping("/{id}") - public Result detail(@ApiParam("日志ID") @PathVariable Long id) { - OperationLog log = operationLogService.getById(id); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RedisMonitorController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RedisMonitorController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RedisMonitorController.java -index e70ae11..ffc059f 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RedisMonitorController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RedisMonitorController.java -@@ -17,7 +17,7 @@ public class RedisMonitorController { - - private final RedisMonitorService redisMonitorService; - -- @ApiOperation("Redis实时监控数据") -+ @ApiOperation(value = "Redis实时监控数据", notes = "返回Redis实时状态:内存使用量、连接数、Key数量、命中率、每秒命令数等核心指标") - @GetMapping - public Result> overview() { - return Result.success(redisMonitorService.getOverview()); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RocketMqMonitorController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RocketMqMonitorController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RocketMqMonitorController.java -index 5d642cb..9f32297 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RocketMqMonitorController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RocketMqMonitorController.java -@@ -18,19 +18,19 @@ public class RocketMqMonitorController { - - private final RocketMqMonitorService rocketMqMonitorService; - -- @ApiOperation("RocketMQ概览") -+ @ApiOperation(value = "RocketMQ概览", notes = "返回RocketMQ集群状态:Broker状态、Topic数量、消息积压量、生产者/消费者连接数等核心指标") - @GetMapping - public Result> overview() { - return Result.success(rocketMqMonitorService.getOverview()); - } - -- @ApiOperation("Topic统计") -+ @ApiOperation(value = "Topic统计", notes = "返回各Topic的消息量、最新偏移量和消费进度等信息") - @GetMapping("/topics") - public Result>> topicStats() { - return Result.success(rocketMqMonitorService.getTopicStats()); - } - -- @ApiOperation("消费者组统计") -+ @ApiOperation(value = "消费者组统计", notes = "返回各消费者组的消费进度、积压量和在线消费者实例信息") - @GetMapping("/consumer-groups") - public Result>> consumerGroupStats() { - return Result.success(rocketMqMonitorService.getConsumerGroupStats()); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ServiceMonitorController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ServiceMonitorController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ServiceMonitorController.java -index 63d09ef..11e5509 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ServiceMonitorController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ServiceMonitorController.java -@@ -18,7 +18,7 @@ public class ServiceMonitorController { - - private final ServiceMonitorService serviceMonitorService; - -- @ApiOperation("微服务列表和健康状态") -+ @ApiOperation(value = "微服务列表和健康状态", notes = "从Nacos注册中心获取所有微服务的实例列表和健康状态,包含IP、端口、注册时间和健康检查结果") - @GetMapping - public Result>> list() { - return Result.success(serviceMonitorService.getServiceList()); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpActivityController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpActivityController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpActivityController.java -index f7f787c..da96036 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpActivityController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpActivityController.java -@@ -22,7 +22,8 @@ public class MpActivityController { - private final MpResourceFeignClient resourceFeignClient; - private final ResourceMapService resourceMapService; - -- @ApiOperation("活动列表") -+ @ApiOperation(value = "活动列表", -+ notes = "分页查询已上架的活动列表,支持关键词和分类筛选。聚合层透传resource-service的活动数据给小程序前端。") - @GetMapping("/list") - public Result>> listActivities( - @ApiParam("关键词") @RequestParam(required = false) String keyword, -@@ -37,7 +38,8 @@ public class MpActivityController { - return resourceFeignClient.listActivities(query); - } - -- @ApiOperation("活动详情") -+ @ApiOperation(value = "活动详情", -+ notes = "获取活动完整信息(含图文详情、价格等),自动注入静态地图图片URL用于详情页地图展示。") - @GetMapping("/{activityId}") - public Result> getActivityDetail(@ApiParam("活动ID") @PathVariable Long activityId) { - Result> result = resourceFeignClient.getActivityDetail(activityId); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBadgeController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBadgeController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBadgeController.java -index 9023792..61ad359 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBadgeController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBadgeController.java -@@ -18,7 +18,7 @@ public class MpBadgeController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("获取徽章数据") -+ @ApiOperation(value = "获取徽章数据", notes = "返回用户的徽章统计(未读消息数、待办事项数等),用于「我的」页面角标展示") - @GetMapping - public Result> getBadges(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBannerController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBannerController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBannerController.java -index 6089f32..df4d3dd 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBannerController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBannerController.java -@@ -23,7 +23,8 @@ public class MpBannerController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("获取当前生效的轮播图列表") -+ @ApiOperation(value = "获取当前生效的轮播图列表", -+ notes = "返回当前处于有效期内的轮播图,按排序值排列。用于小程序首页顶部轮播展示,透传自user-service。") - @GetMapping("/active") - public Result>> listActiveBanners() { - return userFeignClient.listActiveBanners(); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpConfigController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpConfigController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpConfigController.java -index be29a79..84ec777 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpConfigController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpConfigController.java -@@ -22,13 +22,15 @@ public class MpConfigController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("获取所有非敏感前端配置") -+ @ApiOperation(value = "获取所有非敏感前端配置", -+ notes = "返回所有非SECRET类型的前端配置项(如主题色、客服电话、版本号等)。不含敏感配置,可安全传输给小程序端。") - @GetMapping - public Result>> listPublicConfigs() { - return userFeignClient.listAllFrontendConfigs(); - } - -- @ApiOperation("按分组获取非敏感前端配置") -+ @ApiOperation(value = "按分组获取非敏感前端配置", -+ notes = "按配置分组获取前端配置项,如UI分组、功能开关分组等。用于小程序按需加载特定分组的配置。") - @GetMapping("/group/{group}") - public Result>> listPublicConfigsByGroup( - @ApiParam("配置分组") @PathVariable String group) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpContractController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpContractController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpContractController.java -index 4e34f66..c5b60cb 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpContractController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpContractController.java -@@ -20,7 +20,7 @@ public class MpContractController { - - private final MpContractFeignClient contractFeignClient; - -- @ApiOperation("合同列表") -+ @ApiOperation(value = "合同列表", notes = "**关联字典(BFF透传)**:\n- contract_status:合同状态(列表筛选+显示)") - @GetMapping("/list") - public Result>> listContracts( - HttpServletRequest request, -@@ -31,7 +31,7 @@ public class MpContractController { - return contractFeignClient.listContracts(userId, status, page, pageSize); - } - -- @ApiOperation(value = "合同详情", notes = "返回合同基本信息、签署状态、出行人签署详情及合同文件下载链接") -+ @ApiOperation(value = "合同详情", notes = "返回合同基本信息、签署状态、出行人签署详情及合同文件下载链接\n\n**关联字典(BFF透传)**:\n- contract_status:合同状态(显示)") - @GetMapping("/{id}") - public Result> getContractDetail( - HttpServletRequest request, -@@ -40,7 +40,7 @@ public class MpContractController { - return contractFeignClient.getContractDetail(id, userId); - } - -- @ApiOperation(value = "按订单查合同", notes = "返回订单关联的最新有效合同(非作废)") -+ @ApiOperation(value = "按订单查合同", notes = "返回订单关联的最新有效合同(非作废)\n\n**关联字典(BFF透传)**:\n- contract_status:合同状态(显示)") - @GetMapping("/by-order/{orderId}") - public Result> getContractByOrder( - HttpServletRequest request, -@@ -49,7 +49,7 @@ public class MpContractController { - return contractFeignClient.getContractByOrder(orderId, userId); - } - -- @ApiOperation(value = "按订单查所有合同", notes = "返回订单关联的所有有效合同(TOUR+INSURANCE各一条)") -+ @ApiOperation(value = "按订单查所有合同", notes = "返回订单关联的所有有效合同(TOUR+INSURANCE各一条)\n\n**关联字典(BFF透传)**:\n- contract_status:合同状态(显示)") - @GetMapping("/by-order/{orderId}/all") - public Result>> getContractsByOrder( - HttpServletRequest request, -@@ -58,7 +58,8 @@ public class MpContractController { - return contractFeignClient.getContractsByOrder(orderId, userId); - } - -- @ApiOperation("重新发送合同签署短信") -+ @ApiOperation(value = "重新发送合同签署短信", -+ notes = "重新向出行人发送合同签署短信通知,适用于出行人未收到短信或短信过期的场景。\n\n**权限**:需登录。") - @PostMapping("/{contractId}/resend-sms") - public Result resendContractSms( - @ApiParam("合同ID") @PathVariable Long contractId, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDesignerController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDesignerController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDesignerController.java -index ae62fb8..01d0115 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDesignerController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDesignerController.java -@@ -22,7 +22,8 @@ public class MpDesignerController { - private final MpUserFeignClient userFeignClient; - private final DesignerAggregationService designerAggregationService; - -- @ApiOperation("定制师列表(含真实产品数和评分,综合排序)") -+ @ApiOperation(value = "定制师列表(含真实产品数和评分,综合排序)", -+ notes = "获取定制师列表,聚合层会补充每个定制师的真实产品数量和评价评分。按综合排序(评分>路线数>咨询人数),用于小程序定制师推荐页。") - @SuppressWarnings("unchecked") - @GetMapping - public Result>> listDesigners( -@@ -37,7 +38,8 @@ public class MpDesignerController { - return result; - } - -- @ApiOperation("推荐定制师(综合排序第一名)") -+ @ApiOperation(value = "推荐定制师(综合排序第一名)", -+ notes = "获取综合排序排名第一的定制师信息(含产品数和评分),用于首页推荐定制师卡片展示。") - @GetMapping("/featured") - public Result> getFeaturedDesigner() { - // Fetch all designers, enrich and sort, return top one -@@ -74,7 +76,8 @@ public class MpDesignerController { - try { return Integer.parseInt(obj.toString()); } catch (NumberFormatException e) { return 0; } - } - -- @ApiOperation("定制师详情(含产品数量和评分)") -+ @ApiOperation(value = "定制师详情(含产品数量和评分)", -+ notes = "获取定制师完整个人信息,聚合层会补充该定制师的已发布产品数量和综合评分,用于定制师个人主页展示。") - @GetMapping("/{id}") - public Result> getDesignerDetail(@ApiParam("定制师ID") @PathVariable Long id) { - Map data = designerAggregationService.getDesignerDetailWithStats(id); -@@ -84,7 +87,7 @@ public class MpDesignerController { - return Result.success(data); - } - -- @ApiOperation("定制师已发布产品列表") -+ @ApiOperation(value = "定制师已发布产品列表", notes = "**关联字典(BFF透传)**:\n- product_type:产品类型(显示)") - @GetMapping("/{id}/products") - public Result>> getDesignerProducts( - @ApiParam("定制师ID") @PathVariable Long id, -@@ -93,7 +96,7 @@ public class MpDesignerController { - return designerAggregationService.getDesignerProducts(id, page, pageSize); - } - -- @ApiOperation("定制师产品评价列表") -+ @ApiOperation(value = "定制师产品评价列表", notes = "**关联字典(BFF透传)**:\n- rating_level:评价等级(显示)") - @GetMapping("/{id}/reviews") - public Result>> getDesignerReviews( - @ApiParam("定制师ID") @PathVariable Long id, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDictController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDictController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDictController.java -index b57cfd7..e689361 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDictController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDictController.java -@@ -23,7 +23,7 @@ public class MpDictController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("获取所有字典数据") -+ @ApiOperation(value = "获取所有字典数据", notes = "获取系统全部字典数据(按字典类型分组),用于小程序端的下拉选项、枚举映射等。建议前端缓存此数据") - @GetMapping("/all") - public Result>> getAllDict() { - return userFeignClient.getAllDict(); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpExploreController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpExploreController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpExploreController.java -index ba1fcaa..5aa4cfc 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpExploreController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpExploreController.java -@@ -9,6 +9,7 @@ import lombok.RequiredArgsConstructor; - import org.springframework.web.bind.annotation.*; - - import javax.servlet.http.HttpServletRequest; -+import java.util.Map; - - @Api(tags = "C端 - 探索接口") - @RestController -@@ -18,9 +19,10 @@ public class MpExploreController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("探索列表") -+ @ApiOperation(value = "探索列表", -+ notes = "获取已启用的探索分类列表(图文攻略内容),支持综合/最新/最热排序,分页返回。用于小程序探索频道首页瀑布流展示。") - @GetMapping("/list") -- public Result list( -+ public Result> list( - @ApiParam("排序方式:comprehensive/newest/hottest") @RequestParam(defaultValue = "comprehensive") String sortType, - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, - @ApiParam("每页条数") @RequestParam(defaultValue = "20") int pageSize) { -@@ -29,7 +31,7 @@ public class MpExploreController { - - @ApiOperation(value = "探索详情", notes = "自动增加浏览量,已登录时返回点赞/收藏状态") - @GetMapping("/{id}") -- public Result detail(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { -+ public Result> detail(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { - // optional auth: userId may be null if not logged in - Long userId = null; - String userIdHeader = request.getHeader("X-User-Id"); -@@ -42,22 +44,25 @@ public class MpExploreController { - return userFeignClient.getExploreCategoryDetail(id, userId); - } - -- @ApiOperation("浏览+1") -+ @ApiOperation(value = "浏览+1", -+ notes = "增加探索内容的浏览计数。前端进入探索详情页时调用,无需登录。") - @PostMapping("/{id}/view") -- public Result view(@ApiParam("探索分类ID") @PathVariable Long id) { -+ public Result view(@ApiParam("探索分类ID") @PathVariable Long id) { - return userFeignClient.incrementExploreViewCount(id); - } - -- @ApiOperation("切换点赞") -+ @ApiOperation(value = "切换点赞", -+ notes = "对探索内容点赞/取消点赞,返回当前点赞状态(true=已点赞)。\n\n**权限**:需登录。") - @PostMapping("/{id}/like") -- public Result toggleLike(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { -+ public Result toggleLike(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.toggleExploreLike(id, userId); - } - -- @ApiOperation("切换收藏") -+ @ApiOperation(value = "切换收藏", -+ notes = "对探索内容收藏/取消收藏,返回当前收藏状态(true=已收藏)。收藏后可在'我的收藏'中查看。\n\n**权限**:需登录。") - @PostMapping("/{id}/favorite") -- public Result toggleFavorite(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { -+ public Result toggleFavorite(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.toggleExploreFavorite(id, userId); - } -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFavoriteController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFavoriteController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFavoriteController.java -index 94c53e4..d596692 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFavoriteController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFavoriteController.java -@@ -27,7 +27,7 @@ public class MpFavoriteController { - private final MpUserFeignClient userFeignClient; - private final FavoriteAggregationService favoriteAggregationService; - -- @ApiOperation("添加收藏") -+ @ApiOperation(value = "添加收藏", notes = "将产品/景区/餐厅/活动加入收藏。同一目标重复收藏会返回已有收藏记录") - @PostMapping - public Result> addFavorite(HttpServletRequest request, - @Valid @RequestBody MpFavoriteRequest body) { -@@ -38,7 +38,8 @@ public class MpFavoriteController { - return userFeignClient.addFavorite(userId, map); - } - -- @ApiOperation("收藏列表(含资源摘要)") -+ @ApiOperation(value = "收藏列表(含资源摘要)", -+ notes = "分页查询收藏列表,聚合层会补充每个收藏项对应资源的摘要信息(名称、封面图、价格等)。支持按目标类型筛选。\n\n**权限**:需登录。\n\n**关联字典**:\n- favorite_resource_type:收藏资源类型(PRODUCT/SCENIC/RESTAURANT/ACTIVITY)") - @GetMapping - public Result> listFavorites(HttpServletRequest request, - @ApiParam("目标类型筛选(字典:favorite_resource_type):PRODUCT/SCENIC/RESTAURANT/ACTIVITY") -@@ -49,7 +50,8 @@ public class MpFavoriteController { - return Result.success(favoriteAggregationService.listFavorites(userId, targetType, page, pageSize)); - } - -- @ApiOperation("检查是否已收藏") -+ @ApiOperation(value = "检查是否已收藏", -+ notes = "检查当前用户是否已收藏指定资源,用于详情页收藏按钮状态显示。\n\n**权限**:需登录。") - @GetMapping("/check") - public Result checkFavorite(HttpServletRequest request, - @ApiParam("目标类型(字典:favorite_resource_type)") @RequestParam String targetType, -@@ -58,7 +60,8 @@ public class MpFavoriteController { - return userFeignClient.checkFavorite(userId, targetType, targetId); - } - -- @ApiOperation("批量删除收藏") -+ @ApiOperation(value = "批量删除收藏", -+ notes = "批量删除多条收藏记录,传入收藏记录ID列表。用于收藏管理页面的批量操作。\n\n**权限**:需登录,仅能删除自己的收藏。") - @DeleteMapping("/batch") - public Result batchDeleteFavorites(HttpServletRequest request, - @ApiParam("收藏ID列表") @RequestBody List ids) { -@@ -66,7 +69,8 @@ public class MpFavoriteController { - return userFeignClient.batchDeleteFavorites(userId, ids); - } - -- @ApiOperation("按目标取消收藏") -+ @ApiOperation(value = "按目标取消收藏", -+ notes = "通过目标类型+目标ID取消收藏,适用于详情页点击取消收藏的场景(不需要知道收藏记录ID)。\n\n**权限**:需登录。") - @DeleteMapping("/by-target") - public Result deleteFavoriteByTarget(HttpServletRequest request, - @ApiParam("目标类型") @RequestParam String targetType, -@@ -75,7 +79,8 @@ public class MpFavoriteController { - return userFeignClient.deleteFavoriteByTarget(userId, targetType, targetId); - } - -- @ApiOperation("取消收藏") -+ @ApiOperation(value = "取消收藏", -+ notes = "通过收藏记录ID取消收藏,适用于收藏列表页的删除操作。\n\n**权限**:需登录,仅能删除自己的收藏。") - @DeleteMapping("/{id}") - public Result deleteFavorite(HttpServletRequest request, - @ApiParam("收藏记录ID") @PathVariable Long id) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFootprintController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFootprintController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFootprintController.java -index c25ed9b..ab02f01 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFootprintController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFootprintController.java -@@ -26,7 +26,7 @@ public class MpFootprintController { - private final MpUserFeignClient userFeignClient; - private final FootprintAggregationService footprintAggregationService; - -- @ApiOperation("记录足迹") -+ @ApiOperation(value = "记录足迹", notes = "记录用户浏览资源的足迹,同一资源重复浏览会更新浏览时间而非新增记录") - @PostMapping - public Result> addFootprint(HttpServletRequest request, - @RequestBody MpFootprintAddRequest body) { -@@ -37,7 +37,8 @@ public class MpFootprintController { - return userFeignClient.addFootprint(userId, map); - } - -- @ApiOperation("足迹列表(含资源摘要)") -+ @ApiOperation(value = "足迹列表(含资源摘要)", -+ notes = "分页查询浏览足迹列表,聚合层会补充每条足迹对应资源的摘要信息(名称、封面图等)。支持按资源类型筛选,按浏览时间倒序。\n\n**权限**:需登录。") - @GetMapping - public Result> listFootprints(HttpServletRequest request, - @ApiParam("资源类型筛选:PRODUCT/SCENIC/RESTAURANT/ACTIVITY") @RequestParam(required = false) String resourceType, -@@ -47,14 +48,16 @@ public class MpFootprintController { - return Result.success(footprintAggregationService.listFootprints(userId, resourceType, page, pageSize)); - } - -- @ApiOperation("删除足迹") -+ @ApiOperation(value = "删除足迹", -+ notes = "删除单条浏览足迹记录。\n\n**权限**:需登录,仅能删除自己的足迹。") - @DeleteMapping("/{id}") - public Result deleteFootprint(HttpServletRequest request, @ApiParam("足迹ID") @PathVariable Long id) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.deleteFootprint(userId, id); - } - -- @ApiOperation("批量删除足迹") -+ @ApiOperation(value = "批量删除足迹", -+ notes = "批量删除多条浏览足迹记录,传入足迹ID列表。用于足迹管理页面的批量清理。\n\n**权限**:需登录,仅能删除自己的足迹。") - @DeleteMapping("/batch") - public Result batchDeleteFootprints(HttpServletRequest request, - @ApiParam("足迹ID列表") @RequestBody List ids) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHomeController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHomeController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHomeController.java -index 8e7cdc5..0c6487f 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHomeController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHomeController.java -@@ -18,7 +18,7 @@ public class MpHomeController { - - private final HomeAggregationService homeAggregationService; - -- @ApiOperation(value = "首页数据", notes = "聚合流程:并行获取推荐产品列表+产品线列表+轮播图 → Redis缓存5分钟 → 返回聚合数据") -+ @ApiOperation(value = "首页数据", notes = "聚合流程:并行获取推荐产品列表+产品线列表+轮播图 → Redis缓存5分钟 → 返回聚合数据\n\n**关联字典(BFF透传)**:\n- product_type:产品类型(产品卡片显示)\n- product_status:产品状态(透传自product-service)") - @GetMapping - public Result getHomeData() { - return Result.success(homeAggregationService.getHomeData()); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHotelController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHotelController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHotelController.java -index d820bba..2d649e1 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHotelController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHotelController.java -@@ -22,7 +22,8 @@ public class MpHotelController { - private final MpResourceFeignClient resourceFeignClient; - private final ResourceMapService resourceMapService; - -- @ApiOperation("酒店列表") -+ @ApiOperation(value = "酒店列表", -+ notes = "分页查询已上架的酒店列表,支持按关键词、城市、星级筛选。聚合层透传resource-service的酒店数据。") - @GetMapping("/list") - public Result>> listHotels( - @ApiParam("关键词") @RequestParam(required = false) String keyword, -@@ -39,7 +40,8 @@ public class MpHotelController { - return resourceFeignClient.listHotels(query); - } - -- @ApiOperation("酒店详情") -+ @ApiOperation(value = "酒店详情", -+ notes = "获取酒店完整信息(含房型列表、图文详情、价格等),自动注入静态地图图片URL用于详情页地图展示。") - @GetMapping("/{hotelId}") - public Result> getHotelDetail(@ApiParam("酒店ID") @PathVariable Long hotelId) { - Result> result = resourceFeignClient.getHotelDetail(hotelId); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInsuranceController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInsuranceController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInsuranceController.java -index 3941bc4..d1403a0 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInsuranceController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInsuranceController.java -@@ -18,7 +18,7 @@ public class MpInsuranceController { - - private final MpInsuranceFeignClient insuranceFeignClient; - -- @ApiOperation(value = "获取订单所有保单PDF", notes = "合并所有出行人的有效保单为一个PDF,返回base64") -+ @ApiOperation(value = "获取订单所有保单PDF", notes = "合并所有出行人的有效保单为一个PDF,返回base64\n\n**关联字典(BFF透传)**:\n- insurance_status:保险状态(返回字段)") - @GetMapping("/policy-pdf/{orderId}") - public Result> getPolicyPdf( - @ApiParam("订单ID") @PathVariable Long orderId) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInvoiceController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInvoiceController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInvoiceController.java -index bda90ad..a42a662 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInvoiceController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInvoiceController.java -@@ -31,7 +31,7 @@ public class MpInvoiceController { - return orderFeignClient.applyInvoice(userId, body); - } - -- @ApiOperation("发票详情") -+ @ApiOperation(value = "发票详情", notes = "获取发票的完整信息,包含开票状态、发票抬头、税号、金额、电子发票文件链接等") - @GetMapping("/{id}") - public Result> getInvoiceDetail(@ApiParam("发票ID") @PathVariable Long id, - HttpServletRequest request) { -@@ -39,7 +39,7 @@ public class MpInvoiceController { - return orderFeignClient.getInvoiceDetail(id, userId); - } - -- @ApiOperation("通过订单ID查询发票") -+ @ApiOperation(value = "通过订单ID查询发票", notes = "查询指定订单的发票信息,如果订单未开票则返回null") - @GetMapping("/order/{orderId}") - public Result> getInvoiceByOrderId(@ApiParam("订单ID") @PathVariable Long orderId, - HttpServletRequest request) { -@@ -47,7 +47,7 @@ public class MpInvoiceController { - return orderFeignClient.getInvoiceByOrderId(orderId, userId); - } - -- @ApiOperation("发票换开") -+ @ApiOperation(value = "发票换开", notes = "对已开发票申请换开(修改抬头/税号等),原发票作废后重新开具新发票") - @PostMapping("/{invoiceId}/reissue") - public Result> reissueInvoice( - @ApiParam("发票ID") @PathVariable Long invoiceId, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpLikeController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpLikeController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpLikeController.java -index d60be9e..c8d50b5 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpLikeController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpLikeController.java -@@ -57,7 +57,8 @@ public class MpLikeController { - return result; - } - -- @ApiOperation("检查是否已点赞") -+ @ApiOperation(value = "检查是否已点赞", -+ notes = "检查当前用户是否已对指定目标点赞,用于前端点赞按钮状态展示。\n\n**权限**:需登录。") - @GetMapping("/{targetType}/{targetId}/check") - public Result checkLike( - @ApiParam("目标类型") @PathVariable String targetType, -@@ -67,7 +68,8 @@ public class MpLikeController { - return userFeignClient.checkLikeStatus(targetType.toUpperCase(), targetId, userId); - } - -- @ApiOperation("批量检查点赞状态") -+ @ApiOperation(value = "批量检查点赞状态", -+ notes = "批量检查当前用户是否已对多个目标点赞,返回已点赞的目标ID列表。用于列表页批量展示点赞状态。\n\n**权限**:需登录。") - @PostMapping("/{targetType}/batch-check") - public Result> batchCheckLiked( - @ApiParam("目标类型") @PathVariable String targetType, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpOrderController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpOrderController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpOrderController.java -index bc4abe0..e1f7fa6 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpOrderController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpOrderController.java -@@ -37,7 +37,7 @@ public class MpOrderController { - return orderFeignClient.createOrder(userId, body); - } - -- @ApiOperation("订单列表") -+ @ApiOperation(value = "订单列表", notes = "分页查询当前用户的订单列表,支持按状态筛选。返回订单摘要信息(不含详细出行人信息)\n\n**关联字典(BFF透传)**:\n- order_status:订单状态(列表筛选+显示)\n- product_type:产品类型(订单卡片显示)") - @GetMapping("/list") - public Result> listOrders(HttpServletRequest request, - @ApiParam("状态") @RequestParam(required = false) String status, -@@ -51,7 +51,7 @@ public class MpOrderController { - return orderFeignClient.listOrders(userId, query); - } - -- @ApiOperation("订单详情") -+ @ApiOperation(value = "订单详情", notes = "获取订单完整信息,包含产品快照、出行人列表、支付信息、合同状态等\n\n**关联字典(BFF透传)**:\n- order_status:订单状态(显示)\n- product_type:产品类型(显示)\n- contract_status:合同状态(显示)") - @GetMapping("/{orderId}") - public Result getOrder(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId) { -@@ -86,9 +86,10 @@ public class MpOrderController { - return orderFeignClient.cancelOrder(userId, orderId, body != null ? body : new MpCancelOrderRequest()); - } - -- @ApiOperation("通过联系人手机号+姓名查找订单(无需登录)") -+ @ApiOperation(value = "通过联系人手机号+姓名查找订单(无需登录)", -+ notes = "无需登录即可查询。用于管理员代下单场景:管理员创建订单后,用户通过联系人手机号+姓名查找订单并绑定到自己账号。仅返回尚未绑定用户(userId=NULL)的订单。") - @GetMapping("/lookup") -- public Result lookupByContact(@ApiParam("联系人手机号") @RequestParam String contactPhone, -+ public Result>> lookupByContact(@ApiParam("联系人手机号") @RequestParam String contactPhone, - @ApiParam("联系人姓名") @RequestParam String contactName) { - return orderFeignClient.lookupByContact(contactPhone, contactName); - } -@@ -101,7 +102,7 @@ public class MpOrderController { - return orderFeignClient.bindByContact(userId, body); - } - -- @ApiOperation("同意解锁订单") -+ @ApiOperation(value = "同意解锁订单", notes = "用户同意管理员的修改请求,解除订单锁定状态,允许管理员继续修改订单") - @PostMapping("/{orderId}/approve-unlock") - public Result approveUnlock(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId) { -@@ -116,7 +117,7 @@ public class MpOrderController { - return orderFeignClient.getUpcomingDepartures(userId); - } - -- @ApiOperation("各状态订单数量") -+ @ApiOperation(value = "各状态订单数量", notes = "统计当前用户各状态的订单数量,用于「我的」页面的订单状态角标展示\n\n**关联字典(BFF透传)**:\n- order_status:订单状态(状态分类统计)") - @GetMapping("/count") - public Result> countByStatus(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpPaymentController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpPaymentController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpPaymentController.java -index 6ddf62a..274102d 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpPaymentController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpPaymentController.java -@@ -21,7 +21,7 @@ public class MpPaymentController { - private final MpPaymentFeignClient paymentFeignClient; - - @PostMapping("/prepay") -- @ApiOperation(value = "发起支付", notes = "支付流程:选择支付方式(JSAPI/H5) → 调用微信支付API → 返回支付参数 → 前端调起微信支付") -+ @ApiOperation(value = "发起支付", notes = "支付流程:选择支付方式(JSAPI/H5) → 调用微信支付API → 返回支付参数 → 前端调起微信支付\n\n**关联字典(BFF透传)**:\n- payment_status:支付状态(返回字段)") - public Result> prepay( - HttpServletRequest httpRequest, - @ApiParam("支付请求体") @RequestBody MpPaymentPrepayRequest request) { -@@ -30,7 +30,7 @@ public class MpPaymentController { - } - - @GetMapping("/status/{orderId}") -- @ApiOperation("查询支付状态") -+ @ApiOperation(value = "查询支付状态", notes = "**关联字典(BFF透传)**:\n- payment_status:支付状态(显示)") - public Result> getStatus(@ApiParam("订单ID") @PathVariable Long orderId, - HttpServletRequest httpRequest) { - Long userId = (Long) httpRequest.getAttribute("userId"); -@@ -38,8 +38,8 @@ public class MpPaymentController { - } - - @GetMapping("/transactions/{orderId}") -- @ApiOperation("订单交易记录列表") -- public Result listTransactions(@ApiParam("订单ID") @PathVariable Long orderId, -+ @ApiOperation(value = "订单交易记录列表", notes = "**关联字典(BFF透传)**:\n- payment_status:支付状态(显示)") -+ public Result>> listTransactions(@ApiParam("订单ID") @PathVariable Long orderId, - HttpServletRequest httpRequest) { - Long userId = (Long) httpRequest.getAttribute("userId"); - return paymentFeignClient.listTransactions(userId, orderId); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpProductController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpProductController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpProductController.java -index 6aa9542..1aa236f 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpProductController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpProductController.java -@@ -34,7 +34,7 @@ public class MpProductController { - private final MpOrderFeignClient orderFeignClient; - private final ProductAggregationService productAggregationService; - -- @ApiOperation("产品列表") -+ @ApiOperation(value = "产品列表", notes = "分页查询已上架产品,支持按关键词、产品类型(CORE/ROUTE/CUSTOM/GROUP)、季节、天数、目的地、产品线筛选和排序\n\n**关联字典(BFF透传)**:\n- product_type:产品类型(列表筛选+显示)\n- product_status:产品状态(透传自product-service)") - @GetMapping("/list") - public Result>> listProducts( - @ApiParam("搜索关键词") @RequestParam(required = false) String keyword, -@@ -63,7 +63,7 @@ public class MpProductController { - return productFeignClient.listProducts(query); - } - -- @ApiOperation(value = "产品详情(聚合收藏状态)", notes = "聚合流程:获取产品详情 → 并行查询收藏状态 → 异步记录足迹 → 返回聚合数据。支持未登录访问(不返回收藏状态)") -+ @ApiOperation(value = "产品详情(聚合收藏状态)", notes = "聚合流程:获取产品详情 → 并行查询收藏状态 → 异步记录足迹 → 返回聚合数据。支持未登录访问(不返回收藏状态)\n\n**关联字典(BFF透传)**:\n- product_type:产品类型(显示)\n- product_status:产品状态(透传自product-service)") - @GetMapping("/{productId}") - public Result getProduct(HttpServletRequest request, - @ApiParam("产品ID") @PathVariable Long productId) { -@@ -256,7 +256,7 @@ public class MpProductController { - } - } - -- @ApiOperation("产品线列表") -+ @ApiOperation(value = "产品线列表", notes = "返回所有已启用的产品线,用于小程序首页或筛选栏展示") - @GetMapping("/lines") - public Result>> listLines() { - return productFeignClient.listActiveLines(); -@@ -284,7 +284,7 @@ public class MpProductController { - return productFeignClient.listBatchCombos(batchId); - } - -- @ApiOperation("价格日历") -+ @ApiOperation(value = "价格日历", notes = "返回产品指定日期范围内的每日价格,用于日历组件展示。不传日期时默认返回未来一个月") - @GetMapping("/{productId}/price-calendar") - public Result>> getPriceCalendar( - @ApiParam("产品ID") @PathVariable Long productId, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRefundController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRefundController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRefundController.java -index 5a72099..71890d6 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRefundController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRefundController.java -@@ -32,7 +32,7 @@ public class MpRefundController { - return orderFeignClient.refundPreview(userId, orderId); - } - -- @ApiOperation("退款原因列表") -+ @ApiOperation(value = "退款原因列表", notes = "返回系统预设的退款原因选项,用于退款申请页面的原因选择") - @GetMapping("/refund-reasons") - public Result> listRefundReasons() { - return orderFeignClient.listRefundReasons(); -@@ -48,7 +48,7 @@ public class MpRefundController { - return orderFeignClient.applyRefund(userId, userName, orderId, body); - } - -- @ApiOperation("退款申请详情") -+ @ApiOperation(value = "退款申请详情", notes = "获取退款申请的完整信息,包含审核状态、退款金额、退款进度和操作记录\n\n**关联字典(BFF透传)**:\n- order_status:订单状态(显示)\n- payment_status:支付/退款状态(显示)") - @GetMapping("/refund/{applicationId}") - public Result getRefundDetail(@ApiParam("退款申请ID") @PathVariable Long applicationId, - HttpServletRequest request) { -@@ -56,7 +56,7 @@ public class MpRefundController { - return orderFeignClient.getRefundDetail(userId, applicationId); - } - -- @ApiOperation("根据订单ID获取最新退款详情") -+ @ApiOperation(value = "根据订单ID获取最新退款详情", notes = "查询订单关联的最新一条退款申请详情,无退款记录时返回null\n\n**关联字典(BFF透传)**:\n- order_status:订单状态(显示)\n- payment_status:支付/退款状态(显示)") - @GetMapping("/{orderId}/refund-detail") - public Result getRefundDetailByOrder(@ApiParam("订单ID") @PathVariable String orderId, - HttpServletRequest request) { -@@ -84,7 +84,7 @@ public class MpRefundController { - return orderFeignClient.refundAppeal(userId, applicationId, body); - } - -- @ApiOperation("撤回退款申请") -+ @ApiOperation(value = "撤回退款申请", notes = "仅PENDING状态的退款申请可撤回,撤回后订单恢复到原状态") - @PostMapping("/refund/{applicationId}/cancel") - public Result cancelRefund(@ApiParam("退款申请ID") @PathVariable Long applicationId, - HttpServletRequest request) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRestaurantController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRestaurantController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRestaurantController.java -index 4b75e9b..38fa21b 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRestaurantController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRestaurantController.java -@@ -22,7 +22,8 @@ public class MpRestaurantController { - private final MpResourceFeignClient resourceFeignClient; - private final ResourceMapService resourceMapService; - -- @ApiOperation("餐厅列表") -+ @ApiOperation(value = "餐厅列表", -+ notes = "分页查询已上架的餐厅列表,支持按关键词和城市筛选。聚合层透传resource-service的餐厅数据。") - @GetMapping("/list") - public Result>> listRestaurants( - @ApiParam("关键词") @RequestParam(required = false) String keyword, -@@ -37,7 +38,8 @@ public class MpRestaurantController { - return resourceFeignClient.listRestaurants(query); - } - -- @ApiOperation("餐厅详情") -+ @ApiOperation(value = "餐厅详情", -+ notes = "获取餐厅完整信息(含菜品、图文详情等),自动注入静态地图图片URL用于详情页地图展示。") - @GetMapping("/{restaurantId}") - public Result> getRestaurantDetail(@ApiParam("餐厅ID") @PathVariable Long restaurantId) { - Result> result = resourceFeignClient.getRestaurantDetail(restaurantId); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpReviewController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpReviewController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpReviewController.java -index 1f44df4..1cf55b2 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpReviewController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpReviewController.java -@@ -55,7 +55,7 @@ public class MpReviewController { - return Result.success(categories); - } - -- @ApiOperation(value = "创建评价", notes = "评价流程:订单完成后 → 查询可评价目标列表 → 对每个目标(酒店/景区/活动等)提交评价 → 自动内容审核 → 审核通过后公开展示") -+ @ApiOperation(value = "创建评价", notes = "评价流程:订单完成后 → 查询可评价目标列表 → 对每个目标(酒店/景区/活动等)提交评价 → 自动内容审核 → 审核通过后公开展示\n\n**关联字典(BFF透传)**:\n- review_status:评价审核状态(返回字段)\n- rating_level:评价等级(返回字段)") - @PostMapping("/create") - public Result> createReview(@ApiParam("评价请求体") @RequestBody MpReviewCreateRequest body, - HttpServletRequest request) { -@@ -65,7 +65,7 @@ public class MpReviewController { - return reviewFeignClient.createReview(body, userId); - } - -- @ApiOperation("我的评价列表") -+ @ApiOperation(value = "我的评价列表", notes = "**关联字典(BFF透传)**:\n- review_status:评价审核状态(显示)\n- rating_level:评价等级(显示)") - @GetMapping("/my") - public Result>> getMyReviews( - @ApiParam("页码") @RequestParam(defaultValue = "1") Integer page, -@@ -75,7 +75,7 @@ public class MpReviewController { - return reviewFeignClient.getMyReviews(page, pageSize, userId); - } - -- @ApiOperation(value = "关键词搜索评价(公开)", notes = "按关键词搜索已通过的评价内容,支持按目标类型和目标ID筛选") -+ @ApiOperation(value = "关键词搜索评价(公开)", notes = "按关键词搜索已通过的评价内容,支持按目标类型和目标ID筛选\n\n**关联字典(BFF透传)**:\n- rating_level:评价等级(显示)") - @GetMapping("/search") - public Result>> searchReviews( - @ApiParam(value = "搜索关键词", required = true) @RequestParam String keyword, -@@ -86,7 +86,7 @@ public class MpReviewController { - return reviewFeignClient.searchReviews(keyword, targetType, targetId, page, pageSize); - } - -- @ApiOperation("某目标的已通过评价(公开)") -+ @ApiOperation(value = "某目标的已通过评价(公开)", notes = "**关联字典(BFF透传)**:\n- rating_level:评价等级(筛选+显示)") - @GetMapping("/target") - public Result>> getTargetReviews( - @ApiParam("目标类型") @RequestParam String targetType, -@@ -102,7 +102,7 @@ public class MpReviewController { - return reviewFeignClient.getTargetReviews(targetType, targetId, ratingLevel, hasImage, hasVideo, page, pageSize); - } - -- @ApiOperation(value = "按产品ID查看评价列表", notes = "返回评价列表+统计数据,支持好中差评/有图/有视频筛选") -+ @ApiOperation(value = "按产品ID查看评价列表", notes = "返回评价列表+统计数据,支持好中差评/有图/有视频筛选\n\n**关联字典(BFF透传)**:\n- rating_level:评价等级(筛选+显示)") - @GetMapping("/product/{productId}") - public Result> getProductReviews( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -144,7 +144,8 @@ public class MpReviewController { - return reviewFeignClient.getProductHighlights(productId); - } - -- @ApiOperation("评价统计(平均分、数量)") -+ @ApiOperation(value = "评价统计(平均分、数量)", -+ notes = "获取指定目标的评价统计数据(平均评分、总评价数等),用于详情页评价区域展示。产品showReview关闭时返回空统计。") - @GetMapping("/stats") - public Result> getTargetStats( - @ApiParam("目标类型") @RequestParam String targetType, -@@ -174,21 +175,23 @@ public class MpReviewController { - return true; // 查询失败时默认显示 - } - -- @ApiOperation(value = "精选评价列表(公开)", notes = "无需登录,返回精选评价数组,用于评价浏览页") -+ @ApiOperation(value = "精选评价列表(公开)", notes = "无需登录,返回精选评价数组,用于评价浏览页\n\n**关联字典(BFF透传)**:\n- rating_level:评价等级(显示)") - @GetMapping("/featured") - public Result>> getFeaturedReviews( - @ApiParam("数量限制") @RequestParam(defaultValue = "50") Integer limit) { - return reviewFeignClient.getFeaturedReviews(limit); - } - -- @ApiOperation("检查订单是否已评价") -+ @ApiOperation(value = "检查订单是否已评价", -+ notes = "检查指定订单是否已提交评价,用于订单详情页决定是否显示'去评价'按钮。") - @GetMapping("/order/{orderId}/reviewed") - public Result isOrderReviewed( - @ApiParam("订单ID") @PathVariable Long orderId) { - return reviewFeignClient.isOrderReviewed(orderId); - } - -- @ApiOperation("订单可评价目标列表") -+ @ApiOperation(value = "订单可评价目标列表", -+ notes = "返回订单中可评价的资源目标列表(景区/酒店/活动等),用于评价页面展示可评价项。已评价的目标不会重复出现。\n\n**权限**:需登录。") - @GetMapping("/order/{orderId}/reviewable-targets") - public Result>> getReviewableTargets( - @ApiParam("订单ID") @PathVariable Long orderId, HttpServletRequest request) { -@@ -196,7 +199,8 @@ public class MpReviewController { - return reviewFeignClient.getReviewableTargets(orderId, userId); - } - -- @ApiOperation("点赞/取消点赞评价") -+ @ApiOperation(value = "点赞/取消点赞评价", -+ notes = "对评价进行点赞或取消点赞操作,返回当前点赞状态和点赞总数。\n\n**权限**:需登录。") - @PostMapping("/{reviewId}/like") - public Result> toggleLike( - @ApiParam("评价ID") @PathVariable Long reviewId, HttpServletRequest request) { -@@ -204,7 +208,8 @@ public class MpReviewController { - return reviewFeignClient.toggleLike(reviewId, userId); - } - -- @ApiOperation("检查是否已点赞") -+ @ApiOperation(value = "检查是否已点赞", -+ notes = "检查当前用户是否已点赞指定评价,用于评价列表/详情的点赞按钮状态展示。\n\n**权限**:需登录。") - @GetMapping("/{reviewId}/like/check") - public Result checkLiked( - @ApiParam("评价ID") @PathVariable Long reviewId, HttpServletRequest request) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpScenicController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpScenicController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpScenicController.java -index 96a4529..8f59647 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpScenicController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpScenicController.java -@@ -27,7 +27,8 @@ public class MpScenicController { - private final MpUserFeignClient userFeignClient; - private final ResourceMapService resourceMapService; - -- @ApiOperation("景区列表") -+ @ApiOperation(value = "景区列表", -+ notes = "分页查询已上架的景区列表,支持按关键词和城市筛选。聚合层透传resource-service的景区数据。") - @GetMapping("/list") - public Result>> listScenic( - @ApiParam("关键词") @RequestParam(required = false) String keyword, -@@ -42,7 +43,8 @@ public class MpScenicController { - return resourceFeignClient.listScenic(query); - } - -- @ApiOperation("景区详情") -+ @ApiOperation(value = "景区详情", -+ notes = "获取景区完整信息(含季节素材、图文详情、价格等),自动注入静态地图图片URL用于详情页地图展示。") - @GetMapping("/{scenicId}") - public Result> getScenicDetail(@ApiParam("景区ID") @PathVariable Long scenicId) { - Result> result = resourceFeignClient.getScenicDetail(scenicId); -@@ -52,7 +54,8 @@ public class MpScenicController { - return result; - } - -- @ApiOperation("附近景区(地理+探索分类聚合)") -+ @ApiOperation(value = "附近景区(地理+探索分类聚合)", -+ notes = "聚合两个数据源:1.基于经纬度的地理位置附近景区(resource-service);2.探索分类关联的景区(user-service)。去重合并后返回,用于景区详情页底部'附近推荐'展示。") - @GetMapping("/{scenicId}/nearby") - public Result>> getNearbyScenic( - @ApiParam("景区ID") @PathVariable Long scenicId, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpSearchController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpSearchController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpSearchController.java -index 7a2362a..689c544 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpSearchController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpSearchController.java -@@ -20,7 +20,7 @@ public class MpSearchController { - - private final MpProductFeignClient productFeignClient; - -- @ApiOperation("搜索产品") -+ @ApiOperation(value = "搜索产品", notes = "按关键词搜索已上架产品(匹配产品名称和描述),支持按产品类型进一步筛选\n\n**关联字典(BFF透传)**:\n- product_type:产品类型(筛选+显示)") - @GetMapping - public Result>> search( - @ApiParam("搜索关键词") @RequestParam String keyword, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTravelerController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTravelerController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTravelerController.java -index 8831fd0..4f8f4d9 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTravelerController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTravelerController.java -@@ -22,7 +22,7 @@ public class MpTravelerController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("添加出行人") -+ @ApiOperation(value = "添加出行人", notes = "添加常用出行人信息(姓名/证件/联系方式等),下单时可快速选择。单个用户最多50个出行人") - @PostMapping - public Result> addTraveler(HttpServletRequest request, - @RequestBody MpTravelerRequest body) { -@@ -31,21 +31,23 @@ public class MpTravelerController { - return userFeignClient.addTraveler(userId, map); - } - -- @ApiOperation("出行人列表") -+ @ApiOperation(value = "出行人列表", notes = "返回当前用户的所有出行人列表。如果用户已完善实名信息,列表中会自动包含一条「本人」虚拟记录(travelerId=0)") - @GetMapping - public Result>> listTravelers(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.listTravelers(userId); - } - -- @ApiOperation("出行人详情") -+ @ApiOperation(value = "出行人详情", -+ notes = "获取单个出行人的完整信息(姓名、证件信息、联系方式等)。\n\n**权限**:需登录,仅能查看自己的出行人。") - @GetMapping("/{id}") - public Result> getTraveler(HttpServletRequest request, @ApiParam("出行人ID") @PathVariable Long id) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.getTraveler(userId, id); - } - -- @ApiOperation("更新出行人") -+ @ApiOperation(value = "更新出行人", -+ notes = "修改出行人信息,支持部分更新(只传需要修改的字段)。已关联订单的出行人修改不影响历史订单记录。\n\n**权限**:需登录。") - @PutMapping("/{id}") - public Result> updateTraveler(HttpServletRequest request, - @ApiParam("出行人ID") @PathVariable Long id, -@@ -55,14 +57,15 @@ public class MpTravelerController { - return userFeignClient.updateTraveler(userId, id, map); - } - -- @ApiOperation("删除出行人") -+ @ApiOperation(value = "删除出行人", -+ notes = "删除常用出行人记录。默认出行人不可删除,需先取消默认后再删除。\n\n**权限**:需登录。") - @DeleteMapping("/{id}") - public Result deleteTraveler(HttpServletRequest request, @ApiParam("出行人ID") @PathVariable Long id) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.deleteTraveler(userId, id); - } - -- @ApiOperation("设为默认出行人") -+ @ApiOperation(value = "设为默认出行人", notes = "设为默认出行人后,下单时自动作为第一个出行人。每个用户只能有一个默认出行人") - @PutMapping("/{id}/default") - public Result setDefaultTraveler(HttpServletRequest request, @ApiParam("出行人ID") @PathVariable Long id) { - Long userId = (Long) request.getAttribute("userId"); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTripController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTripController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTripController.java -index 5247c6f..9870345 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTripController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTripController.java -@@ -22,14 +22,14 @@ public class MpTripController { - private final MpOrderFeignClient orderFeignClient; - private final WeatherService weatherService; - -- @ApiOperation(value = "行程列表", notes = "获取当前登录用户的行程列表(已确认及进行中的订单对应的行程)") -+ @ApiOperation(value = "行程列表", notes = "获取当前登录用户的行程列表(已确认及进行中的订单对应的行程)\n\n**关联字典(BFF透传)**:\n- order_status:订单/行程状态(显示)") - @GetMapping("/list") - public Result>> getTripList(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return orderFeignClient.getTripList(userId); - } - -- @ApiOperation(value = "行程详情", notes = "获取订单对应的行程详情,含每日行程节点信息(景点/酒店/餐厅等)") -+ @ApiOperation(value = "行程详情", notes = "获取订单对应的行程详情,含每日行程节点信息(景点/酒店/餐厅等)\n\n**关联字典(BFF透传)**:\n- order_status:订单/行程状态(显示)") - @GetMapping("/{orderId}") - public Result> getTripDetail(HttpServletRequest request, - @ApiParam(value = "订单ID", required = true) @PathVariable Long orderId) { -@@ -37,7 +37,7 @@ public class MpTripController { - return orderFeignClient.getTripDetail(userId, orderId); - } - -- @ApiOperation(value = "今日行程", notes = "获取今日行程(如果有正在进行中的行程),无行程时data为null") -+ @ApiOperation(value = "今日行程", notes = "获取今日行程(如果有正在进行中的行程),无行程时data为null\n\n**关联字典(BFF透传)**:\n- order_status:订单/行程状态(显示)") - @GetMapping("/today") - public Result> getTodayTrip(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpUserController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpUserController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpUserController.java -index 26146f8..249591a 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpUserController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpUserController.java -@@ -20,7 +20,7 @@ public class MpUserController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("发送短信验证码") -+ @ApiOperation(value = "发送短信验证码", notes = "向指定手机号发送登录验证码,有效期5分钟,60秒内不可重复发送") - @PostMapping("/sms/send") - public Result sendSmsCode(@RequestBody MpSmsSendRequest request) { - Map map = new java.util.HashMap<>(); -@@ -45,14 +45,14 @@ public class MpUserController { - return userFeignClient.login(map); - } - -- @ApiOperation("获取用户信息") -+ @ApiOperation(value = "获取用户信息", notes = "获取当前登录用户的个人资料,包含头像、昵称、手机号、实名信息等") - @GetMapping("/profile") - public Result> getProfile(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.getProfile(userId); - } - -- @ApiOperation("更新用户信息") -+ @ApiOperation(value = "更新用户信息", notes = "更新当前用户的个人资料,支持部分更新(只传需要修改的字段)。首次完善资料时realName为必填") - @PutMapping("/profile") - public Result> updateProfile(HttpServletRequest request, - @RequestBody MpUserProfileUpdateRequest body) { -@@ -69,7 +69,8 @@ public class MpUserController { - return userFeignClient.updateProfile(userId, map); - } - -- @ApiOperation("用户登出") -+ @ApiOperation(value = "用户登出", -+ notes = "清除用户登录状态和服务端缓存的令牌信息。登出后需重新登录获取新令牌。\n\n**权限**:需登录。") - @PostMapping("/logout") - public Result logout(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWeatherController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWeatherController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWeatherController.java -index 9341450..592fba5 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWeatherController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWeatherController.java -@@ -19,21 +19,21 @@ public class MpWeatherController { - - private final MpOrderFeignClient orderFeignClient; - -- @ApiOperation("获取订单行程天气") -+ @ApiOperation(value = "获取订单行程天气", notes = "根据订单行程中的目的地城市,批量查询每日天气信息,用于行程详情页展示") - @GetMapping("/itinerary/{orderId}") - public Result>> getItineraryWeather( - @ApiParam("订单ID") @PathVariable Long orderId) { - return orderFeignClient.getItineraryWeather(orderId); - } - -- @ApiOperation("获取指定城市实况天气") -+ @ApiOperation(value = "获取指定城市实况天气", notes = "通过高德天气API查询指定城市的实时天气(温度、湿度、风向等)") - @GetMapping("/live") - public Result> getLiveWeather( - @ApiParam("城市名称") @RequestParam String city) { - return orderFeignClient.getLiveWeather(city); - } - -- @ApiOperation("获取指定城市天气预报") -+ @ApiOperation(value = "获取指定城市天气预报", notes = "通过高德天气API查询指定城市未来3天的天气预报信息") - @GetMapping("/forecast") - public Result> getForecastWeather( - @ApiParam("城市名称") @RequestParam String city) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWikiController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWikiController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWikiController.java -index 26fe4ac..c70bd36 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWikiController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWikiController.java -@@ -20,13 +20,15 @@ public class MpWikiController { - - private final MpWikiFeignClient wikiFeignClient; - -- @ApiOperation("攻略分类列表") -+ @ApiOperation(value = "攻略分类列表", -+ notes = "获取所有已启用的攻略分类,按排序值排列。用于小程序攻略频道的分类导航展示。") - @GetMapping("/categories") - public Result>> listCategories() { - return wikiFeignClient.listEnabledCategories(); - } - -- @ApiOperation("分类文章列表") -+ @ApiOperation(value = "分类文章列表", -+ notes = "分页查询指定攻略分类下已发布的文章列表,按发布时间倒序排列。用于攻略分类详情页。") - @GetMapping("/category/{categoryId}/articles") - public Result>> listCategoryArticles( - @ApiParam("攻略分类ID") @PathVariable Long categoryId, -@@ -35,13 +37,14 @@ public class MpWikiController { - return wikiFeignClient.listCategoryArticles(categoryId, page, pageSize); - } - -- @ApiOperation("文章详情") -+ @ApiOperation(value = "文章详情", notes = "**关联字典(BFF透传)**:\n- wiki_status:文章状态(返回字段)") - @GetMapping("/article/{articleId}") - public Result> getArticle(@ApiParam("文章ID") @PathVariable Long articleId) { - return wikiFeignClient.getArticle(articleId); - } - -- @ApiOperation("推荐文章列表") -+ @ApiOperation(value = "推荐文章列表", -+ notes = "获取编辑推荐的攻略文章列表(按推荐权重排序),用于首页或攻略频道的推荐位展示。") - @GetMapping("/recommend-articles") - public Result>> listRecommendArticles( - @ApiParam("返回条数") @RequestParam(defaultValue = "10") Integer limit) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWishController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWishController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWishController.java -index f9abab8..d9d2416 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWishController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWishController.java -@@ -21,14 +21,14 @@ public class MpWishController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("心愿单列表") -+ @ApiOperation(value = "心愿单列表", notes = "返回当前用户的心愿单列表,按创建时间倒序排列") - @GetMapping - public Result>> listWishes(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.listWishes(userId); - } - -- @ApiOperation("创建心愿") -+ @ApiOperation(value = "创建心愿", notes = "创建旅行心愿,描述想去的地方和时间偏好,定制师可据此推荐产品") - @PostMapping - public Result> createWish(@ApiParam("心愿请求体") @RequestBody MpWishCreateRequest body, - HttpServletRequest request) { -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminAlbumController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminAlbumController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminAlbumController.java -index 9b8e419..dce7686 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminAlbumController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminAlbumController.java -@@ -28,7 +28,7 @@ public class AdminAlbumController { - - // ==================== 文件夹管理 ==================== - -- @ApiOperation("创建相册文件夹") -+ @ApiOperation(value = "创建相册文件夹", notes = "为订单创建旅行相册文件夹(如'第一天风景'、'合影'等),用于组织旅途照片/视频") - @PostMapping("/{orderId}/album/folder") - public Result createFolder( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -38,7 +38,7 @@ public class AdminAlbumController { - return Result.success(albumService.createFolder(orderId, request, adminId)); - } - -- @ApiOperation("编辑相册文件夹") -+ @ApiOperation(value = "编辑相册文件夹", notes = "修改文件夹名称或描述。仅创建者或超级管理员可操作") - @PutMapping("/album/folder/{folderId}") - public Result updateFolder( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -49,7 +49,7 @@ public class AdminAlbumController { - return Result.success(albumService.updateFolder(folderId, request, adminId, roleKey)); - } - -- @ApiOperation("删除相册文件夹") -+ @ApiOperation(value = "删除相册文件夹", notes = "删除文件夹及其下所有文件。仅创建者或超级管理员可操作。删除后C端用户不再可见") - @DeleteMapping("/album/folder/{folderId}") - public Result deleteFolder( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -60,7 +60,8 @@ public class AdminAlbumController { - return Result.success(null); - } - -- @ApiOperation("查询订单的文件夹列表") -+ @ApiOperation(value = "查询订单的文件夹列表", -+ notes = "获取指定订单的所有相册文件夹,含文件夹名称、描述、封面图、文件数量等信息。") - @GetMapping("/{orderId}/album/folders") - public Result> listFolders( - @ApiParam("订单ID") @PathVariable Long orderId) { -@@ -69,7 +70,11 @@ public class AdminAlbumController { - - // ==================== 文件管理 ==================== - -- @ApiOperation("批量添加文件到文件夹") -+ @ApiOperation(value = "批量添加文件到文件夹", notes = "一次添加多个照片/视频到指定文件夹。文件需先通过文件服务上传获取OSS URL\n\n" + -+ "**关联字典**:\n" + -+ "- album_file_type(文件类型,返回字段fileType):IMAGE=图片, VIDEO=视频\n" + -+ "- album_location_type(地点类型,返回字段locationType):RESOURCE=关联资源, CUSTOM=自定义地点\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PostMapping("/album/folder/{folderId}/files") - public Result> addFiles( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -80,7 +85,10 @@ public class AdminAlbumController { - return Result.success(albumService.addFiles(folderId, request, adminId, roleKey)); - } - -- @ApiOperation("编辑文件信息") -+ @ApiOperation(value = "编辑文件信息", notes = "**关联字典**:\n" + -+ "- album_file_type(文件类型,返回字段fileType):IMAGE=图片, VIDEO=视频\n" + -+ "- album_location_type(地点类型,返回字段locationType):RESOURCE=关联资源, CUSTOM=自定义地点\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PutMapping("/album/file/{albumFileId}") - public Result updateFile( - @ApiParam("相册文件ID") @PathVariable Long albumFileId, -@@ -91,7 +99,8 @@ public class AdminAlbumController { - return Result.success(albumService.updateFile(albumFileId, request, adminId, roleKey)); - } - -- @ApiOperation("删除文件") -+ @ApiOperation(value = "删除文件", -+ notes = "删除相册中的单个文件(照片/视频)。仅上传者或超级管理员可操作,删除后C端用户不再可见。") - @DeleteMapping("/album/file/{albumFileId}") - public Result deleteFile( - @ApiParam("相册文件ID") @PathVariable Long albumFileId, -@@ -102,7 +111,10 @@ public class AdminAlbumController { - return Result.success(null); - } - -- @ApiOperation("查询文件夹下的文件列表") -+ @ApiOperation(value = "查询文件夹下的文件列表", notes = "**关联字典**:\n" + -+ "- album_file_type(文件类型,返回字段fileType):IMAGE=图片, VIDEO=视频\n" + -+ "- album_location_type(地点类型,返回字段locationType):RESOURCE=关联资源, CUSTOM=自定义地点\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @GetMapping("/album/folder/{folderId}/files") - public Result> listFiles( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -111,7 +123,8 @@ public class AdminAlbumController { - return Result.success(albumService.listFiles(folderId, page, size)); - } - -- @ApiOperation("设置文件夹封面") -+ @ApiOperation(value = "设置文件夹封面", -+ notes = "将文件夹中的指定文件设为封面图,封面图会在文件夹列表中展示。仅上传者或超级管理员可操作。") - @PutMapping("/album/folder/{folderId}/cover") - public Result setCover( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -123,7 +136,11 @@ public class AdminAlbumController { - return Result.success(null); - } - -- @ApiOperation("我的上传(当前管理员上传的所有相册文件)") -+ @ApiOperation(value = "我的上传", notes = "查询当前管理员上传的所有相册文件(跨订单),方便管理自己上传的内容\n\n" + -+ "**关联字典**:\n" + -+ "- album_file_type(文件类型,返回字段fileType):IMAGE=图片, VIDEO=视频\n" + -+ "- album_location_type(地点类型,返回字段locationType):RESOURCE=关联资源, CUSTOM=自定义地点\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @GetMapping("/album/my-uploads") - public Result> listMyUploads( - HttpServletRequest httpRequest, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminEarlyBirdController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminEarlyBirdController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminEarlyBirdController.java -index 261c457..85b97c1 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminEarlyBirdController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminEarlyBirdController.java -@@ -31,7 +31,7 @@ public class AdminEarlyBirdController { - } - } - -- @ApiOperation("早鸟优惠计划列表") -+ @ApiOperation(value = "早鸟优惠计划列表", notes = "分页查询所有早鸟优惠计划。权限:仅超级管理员(SUPER_ADMIN)") - @GetMapping("/list") - public Result> list(HttpServletRequest request, - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -41,7 +41,7 @@ public class AdminEarlyBirdController { - return Result.success(result); - } - -- @ApiOperation("早鸟优惠计划详情") -+ @ApiOperation(value = "早鸟优惠计划详情", notes = "权限:仅超级管理员(SUPER_ADMIN)") - @GetMapping("/{planId}") - public Result detail(HttpServletRequest request, - @ApiParam("早鸟计划ID") @PathVariable Long planId) { -@@ -50,7 +50,8 @@ public class AdminEarlyBirdController { - return Result.success(vo); - } - -- @ApiOperation("创建早鸟优惠计划") -+ @ApiOperation(value = "创建早鸟优惠计划", notes = "创建一个早鸟优惠计划,在指定日期范围内下单且满足最低人数条件的订单可享受优惠。\n" + -+ "下单时系统自动匹配最优的早鸟计划。权限:仅超级管理员(SUPER_ADMIN)") - @PostMapping - public Result create(HttpServletRequest request, - @ApiParam("创建早鸟计划请求") @Valid @RequestBody EarlyBirdPlanRequest planRequest) { -@@ -61,7 +62,7 @@ public class AdminEarlyBirdController { - return Result.success(vo); - } - -- @ApiOperation("修改早鸟优惠计划") -+ @ApiOperation(value = "修改早鸟优惠计划", notes = "权限:仅超级管理员(SUPER_ADMIN)。修改不影响已下单的订单优惠") - @PutMapping("/{planId}") - public Result update(HttpServletRequest request, - @ApiParam("早鸟计划ID") @PathVariable Long planId, -@@ -71,7 +72,7 @@ public class AdminEarlyBirdController { - return Result.success(); - } - -- @ApiOperation("删除早鸟优惠计划") -+ @ApiOperation(value = "删除早鸟优惠计划", notes = "权限:仅超级管理员(SUPER_ADMIN)。删除不影响已下单的订单优惠") - @DeleteMapping("/{planId}") - public Result delete(HttpServletRequest request, - @ApiParam("早鸟计划ID") @PathVariable Long planId) { -@@ -80,7 +81,7 @@ public class AdminEarlyBirdController { - return Result.success(); - } - -- @ApiOperation("启用/禁用早鸟优惠计划") -+ @ApiOperation(value = "启用/禁用早鸟优惠计划", notes = "禁用后该计划不再参与自动匹配。权限:仅超级管理员(SUPER_ADMIN)") - @PutMapping("/{planId}/toggle") - public Result toggle(HttpServletRequest request, - @ApiParam("早鸟计划ID") @PathVariable Long planId, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderConfigController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderConfigController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderConfigController.java -index de26a0f..d79934d 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderConfigController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderConfigController.java -@@ -27,7 +27,8 @@ public class AdminOrderConfigController { - @Value("${order.expiry.redis-key:order:config:expiry-minutes}") - private String expiryRedisKey; - -- @ApiOperation("获取订单过期配置") -+ @ApiOperation(value = "获取订单过期配置", notes = "获取当前的订单未支付自动过期时间(分钟)。\n" + -+ "返回当前值、默认值和配置来源(redis=已自定义, default=使用默认值)") - @GetMapping("/expiry-minutes") - public Result> getExpiryMinutes() { - String val = stringRedisTemplate.opsForValue().get(expiryRedisKey); -@@ -45,7 +46,8 @@ public class AdminOrderConfigController { - )); - } - -- @ApiOperation("设置订单过期时间(分钟)") -+ @ApiOperation(value = "设置订单过期时间(分钟)", notes = "修改订单未支付自动取消的等待时间。存储在Redis中,即时生效。\n" + -+ "仅影响新创建的订单,已有订单的过期时间不变") - @PutMapping("/expiry-minutes") - public Result setExpiryMinutes(@ApiParam("修改订单过期时间请求") @Valid @RequestBody UpdateExpiryMinutesRequest expiryRequest) { - stringRedisTemplate.opsForValue().set(expiryRedisKey, String.valueOf(expiryRequest.getMinutes())); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderController.java -index e7f09ce..72bdfc8 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderController.java -@@ -47,7 +47,18 @@ public class AdminOrderController { - private static final String ORDER_CREATE_DEDUP = "order:admin:create:dedup:"; - - @ApiOperation(value = "创建订单(定制师代下单)", notes = "创建订单流程:选择产品 → 填写联系人和出行人 → 系统计算报价 → 生成订单(PENDING_PAY状态)\n\n" + -- "权限:CUSTOM产品仅创建者可下单,CORE/ROUTE产品所有管理员可下单") -+ "权限:CUSTOM产品仅创建者可下单,CORE/ROUTE产品所有管理员可下单\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 productType → 字典:product_type(产品类型)\n" + -+ "- 请求参数 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 请求参数 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 请求参数 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)\n" + -+ "- 返回字段 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 返回字段 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 返回字段 travelers[].gender → 字典:gender(性别)") - @PostMapping("/create") - public Result createOrder(HttpServletRequest request, - @ApiParam("创建订单请求") @Valid @RequestBody AdminCreateOrderRequest createRequest) { -@@ -69,21 +80,41 @@ public class AdminOrderController { - } - } - -- @ApiOperation("报价预览") -+ @ApiOperation(value = "报价预览", notes = "根据产品、出发日期、人数组合实时计算报价。\n" + -+ "返回各资源明细价格和合计金额,前端据此展示报价清单。\n\n" + -+ "注意:报价仅供参考,最终价格以创建订单时为准(价格日历可能变动)") - @PostMapping("/quote") - public Result> quotePreview(@ApiParam("报价预览请求") @Valid @RequestBody QuotePreviewRequest quoteRequest) { - Map result = orderService.quotePreview(quoteRequest); - return Result.success(result); - } - -- @ApiOperation("订单列表") -+ @ApiOperation(value = "订单列表", notes = "支持按关键词(订单号/联系人/产品名)、状态、内部流程状态、产品类型筛选。\n" + -+ "支持按创建时间/出发日期/总价排序。\n\n" + -+ "返回分页结果,包含订单基本信息、状态、支付信息和产品封面\n\n" + -+ "【关联字典】\n" + -+ "- 筛选参数 status → 字典:order_status(订单状态)\n" + -+ "- 筛选参数 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 筛选参数 productType → 字典:product_type(产品类型)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/list") - public Result> listOrders(@ApiParam("订单查询请求") AdminOrderQueryRequest request) { - PageResult result = orderService.listAdminOrders(request); - return Result.success(result); - } - -- @ApiOperation("订单详情") -+ @ApiOperation(value = "订单详情", notes = "返回订单完整信息,包括:基本信息、产品快照、联系人、出行人列表、支付记录、优惠明细、时间线、内部流程状态等\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)\n" + -+ "- 返回字段 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 返回字段 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 返回字段 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 timeline[].action → 字典:order_timeline_action(订单操作类型)\n" + -+ "- 返回字段 todos[].todoType → 字典:order_todo_type(订单待办类型)") - @GetMapping("/{orderId}") - public Result getOrder(@ApiParam("订单ID") @PathVariable Long orderId) { - OrderDetailVO detail = orderService.getAdminOrderDetail(orderId); -@@ -111,7 +142,9 @@ public class AdminOrderController { - "- 旅行中 → 已完成\n" + - "- 已完成 → 售后中\n" + - "- 售后中 → 退款中\n" + -- "- 退款中 → 已退款") -+ "- 退款中 → 已退款\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 status → 字典:order_status(订单状态)") - @PutMapping("/{orderId}/status") - public Result updateStatus(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -134,7 +167,7 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("添加备注") -+ @ApiOperation(value = "添加备注", notes = "向订单时间线添加一条管理员备注。备注会记录操作人和时间,可用于内部沟通和订单跟踪") - @PostMapping("/{orderId}/remark") - public Result addRemark(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -145,7 +178,8 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("修改定金金额") -+ @ApiOperation(value = "修改定金金额", notes = "修改订单的定金金额。仅待支付(PENDING_PAY)状态可修改。\n\n" + -+ "定金金额不能超过订单总价,修改后影响用户支付页面显示的应付金额") - @PutMapping("/{orderId}/deposit") - public Result updateDeposit(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -156,7 +190,14 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("编辑订单") -+ @ApiOperation(value = "编辑订单", notes = "修改订单的联系人、人数、出发日期、售价、成本、备注等信息。\n" + -+ "仅传入需要修改的字段,未传入的字段不会被修改。\n\n" + -+ "如果提供了出行人列表(travelers),将替换订单的全部出行人。\n" + -+ "已锁定的订单需先调用'申请修改'接口解锁后才能编辑\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 请求参数 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 请求参数 travelers[].gender → 字典:gender(性别)") - @PutMapping("/{orderId}") - public Result editOrder(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -167,7 +208,8 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("更新房间信息(仅房务管理员/超级管理员)") -+ @ApiOperation(value = "更新房间信息(仅房务管理员/超级管理员)", -+ notes = "更新订单的房间分配信息(房型、房间号、入住安排等)。\n\n**权限**:仅ROOM_MANAGER(房务管理员)或SUPER_ADMIN(超级管理员)可操作。") - @PutMapping("/{orderId}/room-info") - public Result updateRoomInfo(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -183,7 +225,8 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("更新车辆信息(仅车务管理员/超级管理员)") -+ @ApiOperation(value = "更新车辆信息(仅车务管理员/超级管理员)", -+ notes = "更新订单的车辆分配信息(车型、车牌号、司机等)。\n\n**权限**:仅VEHICLE_MANAGER(车务管理员)或SUPER_ADMIN(超级管理员)可操作。") - @PutMapping("/{orderId}/vehicle-info") - public Result updateVehicleInfo(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -210,7 +253,9 @@ public class AdminOrderController { - } - - @ApiOperation(value = "推进内部流程", notes = "内部流程推进顺序:待配房(PENDING_ROOM) → 待配车(PENDING_VEHICLE) → 待核算(PENDING_FINANCE) → 就绪(READY)\n\n" + -- "仅在订单状态为已确认(CONFIRMED)时有效,每次调用自动推进到下一步") -+ "仅在订单状态为已确认(CONFIRMED)时有效,每次调用自动推进到下一步\n\n" + -+ "【关联字典】\n" + -+ "- 涉及字段 processStatus → 字典:order_process_status(订单内部流程状态)") - @PutMapping("/{orderId}/process-status") - public Result advanceProcessStatus(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId) { -@@ -220,7 +265,8 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("添加优惠项") -+ @ApiOperation(value = "添加优惠项", notes = "为订单添加手动优惠(如会员折扣、老客优惠等)。\n" + -+ "添加后系统自动重算订单应付金额。一个订单可添加多个优惠项") - @PostMapping("/{orderId}/discount") - public Result addDiscount(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -231,7 +277,7 @@ public class AdminOrderController { - return Result.success(discount); - } - -- @ApiOperation("修改优惠项") -+ @ApiOperation(value = "修改优惠项", notes = "修改已添加的优惠项名称或金额,修改后自动重算订单应付金额") - @PutMapping("/{orderId}/discount/{discountId}") - public Result updateDiscount(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -243,7 +289,7 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("删除优惠项") -+ @ApiOperation(value = "删除优惠项", notes = "删除已添加的优惠项,删除后自动重算订单应付金额") - @DeleteMapping("/{orderId}/discount/{discountId}") - public Result removeDiscount(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -296,7 +342,8 @@ public class AdminOrderController { - return Result.success(diff); - } - -- @ApiOperation("分配车辆信息") -+ @ApiOperation(value = "分配车辆信息", notes = "为订单分配具体的车辆和司机信息(车型、品牌、车牌号、司机姓名和电话)。\n" + -+ "分配后信息将展示在订单详情和C端行程中") - @PutMapping("/{orderId}/vehicle-assignment") - public Result assignVehicle(@ApiParam("订单ID") @PathVariable Long orderId, - @RequestBody @Valid VehicleAssignmentRequest request) { -@@ -304,7 +351,8 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("分配酒店信息") -+ @ApiOperation(value = "分配酒店信息", notes = "按家庭为订单分配具体的酒店房间(酒店名称、房型、入住/退房日期)。\n" + -+ "每个家庭对应一条分配记录,分配后信息将展示在订单详情和C端行程中") - @PutMapping("/{orderId}/hotel-assignment") - public Result assignHotel(@ApiParam("订单ID") @PathVariable Long orderId, - @RequestBody @Valid HotelAssignmentRequest request) { -@@ -312,7 +360,7 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("设置尾款支付方式") -+ @ApiOperation(value = "设置尾款支付方式", notes = "设置订单尾款的支付方式。ONLINE=线上微信支付,OFFLINE=线下转账(需管理员手动记录尾款到账)") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderItineraryController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderItineraryController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderItineraryController.java -index 83ae39c..9ab5d5e 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderItineraryController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderItineraryController.java -@@ -31,7 +31,11 @@ public class AdminOrderItineraryController { - private final OrderItineraryEditService itineraryEditService; - private final OrderPriceDiffService priceDiffService; - -- @ApiOperation(value = "跳过节点", notes = "将行程中的某个节点标记为跳过(客户不去)") -+ @ApiOperation(value = "跳过节点", notes = "将行程中的某个节点标记为跳过(客户不去)\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PostMapping("/skip") - public Result skipNode( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -43,7 +47,10 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.skipNode(orderId, request, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "恢复跳过的节点", notes = "取消跳过,恢复为正常状态") -+ @ApiOperation(value = "恢复跳过的节点", notes = "取消跳过,恢复为正常状态\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @DeleteMapping("/skip/{editId}") - public Result unskipNode( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -58,7 +65,11 @@ public class AdminOrderItineraryController { - return Result.success(); - } - -- @ApiOperation(value = "新增节点", notes = "在某一天的行程中新增一个节点") -+ @ApiOperation(value = "新增节点", notes = "在某一天的行程中新增一个节点\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PostMapping("/add") - public Result addNode( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -76,7 +87,10 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.addNode(orderId, request, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "删除新增的节点", notes = "删除通过编辑新增的节点") -+ @ApiOperation(value = "删除新增的节点", notes = "删除通过编辑新增的节点\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @DeleteMapping("/add/{editId}") - public Result removeAddedNode( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -91,7 +105,10 @@ public class AdminOrderItineraryController { - return Result.success(); - } - -- @ApiOperation("获取合并后的行程(原始+编辑)") -+ @ApiOperation(value = "获取合并后的行程(原始+编辑)", notes = "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @GetMapping("/merged") - public Result>> getMergedItinerary( - @ApiParam("订单ID") @PathVariable Long orderId) { -@@ -105,14 +122,19 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.getBalanceAdjustmentSummary(orderId)); - } - -- @ApiOperation("获取行程编辑记录列表") -+ @ApiOperation(value = "获取行程编辑记录列表", notes = "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @GetMapping("/edits") - public Result> getEditList( - @ApiParam("订单ID") @PathVariable Long orderId) { - return Result.success(itineraryEditService.getEditList(orderId)); - } - -- @ApiOperation(value = "房型切换差价预览", notes = "预览房型切换的差价,不创建记录") -+ @ApiOperation(value = "房型切换差价预览", notes = "预览房型切换的差价,不创建记录\n\n" + -+ "**关联字典**:\n" + -+ "- resource_type(资源类型,返回字段resourceType):HOTEL=酒店") - @PostMapping("/room-type-change/preview") - public Result previewRoomTypeChange( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -120,7 +142,11 @@ public class AdminOrderItineraryController { - return Result.success(priceDiffService.previewRoomTypeDiff(orderId, request)); - } - -- @ApiOperation(value = "房型切换", notes = "执行房型切换,自动计算差价,创建待确认记录") -+ @ApiOperation(value = "房型切换", notes = "执行房型切换,自动计算差价,创建待确认记录\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):ROOM_CHANGE=房型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):HOTEL=酒店") - @PostMapping("/room-type-change") - public Result roomTypeChange( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -132,7 +158,9 @@ public class AdminOrderItineraryController { - return Result.success(priceDiffService.executeRoomTypeChange(orderId, request, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "车型切换差价预览", notes = "预览车型切换的差价,不创建记录") -+ @ApiOperation(value = "车型切换差价预览", notes = "预览车型切换的差价,不创建记录\n\n" + -+ "**关联字典**:\n" + -+ "- resource_type(资源类型,返回字段resourceType):VEHICLE=车辆") - @PostMapping("/vehicle-type-change/preview") - public Result previewVehicleTypeChange( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -140,7 +168,11 @@ public class AdminOrderItineraryController { - return Result.success(priceDiffService.previewVehicleTypeDiff(orderId, request)); - } - -- @ApiOperation(value = "车型切换", notes = "执行车型切换,自动计算差价,创建待确认记录") -+ @ApiOperation(value = "车型切换", notes = "执行车型切换,自动计算差价,创建待确认记录\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):VEHICLE=车辆") - @PostMapping("/vehicle-type-change") - public Result vehicleTypeChange( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -152,7 +184,11 @@ public class AdminOrderItineraryController { - return Result.success(priceDiffService.executeVehicleTypeChange(orderId, request, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "新增整天行程", notes = "在订单行程中新增一整天(含多个节点)") -+ @ApiOperation(value = "新增整天行程", notes = "在订单行程中新增一整天(含多个节点)\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):ADD_DAY=新增整天\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PostMapping("/add-day") - public Result> addDay( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -164,7 +200,9 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.addDay(orderId, request, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "删除新增的整天行程", notes = "删除通过新增操作添加的整天行程及其所有子节点,已确认的天不允许删除") -+ @ApiOperation(value = "删除新增的整天行程", notes = "删除通过新增操作添加的整天行程及其所有子节点,已确认的天不允许删除\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @DeleteMapping("/day/{editId}") - public Result removeDay( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -179,7 +217,11 @@ public class AdminOrderItineraryController { - return Result.success(); - } - -- @ApiOperation(value = "修改编辑记录", notes = "修改待确认状态的编辑记录(如调整价格、名称等)") -+ @ApiOperation(value = "修改编辑记录", notes = "修改待确认状态的编辑记录(如调整价格、名称等)\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PutMapping("/edit/{editId}") - public Result updateEdit( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -192,7 +234,9 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.updateEdit(orderId, editId, updates, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "确认单条修改", notes = "确认一条待确认的行程编辑") -+ @ApiOperation(value = "确认单条修改", notes = "确认一条待确认的行程编辑\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @PostMapping("/confirm/{editId}") - public Result confirmEdit( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -205,7 +249,9 @@ public class AdminOrderItineraryController { - return Result.success(); - } - -- @ApiOperation(value = "批量确认所有待确认修改", notes = "确认该订单所有待确认的行程编辑") -+ @ApiOperation(value = "批量确认所有待确认修改", notes = "确认该订单所有待确认的行程编辑\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @PostMapping("/confirm-all") - public Result confirmAllPending( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -216,7 +262,9 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.confirmAllPending(orderId, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "撤回待确认的修改", notes = "软删除一条待确认的编辑记录") -+ @ApiOperation(value = "撤回待确认的修改", notes = "软删除一条待确认的编辑记录\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @DeleteMapping("/pending/{editId}") - public Result withdrawPendingEdit( - @ApiParam("订单ID") @PathVariable Long orderId, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderTodoController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderTodoController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderTodoController.java -index d7339d2..f708a7f 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderTodoController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderTodoController.java -@@ -29,14 +29,21 @@ public class AdminOrderTodoController { - private final OrderService orderService; - private final UserFeignClient userFeignClient; - -- @ApiOperation("获取订单待办列表") -+ @ApiOperation(value = "获取订单待办列表", notes = "返回指定订单的所有待办项(含已完成和未完成)。\n" + -+ "待办类型包括:配房、配车、签合同、购保险、核算等,随内部流程自动生成\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 todoType → 字典:order_todo_type(订单待办类型)") - @GetMapping("/{orderId}/todos") - public Result> getOrderTodos(@ApiParam("订单ID") @PathVariable Long orderId) { - List todos = orderTodoService.listByOrderId(orderId); - return Result.success(todos); - } - -- @ApiOperation("完成待办") -+ @ApiOperation(value = "完成待办", notes = "将指定待办标记为已完成。\n" + -+ "需要对应角色权限:如配房待办需ROOM_MANAGER角色,配车待办需VEHICLE_MANAGER角色。\n\n" + -+ "完成后系统自动检查是否所有必要待办已完成,若是则推进内部流程\n\n" + -+ "【关联字典】\n" + -+ "- 涉及字段 todoType → 字典:order_todo_type(订单待办类型)") - @PutMapping("/todo/{todoId}/complete") - public Result completeTodo(HttpServletRequest request, - @ApiParam("待办ID") @PathVariable Long todoId) { -@@ -47,7 +54,11 @@ public class AdminOrderTodoController { - return Result.success(); - } - -- @ApiOperation("我的待办列表") -+ @ApiOperation(value = "我的待办列表", notes = "根据当前管理员ID和角色,查询分配给自己的未完成待办。\n" + -+ "超级管理员可看到所有待办,其他角色只能看到对应类型的待办\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 todoType → 字典:order_todo_type(订单待办类型)\n" + -+ "- 返回字段 orderStatus → 字典:order_status(订单状态)") - @GetMapping("/todo/my-list") - public Result> getMyTodos(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -56,7 +67,7 @@ public class AdminOrderTodoController { - return Result.success(todos); - } - -- @ApiOperation("我的待办数量") -+ @ApiOperation(value = "我的待办数量", notes = "返回当前管理员未完成的待办总数,用于首页角标/红点提醒") - @GetMapping("/todo/my-count") - public Result getMyTodosCount(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -65,7 +76,7 @@ public class AdminOrderTodoController { - return Result.success(count); - } - -- @ApiOperation("定制师列表") -+ @ApiOperation(value = "定制师列表", notes = "获取所有定制师(CUSTOMIZER角色)的列表,用于更换定制师时选择目标定制师") - @GetMapping("/todo/customizer-list") - public Result> getCustomizerList() { - try { -@@ -79,7 +90,7 @@ public class AdminOrderTodoController { - return Result.success(Collections.emptyList()); - } - -- @ApiOperation("更换定制师") -+ @ApiOperation(value = "更换定制师", notes = "将订单转派给另一位定制师。更换后原定制师的待办自动转移,订单时间线会记录此操作") - @PutMapping("/{orderId}/customizer") - public Result changeCustomizer(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -90,7 +101,11 @@ public class AdminOrderTodoController { - return Result.success(); - } - -- @ApiOperation("可签合同订单列表(保险已完成)") -+ @ApiOperation(value = "可签合同订单列表(保险已完成)", notes = "查询保险待办已完成、可以进入签合同环节的订单列表。\n" + -+ "用于合同管理页面展示待签合同的订单\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 todoType → 字典:order_todo_type(订单待办类型)\n" + -+ "- 返回字段 orderStatus → 字典:order_status(订单状态)") - @GetMapping("/todo/contract-eligible") - public Result> getContractEligibleOrders(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundController.java -index fddef53..eb92d44 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundController.java -@@ -31,7 +31,11 @@ public class AdminRefundController { - - // ==================== Refund Applications ==================== - -- @ApiOperation("退款申请列表") -+ @ApiOperation(value = "退款申请列表", notes = "分页查询退款申请,支持按状态筛选。\n" + -+ "状态包括:PENDING(待审批)、APPROVED(已通过)、REJECTED(已拒绝)、REFUNDING(退款中)、REFUNDED(已退款)、CANCELLED(已撤回)、APPEAL(申诉中)\n\n" + -+ "【关联字典】\n" + -+ "- 筛选参数 status → 字典:refund_status(退款状态)\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @GetMapping("/list") - public Result> listApplications( - @ApiParam("状态") @RequestParam(required = false) String status, -@@ -40,14 +44,18 @@ public class AdminRefundController { - return Result.success(refundApplicationService.listApplications(status, page, pageSize)); - } - -- @ApiOperation("退款申请详情") -+ @ApiOperation(value = "退款申请详情", notes = "返回退款申请的完整信息,包括退款原因、申请金额、实退金额、审批记录、申诉信息等\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @GetMapping("/{applicationId}") - public Result getDetail(@ApiParam("退款申请ID") @PathVariable Long applicationId) { - return Result.success(refundApplicationService.getDetail(applicationId)); - } - - @ApiOperation(value = "审批退款申请", notes = "退款审批流程:查看退款申请 → 决定通过/拒绝 → 通过时填写实退金额 → 系统自动调起微信退款\n\n" + -- "拒绝后用户可发起申诉") -+ "拒绝后用户可发起申诉\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @PutMapping("/{applicationId}/review") - public Result review(HttpServletRequest request, - @ApiParam("退款申请ID") @PathVariable Long applicationId, -@@ -79,20 +87,26 @@ public class AdminRefundController { - - // ==================== Refund Reasons ==================== - -- @ApiOperation("退款原因列表") -+ @ApiOperation(value = "退款原因列表", notes = "获取所有退款原因选项(含禁用的),用于退款原因管理页面\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 category → 字典:refund_reason_category(退款原因分类)") - @GetMapping("/reason/list") - public Result> listReasons() { - return Result.success(refundReasonService.listReasons(false)); - } - -- @ApiOperation("创建退款原因") -+ @ApiOperation(value = "创建退款原因", notes = "新增退款原因选项,C端用户申请退款时可选择。按sortOrder排序展示\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 category → 字典:refund_reason_category(退款原因分类)") - @PostMapping("/reason") - public Result createReason(@ApiParam("创建退款原因请求") @Valid @RequestBody CreateRefundReasonRequest createRequest) { - return Result.success(refundReasonService.createReason( - createRequest.getReasonText(), createRequest.getCategory(), createRequest.getSortOrder())); - } - -- @ApiOperation("修改退款原因") -+ @ApiOperation(value = "修改退款原因", notes = "修改退款原因的文本、分类或排序,不影响已使用该原因的历史退款申请\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 category → 字典:refund_reason_category(退款原因分类)") - @PutMapping("/reason/{reasonId}") - public Result updateReason(@ApiParam("退款原因ID") @PathVariable Long reasonId, - @ApiParam("修改退款原因请求") @Valid @RequestBody UpdateRefundReasonRequest updateRequest) { -@@ -100,7 +114,7 @@ public class AdminRefundController { - reasonId, updateRequest.getReasonText(), updateRequest.getCategory(), updateRequest.getSortOrder())); - } - -- @ApiOperation("删除退款原因") -+ @ApiOperation(value = "删除退款原因", notes = "软删除退款原因,删除后C端不再展示。不影响已使用该原因的历史退款申请") - @DeleteMapping("/reason/{reasonId}") - public Result deleteReason(@ApiParam("退款原因ID") @PathVariable Long reasonId) { - refundReasonService.deleteReason(reasonId); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundPolicyController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundPolicyController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundPolicyController.java -index 9ff5005..e1bc0c8 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundPolicyController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundPolicyController.java -@@ -22,13 +22,17 @@ public class AdminRefundPolicyController { - - private final RefundPolicyService refundPolicyService; - -- @ApiOperation("退款政策列表") -+ @ApiOperation(value = "退款政策列表", notes = "【关联字典】\n" + -+ "- 返回字段 refundType → 字典:refund_type(退款类型)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/list") - public Result> list() { - return Result.success(refundPolicyService.listPolicies()); - } - -- @ApiOperation("退款政策详情") -+ @ApiOperation(value = "退款政策详情", notes = "【关联字典】\n" + -+ "- 返回字段 refundType → 字典:refund_type(退款类型)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/{policyId}") - public Result detail(@ApiParam("退款政策ID") @PathVariable Long policyId) { - return Result.success(refundPolicyService.getDetail(policyId)); -@@ -36,7 +40,10 @@ public class AdminRefundPolicyController { - - @ApiOperation(value = "创建退款政策", notes = "退款政策定义按产品类型和距出发天数的退款比例阶梯\n\n" + - "例如:出发前30天退90%,前15天退70%,前7天退50%,7天内不可退\n\n" + -- "每种产品类型可配置独立的退款政策,用户申请退款时系统自动匹配") -+ "每种产品类型可配置独立的退款政策,用户申请退款时系统自动匹配\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 refundType → 字典:refund_type(退款类型)\n" + -+ "- 请求参数 productType → 字典:product_type(产品类型)") - @PostMapping - public Result create(HttpServletRequest request, - @ApiParam("创建退款政策请求") @Valid @RequestBody RefundPolicyRequest policyRequest) { -@@ -44,14 +51,17 @@ public class AdminRefundPolicyController { - return Result.success(refundPolicyService.createPolicy(policyRequest, adminId)); - } - -- @ApiOperation("修改退款政策") -+ @ApiOperation(value = "修改退款政策", notes = "【关联字典】\n" + -+ "- 请求参数 refundType → 字典:refund_type(退款类型)\n" + -+ "- 请求参数 productType → 字典:product_type(产品类型)") - @PutMapping("/{policyId}") - public Result update(@ApiParam("退款政策ID") @PathVariable Long policyId, - @ApiParam("修改退款政策请求") @Valid @RequestBody RefundPolicyRequest policyRequest) { - return Result.success(refundPolicyService.updatePolicy(policyId, policyRequest)); - } - -- @ApiOperation("删除退款政策") -+ @ApiOperation(value = "删除退款政策", -+ notes = "软删除退款政策。删除后该产品类型将使用默认退款规则。不影响已使用该政策处理的历史退款申请。") - @DeleteMapping("/{policyId}") - public Result delete(@ApiParam("退款政策ID") @PathVariable Long policyId) { - refundPolicyService.deletePolicy(policyId); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminWorkOrderController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminWorkOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminWorkOrderController.java -index 949f142..faf973b 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminWorkOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminWorkOrderController.java -@@ -25,7 +25,15 @@ public class AdminWorkOrderController { - - private final WorkOrderService workOrderService; - -- @ApiOperation("工单列表") -+ @ApiOperation(value = "工单列表", notes = "分页查询工单,支持按状态/类型/优先级/订单编号/处理人筛选。\n" + -+ "工单用于处理旅行中的突发变更需求(如换房、换车、加景点等)\n\n" + -+ "【关联字典】\n" + -+ "- 筛选参数 status → 字典:work_order_status(工单状态)\n" + -+ "- 筛选参数 type → 字典:work_order_type(工单类型)\n" + -+ "- 筛选参数 priority → 字典:work_order_priority(工单优先级)\n" + -+ "- 返回字段 status → 字典:work_order_status(工单状态)\n" + -+ "- 返回字段 type → 字典:work_order_type(工单类型)\n" + -+ "- 返回字段 priority → 字典:work_order_priority(工单优先级)") - @GetMapping("/list") - public Result> list( - @ApiParam("状态: PENDING/PROCESSING/RESOLVED/REJECTED") @RequestParam(required = false) String status, -@@ -38,19 +46,32 @@ public class AdminWorkOrderController { - return Result.success(workOrderService.listWorkOrders(status, type, priority, orderNo, assigneeAdminId, page, pageSize)); - } - -- @ApiOperation("工单详情") -+ @ApiOperation(value = "工单详情", notes = "返回工单完整信息,包括关联订单、资源详情、处理记录和备注列表\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:work_order_status(工单状态)\n" + -+ "- 返回字段 type → 字典:work_order_type(工单类型)\n" + -+ "- 返回字段 priority → 字典:work_order_priority(工单优先级)") - @GetMapping("/{workOrderId}") - public Result getDetail(@ApiParam("工单ID") @PathVariable Long workOrderId) { - return Result.success(workOrderService.getDetail(workOrderId)); - } - -- @ApiOperation("工单统计(待处理数等)") -+ @ApiOperation(value = "工单统计", notes = "返回各状态的工单数量和紧急工单数,用于工单管理页面顶部统计卡片\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段中的状态key → 字典:work_order_status(工单状态)") - @GetMapping("/stats") - public Result> getStats() { - return Result.success(workOrderService.getStats()); - } - -- @ApiOperation("创建工单") -+ @ApiOperation(value = "创建工单", notes = "创建旅途中的变更工单,需关联订单ID。\n" + -+ "可指定处理人,未指定则进入待分配状态。可附带差价信息和资源详情JSON\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 type → 字典:work_order_type(工单类型)\n" + -+ "- 请求参数 priority → 字典:work_order_priority(工单优先级)\n" + -+ "- 返回字段 status → 字典:work_order_status(工单状态)\n" + -+ "- 返回字段 type → 字典:work_order_type(工单类型)\n" + -+ "- 返回字段 priority → 字典:work_order_priority(工单优先级)") - @PostMapping - public Result create(HttpServletRequest request, - @Valid @RequestBody CreateWorkOrderRequest body) { -@@ -59,7 +80,10 @@ public class AdminWorkOrderController { - return Result.success(workOrderService.createWorkOrder(adminId, adminName, body)); - } - -- @ApiOperation("处理工单(解决/驳回)") -+ @ApiOperation(value = "处理工单(解决/驳回)", notes = "解决时需填写处理结果(resolution),驳回时需填写驳回原因(rejectReason)。\n" + -+ "可调整差价(costDifference),正数表示加价,负数表示退费\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:work_order_status(工单状态)") - @PutMapping("/{workOrderId}/process") - public Result process(HttpServletRequest request, - @ApiParam("工单ID") @PathVariable Long workOrderId, -@@ -69,7 +93,7 @@ public class AdminWorkOrderController { - return Result.success(workOrderService.processWorkOrder(workOrderId, adminId, adminName, body)); - } - -- @ApiOperation("指派工单") -+ @ApiOperation(value = "指派工单", notes = "将工单分配给指定管理员处理。被指派人将在待办列表中看到该工单") - @PutMapping("/{workOrderId}/assign") - public Result assign(HttpServletRequest request, - @ApiParam("工单ID") @PathVariable Long workOrderId, -@@ -80,7 +104,7 @@ public class AdminWorkOrderController { - return Result.success(workOrderService.assignWorkOrder(workOrderId, adminId, adminName, assigneeId, assigneeName)); - } - -- @ApiOperation("添加备注") -+ @ApiOperation(value = "添加工单备注", notes = "在工单中追加备注信息,用于内部沟通和处理过程记录") - @PostMapping("/{workOrderId}/comment") - public Result addComment(HttpServletRequest request, - @ApiParam("工单ID") @PathVariable Long workOrderId, -@@ -94,7 +118,7 @@ public class AdminWorkOrderController { - return Result.success(workOrderService.addComment(workOrderId, adminId, adminName, content)); - } - -- @ApiOperation("按订单查工单数量") -+ @ApiOperation(value = "按订单查工单数量", notes = "返回指定订单关联的工单总数,用于订单详情页展示工单角标") - @GetMapping("/count-by-order/{orderId}") - public Result countByOrder(@ApiParam("订单ID") @PathVariable Long orderId) { - return Result.success(workOrderService.countByOrderId(orderId)); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalAlbumController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalAlbumController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalAlbumController.java -index 0d65e46..e8684ef 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalAlbumController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalAlbumController.java -@@ -16,7 +16,7 @@ import java.util.List; - /** - * 相册内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - */ --@Api(tags = "【内部接口】小程序相册(Feign调用)") -+@Api(tags = "【内部接口】小程序相册(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/album") - @RequiredArgsConstructor -@@ -24,13 +24,14 @@ public class InternalAlbumController { - - private final AlbumService albumService; - -- @ApiOperation("用户有相册的订单列表") -+ @ApiOperation(value = "用户有相册的订单列表", notes = "返回用户所有有相册文件夹的订单(含订单基本信息和相册封面),用于C端'我的相册'入口") - @GetMapping("/orders") - public Result> listAlbumOrders(@RequestParam Long userId) { - return Result.success(albumService.listUserAlbumOrders(userId)); - } - -- @ApiOperation("订单的文件夹列表") -+ @ApiOperation(value = "订单的文件夹列表", -+ notes = "内部服务间调用。返回指定用户指定订单下的相册文件夹列表,会校验订单归属权限。") - @GetMapping("/order/{orderId}/folders") - public Result> listFolders( - @RequestParam Long userId, -@@ -38,7 +39,10 @@ public class InternalAlbumController { - return Result.success(albumService.listUserFolders(userId, orderId)); - } - -- @ApiOperation("文件夹下的文件列表") -+ @ApiOperation(value = "文件夹下的文件列表", notes = "**关联字典**:\n" + -+ "- album_file_type(文件类型,返回字段fileType):IMAGE=图片, VIDEO=视频\n" + -+ "- album_location_type(地点类型,返回字段locationType):RESOURCE=关联资源, CUSTOM=自定义地点\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @GetMapping("/folder/{folderId}/files") - public Result> listFiles( - @RequestParam Long userId, -@@ -48,7 +52,7 @@ public class InternalAlbumController { - return Result.success(albumService.listUserFiles(userId, folderId, page, size)); - } - -- @ApiOperation("获取文件下载链接") -+ @ApiOperation(value = "获取文件下载链接", notes = "生成带签名的临时下载URL(有效期1小时),用于C端用户下载原图/视频") - @GetMapping("/file/{albumFileId}/download-url") - public Result getDownloadUrl( - @RequestParam Long userId, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalDashboardController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDashboardController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDashboardController.java -index 0fd0c6a..110daf9 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDashboardController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDashboardController.java -@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "【内部接口】工作台统计(Feign调用)") -+@Api(tags = "【内部接口】工作台统计(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/order/dashboard") - @RequiredArgsConstructor -@@ -19,7 +19,9 @@ public class InternalDashboardController { - - private final DashboardStatsService dashboardStatsService; - -- @ApiOperation("概览统计(支持定制师/全局,支持今日/本周/本月)") -+ @ApiOperation(value = "概览统计", notes = "返回订单量、成交金额、待处理订单数等概览数据。\n" + -+ "传customizerId则返回该定制师的数据,不传则返回全局数据。\n" + -+ "period支持: today(今日)、week(本周)、month(本月)") - @GetMapping("/overview-stats") - public Result> getOverviewStats( - @ApiParam("定制师ID,不传则为全局") @RequestParam(required = false) Long customizerId, -@@ -27,7 +29,9 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getOverviewStats(customizerId, period)); - } - -- @ApiOperation("待办分类汇总") -+ @ApiOperation(value = "待办分类汇总", notes = "按待办类型分组统计当前管理员的未完成待办数量,用于工作台待办卡片展示\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段中的待办类型key → 字典:order_todo_type(订单待办类型)") - @GetMapping("/todo-summary") - public Result> getTodoSummary( - @ApiParam("管理员ID") @RequestParam Long adminId, -@@ -35,7 +39,7 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getTodoSummary(adminId, roleKey)); - } - -- @ApiOperation("数据趋势(按天聚合)") -+ @ApiOperation(value = "数据趋势", notes = "按天聚合的订单量和金额趋势数据,用于折线图展示。支持最近7天或30天") - @GetMapping("/trend") - public Result>> getTrend( - @ApiParam("定制师ID,不传则为全局") @RequestParam(required = false) Long customizerId, -@@ -46,7 +50,9 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getTrend(customizerId, days)); - } - -- @ApiOperation("转化漏斗") -+ @ApiOperation(value = "转化漏斗", notes = "展示订单从创建→支付→确认→完成的转化率漏斗数据\n\n" + -+ "【关联字典】\n" + -+ "- 涉及字段 订单状态 → 字典:order_status(订单状态)") - @GetMapping("/funnel") - public Result> getFunnel( - @ApiParam("定制师ID,不传则为全局") @RequestParam(required = false) Long customizerId, -@@ -54,7 +60,10 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getFunnel(customizerId, period)); - } - -- @ApiOperation("即将出行列表") -+ @ApiOperation(value = "即将出行列表", notes = "返回最近即将出发的订单列表,按出发日期升序。用于工作台提醒关注即将出行的客户\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/upcoming-trips") - public Result>> getUpcomingTrips( - @ApiParam("定制师ID,不传则为全局") @RequestParam(required = false) Long customizerId, -@@ -62,14 +71,14 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getUpcomingTrips(customizerId, limit)); - } - -- @ApiOperation("业绩排行(本月定制师排名)") -+ @ApiOperation(value = "业绩排行", notes = "按定制师维度统计成交金额排名,支持本周/本月周期。用于工作台排行榜展示") - @GetMapping("/ranking") - public Result>> getRanking( - @ApiParam("时间范围: month/week") @RequestParam(defaultValue = "month") String period) { - return Result.success(dashboardStatsService.getRanking(period)); - } - -- @ApiOperation("日历事件") -+ @ApiOperation(value = "日历事件", notes = "返回指定月份的出发日期事件列表,用于工作台日历组件展示。每个事件包含订单基本信息") - @GetMapping("/calendar-events") - public Result>> getCalendarEvents( - @ApiParam("定制师ID") @RequestParam(required = false) Long customizerId, -@@ -78,14 +87,14 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getCalendarEvents(customizerId, year, month)); - } - -- @ApiOperation("财务统计") -+ @ApiOperation(value = "财务统计", notes = "返回收入、成本、利润等财务汇总数据,支持按时间周期统计") - @GetMapping("/finance-stats") - public Result> getFinanceStats( - @ApiParam("时间范围") @RequestParam(defaultValue = "today") String period) { - return Result.success(dashboardStatsService.getFinanceStats(period)); - } - -- @ApiOperation("退款汇总") -+ @ApiOperation(value = "退款汇总", notes = "返回退款总额、退款笔数、退款率等汇总信息。传customizerId可查看单个定制师的退款数据") - @GetMapping("/refund-summary") - public Result> getRefundSummary( - @ApiParam("定制师ID") @RequestParam(required = false) Long customizerId) { -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalDesignerOrderController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDesignerOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDesignerOrderController.java -index bb7a01e..cd52e45 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDesignerOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDesignerOrderController.java -@@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.*; - - import java.util.Map; - --@Api(tags = "【内部接口】定制师订单(Feign调用)") -+@Api(tags = "【内部接口】定制师订单(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/order") - @RequiredArgsConstructor -@@ -20,20 +20,29 @@ public class InternalDesignerOrderController { - - private final OrderService orderService; - -- @ApiOperation("获取定制师订单统计") -+ @ApiOperation(value = "获取定制师订单统计", notes = "返回指定定制师的订单统计数据(各状态数量、总金额等),用于定制师工作台概览\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段中的状态key → 字典:order_status(订单状态)") - @GetMapping("/designer-stats") - public Result> getDesignerOrderStats( - @ApiParam("定制师管理员ID") @RequestParam Long customizerId) { - return Result.success(orderService.getDesignerOrderStats(customizerId)); - } - -- @ApiOperation("获取全局订单统计") -+ @ApiOperation(value = "获取全局订单统计", notes = "返回全平台的订单统计数据(各状态数量、总金额等),用于管理层工作台概览\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段中的状态key → 字典:order_status(订单状态)") - @GetMapping("/global-stats") - public Result> getGlobalOrderStats() { - return Result.success(orderService.getGlobalOrderStats()); - } - -- @ApiOperation("定制师订单列表") -+ @ApiOperation(value = "定制师订单列表", notes = "分页查询指定定制师负责的订单,支持按状态和关键词筛选\n\n" + -+ "【关联字典】\n" + -+ "- 筛选参数 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/designer-list") - public Result> listDesignerOrders( - @ApiParam("定制师管理员ID") @RequestParam Long customizerId, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalEarlyBirdController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalEarlyBirdController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalEarlyBirdController.java -index 97b3871..b1bf9e7 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalEarlyBirdController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalEarlyBirdController.java -@@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.RestController; - import java.math.BigDecimal; - import java.util.List; - --@Api(tags = "【内部接口】早鸟优惠(Feign调用)") -+@Api(tags = "【内部接口】早鸟优惠(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/early-bird") - @RequiredArgsConstructor -@@ -23,14 +23,17 @@ public class InternalEarlyBirdController { - - private final EarlyBirdPlanService earlyBirdPlanService; - -- @ApiOperation("获取当前有效的早鸟优惠计划列表") -+ @ApiOperation(value = "获取当前有效的早鸟优惠计划列表", notes = "返回当前日期处于生效期内且已启用的早鸟计划,C端下单时展示可用优惠") - @GetMapping("/active") - public Result> listActivePlans() { - List plans = earlyBirdPlanService.listActivePlans(); - return Result.success(plans); - } - -- @ApiOperation("匹配最优早鸟优惠计划") -+ @ApiOperation(value = "匹配最优早鸟优惠计划", notes = "根据产品类型、出行人数、订单总价匹配优惠金额最大的早鸟计划。\n" + -+ "无匹配返回null。供下单时自动匹配调用\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 productType → 字典:product_type(产品类型)") - @GetMapping("/match") - public Result matchPlan( - @RequestParam String productType, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalInvoiceController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalInvoiceController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalInvoiceController.java -index e84a0e6..310b627 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalInvoiceController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalInvoiceController.java -@@ -15,7 +15,7 @@ import javax.validation.Valid; - * C端发票内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "【内部接口】小程序发票(Feign调用)") -+@Api(tags = "【内部接口】小程序发票(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/invoice") - @RequiredArgsConstructor -@@ -23,21 +23,33 @@ public class InternalInvoiceController { - - private final InvoiceService invoiceService; - -- @ApiOperation("申请开票") -+ @ApiOperation(value = "申请开票", notes = "用户对已支付订单申请开具电子发票。支持个人和企业抬头。\n" + -+ "同一订单只能开一次发票(可换开)\n\n" + -+ "**关联字典**:\n" + -+ "- invoice_title_type(抬头类型,请求/返回字段titleType):PERSONAL=个人, COMPANY=企业\n" + -+ "- invoice_type(发票类型,返回字段invoiceType):NORMAL=普通发票, SPECIAL=专用发票\n" + -+ "- invoice_status(发票状态,返回字段status):PENDING=待开票, ISSUED=已开票, FAILED=开票失败, CANCELLED=已作废") - @PostMapping("/apply") - public Result applyInvoice(@RequestParam Long userId, - @Valid @RequestBody InvoiceApplyRequest request) { - return Result.success(invoiceService.applyInvoice(userId, request)); - } - -- @ApiOperation("发票详情") -+ @ApiOperation(value = "发票详情", notes = "**关联字典**:\n" + -+ "- invoice_title_type(抬头类型,返回字段titleType):PERSONAL=个人, COMPANY=企业\n" + -+ "- invoice_type(发票类型,返回字段invoiceType):NORMAL=普通发票, SPECIAL=专用发票\n" + -+ "- invoice_status(发票状态,返回字段status):PENDING=待开票, ISSUED=已开票, FAILED=开票失败, CANCELLED=已作废") - @GetMapping("/{id}") - public Result getInvoiceDetail(@RequestParam Long userId, - @PathVariable Long id) { - return Result.success(invoiceService.getInvoiceDetail(userId, id)); - } - -- @ApiOperation("通过订单ID查询发票") -+ @ApiOperation(value = "通过订单ID查询发票", notes = "查询订单关联的发票信息。未开票时返回null\n\n" + -+ "**关联字典**:\n" + -+ "- invoice_title_type(抬头类型,返回字段titleType):PERSONAL=个人, COMPANY=企业\n" + -+ "- invoice_type(发票类型,返回字段invoiceType):NORMAL=普通发票, SPECIAL=专用发票\n" + -+ "- invoice_status(发票状态,返回字段status):PENDING=待开票, ISSUED=已开票, FAILED=开票失败, CANCELLED=已作废") - @GetMapping("/order/{orderId}") - public Result getInvoiceByOrderId(@RequestParam Long userId, - @PathVariable Long orderId) { -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpOrderController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpOrderController.java -index c27da3a..ec5f305 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpOrderController.java -@@ -24,7 +24,7 @@ import java.util.Map; - * C端订单内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "【内部接口】小程序订单(Feign调用)") -+@Api(tags = "【内部接口】小程序订单(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/order") - @RequiredArgsConstructor -@@ -32,7 +32,13 @@ public class InternalMpOrderController { - - private final OrderService orderService; - -- @ApiOperation("创建订单") -+ @ApiOperation(value = "创建订单", notes = "供BFF层调用的C端下单接口。创建后返回订单详情(含支付信息),前端可直接跳转支付\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 请求参数 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 请求参数 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @PostMapping("/create") - public Result createOrder(@RequestParam Long userId, - @Valid @RequestBody CreateOrderRequest request) { -@@ -41,21 +47,32 @@ public class InternalMpOrderController { - return Result.success(detail); - } - -- @ApiOperation("订单列表") -+ @ApiOperation(value = "订单列表", notes = "【关联字典】\n" + -+ "- 筛选参数 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/list") - public Result> listOrders(@RequestParam Long userId, - MpOrderQueryRequest query) { - return Result.success(orderService.listUserOrders(userId, query)); - } - -- @ApiOperation("订单详情") -+ @ApiOperation(value = "订单详情", notes = "【关联字典】\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)\n" + -+ "- 返回字段 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 返回字段 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 返回字段 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 timeline[].action → 字典:order_timeline_action(订单操作类型)") - @GetMapping("/{orderId}") - public Result getOrder(@RequestParam Long userId, - @PathVariable Long orderId) { - return Result.success(orderService.getUserOrderDetail(userId, orderId)); - } - -- @ApiOperation("取消订单") -+ @ApiOperation(value = "取消订单", -+ notes = "内部服务间调用,供BFF层调用的用户取消订单接口。仅允许取消待支付/已付定金状态的订单。") - @PostMapping("/{orderId}/cancel") - public Result cancelOrder(@RequestParam Long userId, - @PathVariable Long orderId, -@@ -65,7 +82,8 @@ public class InternalMpOrderController { - return Result.success(); - } - -- @ApiOperation("订单资源详情(按分类)") -+ @ApiOperation(value = "订单资源详情(按分类)", -+ notes = "内部服务间调用。解析订单的产品快照JSON,按资源类型分类提取资源详情(景区/酒店/活动/餐厅等),返回Map结构。") - @GetMapping("/{orderId}/resources") - public Result>>> getOrderResources( - @RequestParam Long userId, -@@ -73,7 +91,7 @@ public class InternalMpOrderController { - return Result.success(orderService.getOrderSnapshotResources(userId, orderId)); - } - -- @ApiOperation("通过联系人手机号+姓名查找订单(无需登录)") -+ @ApiOperation(value = "通过联系人手机号+姓名查找订单", notes = "无需登录。用于管理员代下单场景:管理员创建订单后用户通过手机号+姓名查找并绑定订单") - @GetMapping("/lookup") - public Result> lookupByContact( - @RequestParam String contactPhone, -@@ -81,7 +99,8 @@ public class InternalMpOrderController { - return Result.success(orderService.lookupByContact(contactPhone, contactName)); - } - -- @ApiOperation("绑定未绑定的订单(通过联系人手机号+姓名)") -+ @ApiOperation(value = "绑定未绑定的订单", notes = "将userId=NULL且联系人手机号+姓名匹配的订单绑定到当前用户。\n" + -+ "用于管理员代下单后用户登录自动关联订单。返回绑定的订单数量") - @PostMapping("/bind-by-contact") - public Result bindByContact(@RequestParam Long userId, - @Valid @RequestBody BindByContactRequest request) { -@@ -89,7 +108,7 @@ public class InternalMpOrderController { - return Result.success(bindCount); - } - -- @ApiOperation("客户同意解锁订单") -+ @ApiOperation(value = "客户同意解锁订单", notes = "管理员申请修改锁定订单后,C端用户确认同意解锁。解锁后管理员可重新编辑订单") - @PostMapping("/{orderId}/approve-unlock") - public Result approveUnlock(@RequestParam Long userId, - @PathVariable Long orderId) { -@@ -103,13 +122,16 @@ public class InternalMpOrderController { - return Result.success(orderService.getUpcomingDepartures(userId)); - } - -- @ApiOperation("各状态订单数量") -+ @ApiOperation(value = "各状态订单数量", notes = "返回用户各状态的订单数量Map,用于小程序订单页Tab角标显示\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段中的状态key → 字典:order_status(订单状态)") - @GetMapping("/count") - public Result> countByStatus(@RequestParam Long userId) { - return Result.success(orderService.countByStatusForUser(userId)); - } - -- @ApiOperation("标记订单已评价(评价服务回调)") -+ @ApiOperation(value = "标记订单已评价", notes = "评价服务(review-service)在用户发布评价后回调此接口,将订单标记为已评价。\n" + -+ "标记后订单详情不再显示'去评价'按钮") - @PutMapping("/{orderId}/mark-reviewed") - public Result markReviewed(@PathVariable Long orderId) { - orderService.markReviewed(orderId); -@@ -118,7 +140,13 @@ public class InternalMpOrderController { - - @ApiOperation(value = "用户修改订单", notes = "用户可修改出发日期和出行人,修改后重走内部流程(级联检测+价格重算)。" + - "仅待支付/已付定金/已支付/已确认/待付尾款/待出发状态可修改。" + -- "内部流程已启动的订单修改后会通知定制师,返回message中包含提示") -+ "内部流程已启动的订单修改后会通知定制师,返回message中包含提示\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 请求参数 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 请求参数 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @PutMapping("/{orderId}/edit") - public Result userEditOrder(@RequestParam Long userId, - @PathVariable Long orderId, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpTripController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpTripController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpTripController.java -index db0d1cc..8e4b990 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpTripController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpTripController.java -@@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "【内部接口】小程序行程(Feign调用)") -+@Api(tags = "【内部接口】小程序行程(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/trip") - @RequiredArgsConstructor -@@ -18,20 +18,29 @@ public class InternalMpTripController { - - private final TripService tripService; - -- @ApiOperation("行程列表") -+ @ApiOperation(value = "行程列表", notes = "返回用户所有有效订单的行程概要列表(已确认/待出发/出行中/已完成),按出发日期排序\n\n" + -+ "**关联字典**:\n" + -+ "- order_status(订单状态,返回字段status):CONFIRMED=已确认, PENDING_DEPARTURE=待出发, TRAVELLING=出行中, COMPLETED=已完成\n" + -+ "- trip_phase(行程阶段,返回字段tripPhase):BEFORE_START=出发前, IN_PROGRESS=出行中, ENDED=已结束") - @GetMapping("/list") - public Result>> getTripList(@RequestParam Long userId) { - return Result.success(tripService.getTripList(userId)); - } - -- @ApiOperation("行程详情") -+ @ApiOperation(value = "行程详情", notes = "返回订单的完整行程信息,包括每日行程节点、酒店安排、车辆安排、天气预报等\n\n" + -+ "**关联字典**:\n" + -+ "- order_status(订单状态,返回字段status):CONFIRMED=已确认, PENDING_DEPARTURE=待出发, TRAVELLING=出行中, COMPLETED=已完成\n" + -+ "- trip_phase(行程阶段,返回字段tripPhase):BEFORE_START=出发前, IN_PROGRESS=出行中, ENDED=已结束") - @GetMapping("/{orderId}") - public Result> getTripDetail(@RequestParam Long userId, - @PathVariable Long orderId) { - return Result.success(tripService.getTripDetail(userId, orderId)); - } - -- @ApiOperation("今日行程") -+ @ApiOperation(value = "今日行程", notes = "返回用户今天的行程安排。如果今天有正在出行的订单,返回当天的行程节点和安排;否则返回null\n\n" + -+ "**关联字典**:\n" + -+ "- order_status(订单状态,返回字段status):CONFIRMED=已确认, PENDING_DEPARTURE=待出发, TRAVELLING=出行中, COMPLETED=已完成\n" + -+ "- trip_phase(行程阶段,返回字段tripPhase):BEFORE_START=出发前, IN_PROGRESS=出行中, ENDED=已结束") - @GetMapping("/today") - public Result> getTodayTrip(@RequestParam Long userId) { - Map trip = tripService.getTodayTrip(userId); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderStatsController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderStatsController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderStatsController.java -index 887cf27..38d3022 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderStatsController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderStatsController.java -@@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.*; - - import javax.validation.Valid; - --@Api(tags = "内部-订单统计") -+@Api(tags = "内部-订单统计", hidden = true) - @RestController - @RequestMapping("/internal/mp/order") - @RequiredArgsConstructor -@@ -21,19 +21,24 @@ public class InternalOrderStatsController { - private final OrderService orderService; - private final InvoiceService invoiceService; - -- @ApiOperation("获取产品已购出行人总数") -+ @ApiOperation(value = "获取产品已购出行人总数", notes = "统计指定产品的有效订单(非取消/非退款)出行人总数,用于产品详情页显示'已报名X人'") - @GetMapping("/product-sold-count") - public Result getProductSoldCount(@RequestParam Long productId) { - return Result.success(orderService.getProductSoldCount(productId)); - } - -- @ApiOperation("获取产品参与家庭数") -+ @ApiOperation(value = "获取产品参与家庭数", notes = "统计指定产品的有效订单数(一个订单视为一个家庭),用于产品详情页显示'已有X个家庭参与'") - @GetMapping("/participant-family-count") - public Result getParticipantFamilyCount(@RequestParam Long productId) { - return Result.success(orderService.getParticipantFamilyCount(productId)); - } - -- @ApiOperation("发票换开") -+ @ApiOperation(value = "发票换开", notes = "已开发票更换抬头信息(如个人改企业、更换公司名称等)。\n" + -+ "原发票作废,重新生成新发票\n\n" + -+ "**关联字典**:\n" + -+ "- invoice_title_type(抬头类型,请求/返回字段titleType):PERSONAL=个人, COMPANY=企业\n" + -+ "- invoice_type(发票类型,返回字段invoiceType):NORMAL=普通发票, SPECIAL=专用发票\n" + -+ "- invoice_status(发票状态,返回字段status):PENDING=待开票, ISSUED=已开票, FAILED=开票失败, CANCELLED=已作废") - @PostMapping("/invoice/reissue") - public Result reissueInvoice(@RequestBody @Valid InvoiceReissueRequest request) { - return Result.success(invoiceService.reissueInvoice(request)); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderTravelerController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderTravelerController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderTravelerController.java -index 2b39654..656382a 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderTravelerController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderTravelerController.java -@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.*; - /** - * Internal API for payment service - 出行人验证 - */ --@Api(tags = "【内部接口】订单出行人(Feign调用)") -+@Api(tags = "【内部接口】订单出行人(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/order/traveler") - @RequiredArgsConstructor -@@ -19,7 +19,11 @@ public class InternalOrderTravelerController { - - private final OrderTravelerService orderTravelerService; - -- @ApiOperation("验证订单出行人信息(供支付服务调用)") -+ @ApiOperation(value = "验证订单出行人信息", notes = "供支付服务在发起支付前调用。验证出行人数量是否满足订单要求、证件信息是否完整。\n" + -+ "返回验证结果,包含是否通过和具体错误信息列表\n\n" + -+ "【关联字典】\n" + -+ "- 涉及字段 出行人证件类型 → 字典:id_card_type(证件类型)\n" + -+ "- 涉及字段 出行人类型 → 字典:traveler_type(出行人类型)") - @GetMapping("/validate/{orderId}") - public Result validateTravelers(@PathVariable Long orderId) { - TravelerValidationDTO validation = orderTravelerService.validateTravelers(orderId); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalPaymentOrderController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalPaymentOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalPaymentOrderController.java -index b708e85..be4a57c 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalPaymentOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalPaymentOrderController.java -@@ -21,7 +21,7 @@ import java.util.stream.Collectors; - * Internal endpoints for payment-service to call via Feign. - * Not exposed through gateway, no authentication interceptor. - */ --@Api(tags = "【内部接口】订单-支付/合同/保险(Feign调用)") -+@Api(tags = "【内部接口】订单-支付/合同/保险(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/order") - @RequiredArgsConstructor -@@ -30,13 +30,16 @@ public class InternalPaymentOrderController { - private final OrderService orderService; - private final OrderTodoService orderTodoService; - -- @ApiOperation("获取订单支付信息") -+ @ApiOperation(value = "获取订单支付信息", notes = "供支付服务调用。返回订单号、应付金额、定金金额、已付金额等支付所需信息") - @GetMapping("/{orderId}/pay-info") - public Result getPayInfo(@PathVariable Long orderId) { - return Result.success(orderService.getPayInfo(orderId)); - } - -- @ApiOperation("通知支付成功") -+ @ApiOperation(value = "通知支付成功", notes = "支付服务收到微信支付回调后调用。更新订单状态(PENDING_PAY→DEPOSIT_PAID/PAID)和已付金额。\n" + -+ "幂等处理:重复调用不会重复更新\n\n" + -+ "【关联字典】\n" + -+ "- 涉及字段 订单status → 字典:order_status(订单状态)") - @PostMapping("/payment-result") - public Result notifyPaymentResult(@RequestBody PaymentResultDTO dto) { - orderService.handlePaymentSuccess(dto.getOrderId(), dto.getPayType(), -@@ -44,14 +47,16 @@ public class InternalPaymentOrderController { - return Result.success(); - } - -- @ApiOperation("通知退款成功") -+ @ApiOperation(value = "通知退款成功", notes = "支付服务收到微信退款回调后调用。更新订单已退金额,若全额退款则将订单状态改为已退款(REFUNDED)") - @PostMapping("/refund-result") - public Result notifyRefundResult(@RequestBody RefundResultDTO dto) { - orderService.handleRefundSuccess(dto.getOrderId(), dto.getRefundAmount()); - return Result.success(); - } - -- @ApiOperation("获取订单基本信息(供合同服务调用)") -+ @ApiOperation(value = "获取订单基本信息(供合同服务调用)", notes = "【关联字典】\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/{orderId}/basic") - public Result> getOrderBasic(@PathVariable Long orderId) { - OrderInfo order = orderService.getById(orderId); -@@ -80,7 +85,8 @@ public class InternalPaymentOrderController { - return Result.success(data); - } - -- @ApiOperation("获取用户订单ID列表(供合同服务调用)") -+ @ApiOperation(value = "获取用户订单ID列表(供合同服务调用)", -+ notes = "内部服务间调用。返回指定用户的所有订单ID列表,供合同服务查询用户关联合同时使用。") - @GetMapping("/ids-by-user") - public Result> getOrderIdsByUser(@RequestParam Long userId) { - List orders = orderService.list( -@@ -94,7 +100,8 @@ public class InternalPaymentOrderController { - return Result.success(ids); - } - -- @ApiOperation("完成待办项(供合同/保险服务调用)") -+ @ApiOperation(value = "完成待办项(供合同/保险服务调用)", -+ notes = "内部服务间调用。合同服务签约完成或保险服务投保完成后调用此接口,将对应待办标记为已完成。系统自动检查是否所有必要待办已完成并推进内部流程。") - @PostMapping("/{orderId}/complete-todo/{todoType}") - public Result completeTodoByType(@PathVariable Long orderId, - @PathVariable String todoType) { -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalRefundController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalRefundController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalRefundController.java -index 2464f08..f7c334f 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalRefundController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalRefundController.java -@@ -17,7 +17,7 @@ import org.springframework.web.bind.annotation.*; - import javax.validation.Valid; - import java.util.List; - --@Api(tags = "【内部接口】退款(Feign调用)") -+@Api(tags = "【内部接口】退款(Feign调用)", hidden = true) - @RestController - @RequiredArgsConstructor - public class InternalRefundController { -@@ -27,20 +27,26 @@ public class InternalRefundController { - - // ==================== C-end (BFF → order-service) ==================== - -- @ApiOperation(value = "退款金额预览", notes = "退款预览:根据退款政策和距出发天数,计算可退金额和退款比例") -+ @ApiOperation(value = "退款金额预览", notes = "退款预览:根据退款政策和距出发天数,计算可退金额和退款比例\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 refundType → 字典:refund_type(退款类型)") - @GetMapping("/internal/mp/order/{orderId}/refund-preview") - public Result preview(@RequestParam("userId") Long userId, - @PathVariable Long orderId) { - return Result.success(refundApplicationService.previewRefund(orderId, userId)); - } - -- @ApiOperation("退款原因列表") -+ @ApiOperation(value = "退款原因列表(C端)", notes = "返回启用中的退款原因选项,供C端用户申请退款时选择\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 category → 字典:refund_reason_category(退款原因分类)") - @GetMapping("/internal/mp/order/refund-reasons") - public Result> listReasons() { - return Result.success(refundReasonService.listReasons(true)); - } - -- @ApiOperation(value = "提交退款申请", notes = "退款申请流程:用户选择退款原因 → 填写退款说明 → 系统根据退款政策计算可退金额 → 生成退款申请(PENDING状态) → 等待管理员审批") -+ @ApiOperation(value = "提交退款申请", notes = "退款申请流程:用户选择退款原因 → 填写退款说明 → 系统根据退款政策计算可退金额 → 生成退款申请(PENDING状态) → 等待管理员审批\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @PostMapping("/internal/mp/order/{orderId}/refund") - public Result apply(@RequestParam("userId") Long userId, - @RequestParam(value = "userName", required = false) String userName, -@@ -49,14 +55,18 @@ public class InternalRefundController { - return Result.success(refundApplicationService.apply(orderId, userId, userName, request)); - } - -- @ApiOperation("退款申请详情") -+ @ApiOperation(value = "退款申请详情(C端)", notes = "返回退款申请信息,仅允许查看自己的退款申请\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @GetMapping("/internal/mp/order/refund/{applicationId}") - public Result getDetail(@RequestParam("userId") Long userId, - @PathVariable Long applicationId) { - return Result.success(refundApplicationService.getDetailForUser(applicationId, userId)); - } - -- @ApiOperation("根据订单ID获取最新退款申请详情") -+ @ApiOperation(value = "根据订单ID获取最新退款申请", notes = "返回订单关联的最新一条退款申请,用于订单详情页展示退款进度。无退款申请时返回null\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @GetMapping("/internal/mp/order/{orderId}/refund-detail") - public Result getDetailByOrder(@RequestParam("userId") Long userId, - @PathVariable Long orderId) { -@@ -72,7 +82,7 @@ public class InternalRefundController { - return Result.success(refundApplicationService.appeal(applicationId, userId, request)); - } - -- @ApiOperation("撤回退款申请") -+ @ApiOperation(value = "撤回退款申请", notes = "用户主动撤回退款申请。仅在待审批(PENDING)状态下可撤回。撤回后订单恢复原状态") - @PostMapping("/internal/mp/order/refund/{applicationId}/cancel") - public Result cancel(@RequestParam("userId") Long userId, - @PathVariable Long applicationId) { -@@ -82,16 +92,18 @@ public class InternalRefundController { - - // ==================== Approval callback ==================== - -- @ApiOperation("企微退款申诉审批结果回调") -+ @ApiOperation(value = "企微退款申诉审批结果回调", notes = "企微OA审批完成后由callback-service调用。\n" + -+ "审批通过则退款申请状态变为APPEAL_APPROVED,等待管理员确认实退金额后执行退款") - @PostMapping("/internal/order/refund-appeal-result") -- public Result handleRefundAppealResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleRefundAppealResult(@RequestBody ApprovalResultDTO dto) { - refundApplicationService.handleAppealResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); - } - -- @ApiOperation("企微退款申请审批结果回调") -+ @ApiOperation(value = "企微退款申请审批结果回调", notes = "企微OA审批完成后由callback-service调用。\n" + -+ "审批通过则自动执行微信退款,审批拒绝则退款申请状态变为REJECTED") - @PostMapping("/internal/order/refund-application-result") -- public Result handleRefundApplicationResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleRefundApplicationResult(@RequestBody ApprovalResultDTO dto) { - refundApplicationService.handleApplicationApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); - } -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/MpOrderController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/MpOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/MpOrderController.java -index f29e8f9..9b3806e 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/MpOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/MpOrderController.java -@@ -35,7 +35,13 @@ public class MpOrderController { - private static final String ORDER_CREATE_DEDUP = "order:create:dedup:"; - - @ApiOperation(value = "创建订单", notes = "C端下单流程:选择产品 → 填写联系人信息和出行人 → 系统报价 → 生成订单(PENDING_PAY状态)\n\n" + -- "联系人和出行人是独立概念,联系人不必是出行人之一") -+ "联系人和出行人是独立概念,联系人不必是出行人之一\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 请求参数 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 请求参数 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @PostMapping("/create") - public Result createOrder(HttpServletRequest request, - @ApiParam("创建订单请求") @Valid @RequestBody CreateOrderRequest createRequest) { -@@ -55,7 +61,12 @@ public class MpOrderController { - } - } - -- @ApiOperation("我的订单列表") -+ @ApiOperation(value = "我的订单列表", notes = "查询当前用户的订单列表,支持按状态筛选。\n" + -+ "用户需先完善个人资料(realName)后才能看到订单\n\n" + -+ "【关联字典】\n" + -+ "- 筛选参数 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/list") - public Result> listOrders(HttpServletRequest request, - @ApiParam("订单查询请求") MpOrderQueryRequest queryRequest) { -@@ -64,7 +75,15 @@ public class MpOrderController { - return Result.success(result); - } - -- @ApiOperation("订单详情") -+ @ApiOperation(value = "订单详情", notes = "获取订单完整信息。仅能查看自己的订单,查看他人订单会返回权限错误\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)\n" + -+ "- 返回字段 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 返回字段 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 返回字段 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 timeline[].action → 字典:order_timeline_action(订单操作类型)") - @GetMapping("/{orderId}") - public Result getOrder(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId) { -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/MpWeatherController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/MpWeatherController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/MpWeatherController.java -index 9e92157..1df079f 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/MpWeatherController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/MpWeatherController.java -@@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "内部天气接口(Feign)") -+@Api(tags = "内部天气接口(Feign)", hidden = true) - @RestController - @RequestMapping("/internal/mp/weather") - @RequiredArgsConstructor -@@ -20,21 +20,21 @@ public class MpWeatherController { - - private final WeatherService weatherService; - -- @ApiOperation("获取订单行程天气") -+ @ApiOperation(value = "获取订单行程天气", notes = "根据订单行程中的城市和日期,批量查询天气信息。返回每天每个城市的天气数据列表") - @GetMapping("/itinerary/{orderId}") - public Result>> getItineraryWeather( - @ApiParam("订单ID") @PathVariable Long orderId) { - return Result.success(weatherService.getItineraryWeather(orderId)); - } - -- @ApiOperation("获取指定城市实况天气") -+ @ApiOperation(value = "获取指定城市实况天气", notes = "调用高德天气API查询城市实时天气(温度、湿度、风向等),结果缓存30分钟") - @GetMapping("/live") - public Result getLiveWeather( - @ApiParam("城市名称") @RequestParam String city) { - return Result.success(weatherService.getLiveWeather(city)); - } - -- @ApiOperation("获取指定城市天气预报") -+ @ApiOperation(value = "获取指定城市天气预报", notes = "调用高德天气API查询城市未来3天天气预报,结果缓存2小时") - @GetMapping("/forecast") - public Result getForecastWeather( - @ApiParam("城市名称") @RequestParam String city) { -``` - -### `hl-payment-service/src/main/java/com/hulalv/payment/controller/AdminPaymentController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-payment-service/src/main/java/com/hulalv/payment/controller/AdminPaymentController.java b/hl-payment-service/src/main/java/com/hulalv/payment/controller/AdminPaymentController.java -index 3392e72..10a9ea4 100644 ---- a/hl-payment-service/src/main/java/com/hulalv/payment/controller/AdminPaymentController.java -+++ b/hl-payment-service/src/main/java/com/hulalv/payment/controller/AdminPaymentController.java -@@ -27,13 +27,13 @@ public class AdminPaymentController { - private final RefundService refundService; - - @GetMapping("/list") -- @ApiOperation(value = "支付交易列表", notes = "分页查询支付交易记录,支持按订单号、交易状态、交易类型筛选") -+ @ApiOperation(value = "支付交易列表", notes = "分页查询支付交易记录,支持按订单号、交易状态、交易类型筛选\n\n**关联字典**:\n- payment_mode:支付模式(列表筛选+显示)") - public Result> listTransactions(@ApiParam("支付查询条件") @Valid PaymentQueryRequest request) { - return Result.success(paymentService.listTransactions(request)); - } - - @GetMapping("/{transactionId}") -- @ApiOperation(value = "交易详情", notes = "获取单笔交易的完整信息,包含微信支付流水号") -+ @ApiOperation(value = "交易详情", notes = "获取单笔交易的完整信息,包含微信支付流水号\n\n**关联字典**:\n- payment_mode:支付模式(显示)") - public Result getDetail(@ApiParam("交易ID") @PathVariable Long transactionId) { - return Result.success(paymentService.getDetail(transactionId)); - } -``` - -### `hl-payment-service/src/main/java/com/hulalv/payment/controller/InternalPaymentController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-payment-service/src/main/java/com/hulalv/payment/controller/InternalPaymentController.java b/hl-payment-service/src/main/java/com/hulalv/payment/controller/InternalPaymentController.java -index d195a48..dbdfc84 100644 ---- a/hl-payment-service/src/main/java/com/hulalv/payment/controller/InternalPaymentController.java -+++ b/hl-payment-service/src/main/java/com/hulalv/payment/controller/InternalPaymentController.java -@@ -25,14 +25,14 @@ import java.util.List; - @RestController - @RequestMapping("/internal/payment") - @RequiredArgsConstructor --@Api(tags = "【内部接口】支付(Feign调用)") -+@Api(tags = "【内部接口】支付(Feign调用)", hidden = true) - public class InternalPaymentController { - - private final PaymentService paymentService; - private final RefundService refundService; - - @PostMapping("/prepay") -- @ApiOperation("Create prepay order (called by BFF)") -+ @ApiOperation(value = "创建预支付订单", notes = "由BFF层调用,向微信支付API发起预支付请求,返回前端调起支付所需的参数(prepay_id等)") - public Result prepay( - @RequestParam("userId") Long userId, - @Valid @RequestBody PrepayRequest request) { -@@ -41,7 +41,7 @@ public class InternalPaymentController { - } - - @GetMapping("/status/{orderId}") -- @ApiOperation("Query payment status (called by BFF)") -+ @ApiOperation(value = "查询支付状态", notes = "查询订单的支付状态,含用户权限校验(userId不匹配时拒绝访问)\n\n**关联字典**:\n- payment_status:支付状态(返回字段)") - public Result getStatus(@RequestParam(value = "userId", required = false) Long userId, - @PathVariable Long orderId) { - PaymentVO vo = paymentService.getPaymentStatus(orderId); -@@ -53,7 +53,7 @@ public class InternalPaymentController { - } - - @GetMapping("/transactions/{orderId}") -- @ApiOperation("List all transactions for an order (called by BFF)") -+ @ApiOperation(value = "订单交易记录列表", notes = "查询指定订单的所有支付交易记录(含支付和退款),含用户权限校验\n\n**关联字典**:\n- payment_status:支付状态(返回字段)") - public Result> listTransactions(@RequestParam(value = "userId", required = false) Long userId, - @PathVariable Long orderId) { - List list = paymentService.listByOrder(orderId); -@@ -67,7 +67,7 @@ public class InternalPaymentController { - } - - @PostMapping("/refund") -- @ApiOperation("Create refund (called by order-service)") -+ @ApiOperation(value = "创建退款", notes = "由订单服务调用,向微信支付API发起退款请求。退款金额不能超过原支付金额,退款结果通过微信回调异步通知") - public Result createRefund(@Valid @RequestBody PaymentRefundRequest refundRequest) { - RefundRequest request = new RefundRequest(); - request.setOrderId(refundRequest.getOrderId()); -``` - -### `hl-payment-service/src/main/java/com/hulalv/payment/controller/PaymentCallbackController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-payment-service/src/main/java/com/hulalv/payment/controller/PaymentCallbackController.java b/hl-payment-service/src/main/java/com/hulalv/payment/controller/PaymentCallbackController.java -index d950113..8b8106b 100644 ---- a/hl-payment-service/src/main/java/com/hulalv/payment/controller/PaymentCallbackController.java -+++ b/hl-payment-service/src/main/java/com/hulalv/payment/controller/PaymentCallbackController.java -@@ -23,14 +23,14 @@ import java.util.Map; - @RestController - @RequestMapping("/pay/callback") - @RequiredArgsConstructor --@Api(tags = "【回调接口】支付回调") -+@Api(tags = "【回调接口】支付回调", hidden = true) - public class PaymentCallbackController { - - private final PaymentService paymentService; - private final RefundService refundService; - - @PostMapping("/notify/{mchId}") -- @ApiOperation("支付成功回调") -+ @ApiOperation(value = "支付成功回调", notes = "微信支付成功后的异步通知回调(无需认证,通过微信签名验证安全性)。验证签名 → 更新支付状态 → 发送MQ消息通知订单服务") - public ResponseEntity> payNotify( - @PathVariable String mchId, - HttpServletRequest request) { -@@ -49,7 +49,7 @@ public class PaymentCallbackController { - } - - @PostMapping("/refund-notify/{mchId}") -- @ApiOperation("退款回调") -+ @ApiOperation(value = "退款回调", notes = "微信退款结果的异步通知回调(无需认证,通过微信签名验证安全性)。验证签名 → 更新退款状态 → 发送MQ消息通知订单服务") - public ResponseEntity> refundNotify( - @PathVariable String mchId, - HttpServletRequest request) { -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/DistrictController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/DistrictController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/DistrictController.java -index 3d92709..5a21261 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/DistrictController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/DistrictController.java -@@ -21,7 +21,12 @@ public class DistrictController { - - private final AmapDistrictService amapDistrictService; - -- @ApiOperation("搜索行政区划(城市/区县)") -+ @ApiOperation(value = "搜索行政区划(城市/区县)", -+ notes = "通过高德地图 API 搜索行政区划,用于产品的出发城市和目的地城市选择。\n" -+ + "输入关键词(如\"丽江\"、\"昆明\"),返回匹配的城市/区县列表,包含行政区划编码。\n\n" -+ + "**关联字典**:\n" -+ + "- cities(城市):搜索结果可用于产品行程中的城市预览\n" -+ + "- city(城市筛选):搜索结果可用于资源面板城市筛选") - @GetMapping("/search") - public Result> search( - @ApiParam("搜索关键词") @RequestParam String keywords) { -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/FamilyController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/FamilyController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/FamilyController.java -index b1bba5b..8e8827f 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/FamilyController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/FamilyController.java -@@ -21,13 +21,19 @@ public class FamilyController { - - private final ProductFamilyService familyService; - -- @ApiOperation("获取家庭分组列表") -+ @ApiOperation(value = "获取家庭分组列表", -+ notes = "获取产品的家庭分组列表,按排序序号升序。\n\n" -+ + "**仅适用于 CUSTOM(定制)产品**。\n" -+ + "家庭分组用于将定制产品的行程按家庭单位分配,每个家庭可以有不同的人数和行程安排。\n" -+ + "行程节点通过 familyIds 字段关联到具体的家庭分组。") - @GetMapping("/families") - public Result> listFamilies(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(familyService.listFamilies(productId)); - } - -- @ApiOperation("添加家庭分组") -+ @ApiOperation(value = "添加家庭分组", -+ notes = "为 CUSTOM 定制产品添加一个家庭分组,指定家庭名称和各类型人数。\n" -+ + "添加后可在行程节点中关联此家庭,实现按家庭分配行程。") - @PostMapping("/family") - public Result addFamily( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -35,7 +41,9 @@ public class FamilyController { - return Result.success(familyService.addFamily(productId, request)); - } - -- @ApiOperation("更新家庭分组") -+ @ApiOperation(value = "更新家庭分组", -+ notes = "更新家庭分组的名称、各类型人数等信息。\n" -+ + "**仅适用于 CUSTOM(定制)产品**。") - @PutMapping("/family/{familyId}") - public Result updateFamily( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -44,7 +52,9 @@ public class FamilyController { - return Result.success(familyService.updateFamily(familyId, request)); - } - -- @ApiOperation("删除家庭分组") -+ @ApiOperation(value = "删除家庭分组", -+ notes = "删除家庭分组。如果有行程节点通过 familyIds 关联了该分组,需要手动移除关联。\n" -+ + "**仅适用于 CUSTOM(定制)产品**。") - @DeleteMapping("/family/{familyId}") - public Result deleteFamily( - @ApiParam("产品ID") @PathVariable Long productId, -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/FormulaController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/FormulaController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/FormulaController.java -index 9d4395e..6cc32f3 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/FormulaController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/FormulaController.java -@@ -32,20 +32,34 @@ public class FormulaController { - - // ===== Group endpoints ===== - -- @ApiOperation("公式组列表") -+ @ApiOperation(value = "公式组列表", -+ notes = "获取定价公式组列表,可按产品类型筛选。\n\n" -+ + "**公式引擎说明**:定价公式用于自动计算产品的成本价和售价。\n" -+ + "每种产品类型可以有多个公式组,但同一时间只能有一个激活的公式组。\n" -+ + "公式组包含多个步骤,按顺序执行,每步计算一个中间变量或最终结果。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,筛选条件):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/group/list") - public Result> listGroups( - @RequestParam(required = false) String productType) { - return Result.success(groupService.listGroups(productType)); - } - -- @ApiOperation("公式组详情") -+ @ApiOperation(value = "公式组详情", -+ notes = "获取公式组完整信息。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/group/{groupId}") - public Result getGroup(@PathVariable Long groupId) { - return Result.success(groupService.getGroup(groupId)); - } - -- @ApiOperation("创建公式组") -+ @ApiOperation(value = "创建公式组", -+ notes = "创建一个新的定价公式组。创建后默认为未激活状态。\n\n" -+ + "公式组编码(groupCode)在同一产品类型下必须唯一。\n" -+ + "建议命名规范:{产品类型}_PRICING_V{版本号},如 CORE_PRICING_V2。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,公式组所属类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PostMapping("/group") - public Result createGroup(@Valid @RequestBody FormulaGroupRequest request, - HttpServletRequest httpRequest) { -@@ -53,21 +67,31 @@ public class FormulaController { - return Result.success(groupService.createGroup(request, adminId)); - } - -- @ApiOperation("更新公式组") -+ @ApiOperation(value = "更新公式组", -+ notes = "更新公式组信息。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PutMapping("/group/{groupId}") - public Result updateGroup(@PathVariable Long groupId, - @Valid @RequestBody FormulaGroupRequest request) { - return Result.success(groupService.updateGroup(groupId, request)); - } - -- @ApiOperation("激活公式组") -+ @ApiOperation(value = "激活公式组", -+ notes = "激活指定公式组,同时自动停用同产品类型下的其他公式组。\n\n" -+ + "同一产品类型下只能有一个激活的公式组,激活操作具有排他性。\n" -+ + "激活后,该产品类型的自动成本计算将使用此公式组。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,同类型排他激活):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PutMapping("/group/{groupId}/activate") - public Result activateGroup(@PathVariable Long groupId) { - groupService.activateGroup(groupId); - return Result.success(); - } - -- @ApiOperation("删除公式组") -+ @ApiOperation(value = "删除公式组", -+ notes = "删除公式组及其下所有步骤。\n" -+ + "**限制**:已激活的公式组不能删除,需先激活其他公式组。") - @DeleteMapping("/group/{groupId}") - public Result deleteGroup(@PathVariable Long groupId) { - groupService.deleteGroup(groupId); -@@ -76,25 +100,35 @@ public class FormulaController { - - // ===== Step endpoints ===== - -- @ApiOperation("公式步骤列表") -+ @ApiOperation(value = "公式步骤列表", -+ notes = "获取公式组下所有步骤,按执行顺序(executionOrder)升序排列。\n" -+ + "步骤按顺序依次执行,前一步的输出变量可作为后续步骤的输入。") - @GetMapping("/group/{groupId}/steps") - public Result> listSteps(@PathVariable Long groupId) { - return Result.success(stepService.listSteps(groupId)); - } - -- @ApiOperation("公式步骤详情") -+ @ApiOperation(value = "公式步骤详情", -+ notes = "获取单个公式步骤的完整信息,包含表达式、输入/输出变量、执行顺序等。") - @GetMapping("/step/{formulaId}") - public Result getStep(@PathVariable Long formulaId) { - return Result.success(stepService.getStep(formulaId)); - } - -- @ApiOperation("创建公式步骤") -+ @ApiOperation(value = "创建公式步骤", -+ notes = "在公式组中创建一个计算步骤。\n\n" -+ + "**表达式语法**:使用 Aviator 表达式引擎,支持数学运算、条件判断、内置函数等。\n" -+ + "示例:`baseCost = adultCount * adultUnitCost + childCount * childUnitCost`\n\n" -+ + "**输入变量**:可引用公式变量表中定义的变量,或前置步骤的输出变量。\n" -+ + "**输出变量**:每个步骤必须指定一个输出变量名,供后续步骤引用。") - @PostMapping("/step") - public Result createStep(@Valid @RequestBody FormulaStepRequest request) { - return Result.success(stepService.createStep(request)); - } - -- @ApiOperation("更新公式步骤") -+ @ApiOperation(value = "更新公式步骤", -+ notes = "更新公式步骤的表达式、输入/输出变量等。\n" -+ + "每次更新会自动保存一个版本快照,可通过版本历史接口查看和回滚。") - @PutMapping("/step/{formulaId}") - public Result updateStep(@PathVariable Long formulaId, - @Valid @RequestBody FormulaStepRequest request, -@@ -103,27 +137,36 @@ public class FormulaController { - return Result.success(stepService.updateStep(formulaId, request, adminId)); - } - -- @ApiOperation("启用/禁用公式步骤") -+ @ApiOperation(value = "启用/禁用公式步骤", -+ notes = "切换公式步骤的启用状态。\n" -+ + "禁用的步骤在公式执行时会被跳过,不影响其他步骤的执行。\n" -+ + "适用场景:临时跳过某个计算步骤进行调试或测试。") - @PutMapping("/step/{formulaId}/toggle") - public Result toggleStep(@PathVariable Long formulaId) { - stepService.toggleStep(formulaId); - return Result.success(); - } - -- @ApiOperation("删除公式步骤") -+ @ApiOperation(value = "删除公式步骤", -+ notes = "删除指定的公式步骤。删除后其他步骤的执行顺序不会自动调整。\n" -+ + "**注意**:如果后续步骤引用了被删步骤的输出变量,执行时会报错。") - @DeleteMapping("/step/{formulaId}") - public Result deleteStep(@PathVariable Long formulaId) { - stepService.deleteStep(formulaId); - return Result.success(); - } - -- @ApiOperation("公式步骤版本历史") -+ @ApiOperation(value = "公式步骤版本历史", -+ notes = "获取公式步骤的所有历史版本列表,按版本号倒序。\n" -+ + "每次更新步骤表达式会自动创建新版本,方便追溯和回滚。") - @GetMapping("/step/{formulaId}/versions") - public Result> listVersions(@PathVariable Long formulaId) { - return Result.success(stepService.listVersions(formulaId)); - } - -- @ApiOperation("回滚公式步骤到指定版本") -+ @ApiOperation(value = "回滚公式步骤到指定版本", -+ notes = "将公式步骤回滚到历史版本。\n" -+ + "回滚操作会用历史版本的表达式、变量等覆盖当前内容,并创建一个新的版本记录。") - @PutMapping("/step/{formulaId}/rollback/{versionNum}") - public Result rollbackStep(@PathVariable Long formulaId, - @PathVariable Integer versionNum, -@@ -134,7 +177,11 @@ public class FormulaController { - - // ===== Test endpoint ===== - -- @ApiOperation("测试公式执行") -+ @ApiOperation(value = "测试公式执行", -+ notes = "使用自定义变量值测试公式组的执行结果,不影响任何业务数据。\n\n" -+ + "传入公式组ID和测试变量(变量名→值的映射),返回每个步骤的执行结果。\n" -+ + "适用于公式调试:验证表达式是否正确、计算结果是否符合预期。\n" -+ + "如果某步骤执行出错,会在结果中标明错误信息。") - @PostMapping("/test") - public Result testFormulas(@Valid @RequestBody FormulaTestRequest request) { - return Result.success(testService.testFormulas(request)); -@@ -142,27 +189,41 @@ public class FormulaController { - - // ===== Var endpoints ===== - -- @ApiOperation("公式变量列表") -+ @ApiOperation(value = "公式变量列表", -+ notes = "获取公式变量列表,可按变量分类筛选。\n\n" -+ + "**变量分类**:\n" -+ + "- INPUT:输入变量,从业务数据获取(如成人人数、资源单价)\n" -+ + "- INTERMEDIATE:中间变量,由公式步骤计算得出\n" -+ + "- OUTPUT:输出变量,最终报价结果(如总成本、售价)") - @GetMapping("/var/list") - public Result> listVars( - @RequestParam(required = false) String category) { - return Result.success(varService.listVars(category)); - } - -- @ApiOperation("创建公式变量") -+ @ApiOperation(value = "创建公式变量", -+ notes = "创建公式变量定义。变量名(varName)全局唯一,建议使用驼峰命名。\n" -+ + "可指定适用的产品类型列表(productTypes),为空则适用于所有类型。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,变量适用范围):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PostMapping("/var") - public Result createVar(@Valid @RequestBody FormulaVarRequest request) { - return Result.success(varService.createVar(request)); - } - -- @ApiOperation("更新公式变量") -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/GroupBatchController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/GroupBatchController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/GroupBatchController.java -index 7e553dc..ab7b818 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/GroupBatchController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/GroupBatchController.java -@@ -25,7 +25,16 @@ public class GroupBatchController { - - // ===== Batch CRUD ===== - -- @ApiOperation("创建主批次") -+ @ApiOperation(value = "创建主批次", -+ notes = "为 GROUP(小蒙马拼团)产品创建一个团期主批次。\n\n" -+ + "**仅适用于 GROUP 产品类型**。\n" -+ + "每个批次有独立的出发日期、报名截止日期、人数上限。\n" -+ + "创建后状态为 PENDING(待开放),需手动开启报名。\n\n" -+ + "**批次状态流转**:PENDING → ENROLLING(报名中)→ CONFIRMED(已成团)→ CLOSED(已关闭)\n" -+ + "任意报名状态均可被解散(DISBANDED)。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,仅限GROUP):GROUP=小蒙马拼团\n" -+ + "- batch_status(批次状态):PENDING=待开放, ENROLLING=报名中, CONFIRMED=已成团, FULL=已满员, CLOSED=已关闭, DISBANDED=已解散, IN_PROGRESS=进行中, FINISHED=已结束") - @PostMapping - public Result createBatch(@PathVariable Long productId, - @Valid @RequestBody GroupBatchCreateRequest request, -@@ -34,7 +43,11 @@ public class GroupBatchController { - return Result.success(batchService.createBatch(productId, request, adminId)); - } - -- @ApiOperation("创建子批次(溢出)") -+ @ApiOperation(value = "创建子批次(溢出)", -+ notes = "当主批次人数满员时,创建子批次接收溢出报名。\n\n" -+ + "子批次共享主批次的出发日期和行程,但有独立的人数上限和报名人数。\n" -+ + "适用场景:某团期特别火爆,需要扩容但希望分开管理。\n" -+ + "子批次在列表中显示为主批次的子级节点。") - @PostMapping("/{batchId}/sub-batch") - public Result createSubBatch(@PathVariable Long productId, - @PathVariable Long batchId, -@@ -44,7 +57,9 @@ public class GroupBatchController { - return Result.success(batchService.createSubBatch(batchId, request, adminId)); - } - -- @ApiOperation("更新批次") -+ @ApiOperation(value = "更新批次", -+ notes = "更新批次基本信息。仅传入需要修改的字段。\n" -+ + "已有报名人员的批次修改人数上限时,不能低于已报名人数。") - @PutMapping("/{batchId}") - public Result updateBatch(@PathVariable Long productId, - @PathVariable Long batchId, -@@ -52,20 +67,30 @@ public class GroupBatchController { - return Result.success(batchService.updateBatch(batchId, request)); - } - -- @ApiOperation("删除批次") -+ @ApiOperation(value = "删除批次", -+ notes = "删除批次(软删除)。\n" -+ + "**限制**:已有报名人员的批次不能直接删除,需先解散批次。") - @DeleteMapping("/{batchId}") - public Result deleteBatch(@PathVariable Long productId, @PathVariable Long batchId) { - batchService.deleteBatch(batchId); - return Result.success(); - } - -- @ApiOperation("批次列表(树形)") -+ @ApiOperation(value = "批次列表(树形)", -+ notes = "获取产品所有批次,以树形结构返回(主批次包含子批次列表)。\n" -+ + "按出发日期升序排列,包含每个批次的报名人数和剩余名额。\n\n" -+ + "**关联字典**:\n" -+ + "- batch_status(批次状态,返回字段):PENDING=待开放, ENROLLING=报名中, CONFIRMED=已成团, FULL=已满员, CLOSED=已关闭, DISBANDED=已解散, IN_PROGRESS=进行中, FINISHED=已结束") - @GetMapping("/list") - public Result> listBatches(@PathVariable Long productId) { - return Result.success(batchService.listBatches(productId)); - } - -- @ApiOperation("批次详情") -+ @ApiOperation(value = "批次详情", -+ notes = "获取单个批次的完整信息,包括批次基本信息、服务人员配置、套餐组合等。\n\n" -+ + "**关联字典**:\n" -+ + "- batch_status(批次状态):PENDING=待开放, ENROLLING=报名中, CONFIRMED=已成团, FULL=已满员, CLOSED=已关闭, DISBANDED=已解散, IN_PROGRESS=进行中, FINISHED=已结束\n" -+ + "- staff_type(人员类型,服务人员配置):GUIDE=领队, DRIVER=司机, PHOTOGRAPHER=摄影师, ASSISTANT=助理, OTHER=其他") - @GetMapping("/{batchId}") - public Result getBatchDetail(@PathVariable Long productId, - @PathVariable Long batchId) { -@@ -74,21 +99,33 @@ public class GroupBatchController { - - // ===== Status operations ===== - -- @ApiOperation("开启报名(PENDING->ENROLLING)") -+ @ApiOperation(value = "开启报名(PENDING->ENROLLING)", -+ notes = "将批次从 PENDING 状态变更为 ENROLLING(报名中)。\n" -+ + "开启后用户可在小程序端看到该团期并报名。\n" -+ + "前提条件:产品必须已上架(PUBLISHED)。") - @PutMapping("/{batchId}/open") - public Result openEnrollment(@PathVariable Long productId, @PathVariable Long batchId) { - batchService.openEnrollment(batchId); - return Result.success(); - } - -- @ApiOperation("关闭报名(ENROLLING/CONFIRMED->CLOSED)") -+ @ApiOperation(value = "关闭报名(ENROLLING/CONFIRMED->CLOSED)", -+ notes = "关闭批次报名,不再接受新的报名。\n" -+ + "已报名的订单不受影响,仅阻止新增报名。\n" -+ + "适用于报名截止日期到达或手动提前关闭的场景。") - @PutMapping("/{batchId}/close") - public Result closeEnrollment(@PathVariable Long productId, @PathVariable Long batchId) { - batchService.closeEnrollment(batchId); - return Result.success(); - } - -- @ApiOperation("解散批次") -+ @ApiOperation(value = "解散批次", -+ notes = "解散批次并处理已报名的订单。\n\n" -+ + "**重要**:解散操作会触发以下流程:\n" -+ + "1. 批次状态变更为 DISBANDED\n" -+ + "2. 通过 MQ 消息通知订单服务,自动取消该批次下的所有未完成订单\n" -+ + "3. 已支付订单会触发退款流程\n\n" -+ + "必须填写解散原因(如:报名人数不足、行程调整等)。") - @PostMapping("/{batchId}/disband") - public Result disbandBatch(@PathVariable Long productId, - @PathVariable Long batchId, -@@ -103,7 +140,13 @@ public class GroupBatchController { - - // ===== Staff operations ===== - -- @ApiOperation("保存服务人员(全量替换)") -+ @ApiOperation(value = "保存服务人员(全量替换)", -+ notes = "保存批次的服务人员配置,采用全量替换模式(先删后增)。\n\n" -+ + "每次提交完整的人员列表,替换掉该批次原有的所有人员配置。\n" -+ + "人员来源于资源服务的人员库,通过 staffId 关联。\n" -+ + "**角色类型**:LEADER(领队)/PHOTOGRAPHER(摄影师)/DRIVER(司机)/OTHER(其他)\n\n" -+ + "**关联字典**:\n" -+ + "- staff_type(人员类型):GUIDE=领队, DRIVER=司机, PHOTOGRAPHER=摄影师, ASSISTANT=助理, OTHER=其他") - @PostMapping("/{batchId}/staff") - public Result> saveStaff(@PathVariable Long productId, - @PathVariable Long batchId, -@@ -111,14 +154,18 @@ public class GroupBatchController { - return Result.success(staffService.saveStaff(batchId, productId, requests)); - } - -- @ApiOperation("服务人员列表") -+ @ApiOperation(value = "服务人员列表", -+ notes = "**关联字典**:\n" -+ + "- staff_type(人员类型):GUIDE=领队, DRIVER=司机, PHOTOGRAPHER=摄影师, ASSISTANT=助理, OTHER=其他") - @GetMapping("/{batchId}/staff") - public Result> listStaff(@PathVariable Long productId, - @PathVariable Long batchId) { - return Result.success(staffService.listStaff(batchId)); - } - -- @ApiOperation("从其他批次复制服务人员") -+ @ApiOperation(value = "从其他批次复制服务人员", -+ notes = "将源批次的服务人员配置复制到当前批次(全量替换当前批次已有人员)。\n" -+ + "适用场景:多个团期使用相同的服务人员班底。") - @PostMapping("/{batchId}/staff/copy-from/{sourceId}") - public Result> copyStaff(@PathVariable Long productId, - @PathVariable Long batchId, -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/InternalMpProductController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/InternalMpProductController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/InternalMpProductController.java -index 61d9a75..7a6ea65 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/InternalMpProductController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/InternalMpProductController.java -@@ -36,7 +36,7 @@ import java.util.Map; - * C端产品内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "【内部接口】小程序产品(Feign调用)") -+@Api(tags = "【内部接口】小程序产品(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/product") - @RequiredArgsConstructor -@@ -50,39 +50,56 @@ public class InternalMpProductController { - private final ProductPriceCalendarMapper priceCalendarMapper; - private final GroupTourBatchMapper groupTourBatchMapper; - -- @ApiOperation("产品列表") -+ @ApiOperation(value = "产品列表", -+ notes = "内部Feign接口,返回已上架产品列表。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,筛选+返回字段):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/list") - public Result> listProducts(@Valid MpProductQueryRequest query) { - return Result.success(productService.listPublishedProducts(query)); - } - -- @ApiOperation("产品详情") -+ @ApiOperation(value = "产品详情", -+ notes = "内部Feign接口,返回已上架产品详情。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态):PUBLISHED=已上架\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @GetMapping("/{productId}") - public Result getProduct(@PathVariable Long productId) { - return Result.success(productService.getPublishedProduct(productId)); - } - -- @ApiOperation("报价计算") -+ @ApiOperation(value = "报价计算", -+ notes = "内部服务间调用,供 hl-mp-service BFF 层 Feign 调用的报价计算接口。\n" -+ + "计算逻辑与管理后台报价一致,根据日期和人数计算总价。") - @PostMapping("/{productId}/quote") - public Result calculateQuote(@PathVariable Long productId, - @Valid @RequestBody QuoteRequest request) { - return Result.success(quoteCalculatorService.calculateQuote(productId, request)); - } - -- @ApiOperation("产品线列表(活跃)") -+ @ApiOperation(value = "产品线列表(活跃)", -+ notes = "内部服务间调用,供 hl-mp-service 获取所有启用的产品线列表,用于小程序端筛选。") - @GetMapping("/lines") - public Result> listActiveLines() { - return Result.success(productLineService.listAllActive()); - } - -- @ApiOperation("推荐产品列表") -+ @ApiOperation(value = "推荐产品列表", -+ notes = "返回推荐的已上架产品。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,返回字段):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/recommend") - public Result> listRecommendProducts( - @RequestParam(defaultValue = "6") int limit) { - return Result.success(productService.listRecommendProducts(limit)); - } - -- @ApiOperation("C端价格日历") -+ @ApiOperation(value = "C端价格日历", -+ notes = "内部服务间调用,供 hl-mp-service 获取产品的价格日历数据。\n\n" -+ + "可通过 startDate/endDate 限定查询范围,不传则返回今天及之后的所有可用日期。\n" -+ + "返回每天的售价和库存信息,供小程序端日历选择器使用。") - @GetMapping("/{productId}/price-calendar") - public Result>> getPriceCalendar( - @PathVariable Long productId, -@@ -91,7 +108,10 @@ public class InternalMpProductController { - return Result.success(priceCalendarService.getMpPriceCalendar(productId, startDate, endDate)); - } - -- @ApiOperation("产品最早可订日期") -+ @ApiOperation(value = "产品最早可订日期", -+ notes = "根据产品类型查询最早可预订日期。GROUP类型查批次出发日期,CORE/CUSTOM类型查价格日历。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,影响查询逻辑):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/earliest-booking-date") - public Result getEarliestBookingDate(@RequestParam Long productId) { - Product product = productMapper.selectById(productId); -@@ -137,7 +157,10 @@ public class InternalMpProductController { - } - } - -- @ApiOperation("定制师产品统计(C端用)") -+ @ApiOperation(value = "定制师产品统计(C端用)", -+ notes = "统计指定定制师已发布的产品数量。\n\n" -+ + "**关联字典**:\n" -+ + "- product_status(产品状态,统计条件):PUBLISHED=已上架") - @GetMapping("/designer-stats") - public Result> getDesignerStats(@RequestParam Long customizerId) { - long routeCount = productMapper.selectCount( -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/InternalProductController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/InternalProductController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/InternalProductController.java -index 978f513..7c0b2e7 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/InternalProductController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/InternalProductController.java -@@ -49,7 +49,7 @@ import java.util.stream.Collectors; - @RestController - @RequestMapping("/internal/product") - @RequiredArgsConstructor --@Api(tags = "【内部接口】产品(Feign调用)") -+@Api(tags = "【内部接口】产品(Feign调用)", hidden = true) - public class InternalProductController { - - private final ProductStatusService productStatusService; -@@ -66,8 +66,12 @@ public class InternalProductController { - private final GroupTourBatchMapper groupBatchMapper; - private final ObjectMapper objectMapper; - -+ @ApiOperation(value = "处理产品审批结果", -+ notes = "接收企微审批回调结果,更新产品状态。\n\n" -+ + "**关联字典**:\n" -+ + "- product_status(产品状态):PENDING_REVIEW=待审核, REVIEWED=已审核, REJECTED=已驳回, PUBLISHED=已上架") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@Valid @RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@Valid @RequestBody ApprovalResultDTO dto) { - try { - productStatusService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -@@ -78,10 +82,12 @@ public class InternalProductController { - } - } - -- /** -- * 获取产品详情(不过滤状态,供 order-service 创建订单时获取快照) -- * 可选传入 date 参数,传入后会从资源价格日历查询各节点的成本价并填入快照 -- */ -+ @ApiOperation(value = "获取产品详情(内部)", -+ notes = "不过滤状态,供 order-service 创建订单时获取快照。可选传入 date 参数查询各节点成本价。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态):DRAFT=草稿, PENDING_REVIEW=待审核, REVIEWED=已审核, REJECTED=已驳回, PUBLISHED=已上架, UNPUBLISHED=已下架, COMPLETED=已完成, ORDERED=已下单\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @GetMapping("/{productId}/detail") - public Result getProductDetail(@PathVariable Long productId, - @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) { -@@ -91,19 +97,20 @@ public class InternalProductController { - return Result.success(productService.getProduct(productId)); - } - -- /** -- * 报价计算(供 order-service 创建订单时自动报价) -- */ -+ @ApiOperation(value = "报价计算(内部)", -+ notes = "供 order-service 创建订单时自动报价。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,影响计算逻辑):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PostMapping("/{productId}/quote") - public Result calculateQuote(@PathVariable Long productId, - @Valid @RequestBody QuoteRequest request) { - return Result.success(quoteCalculatorService.calculateQuote(productId, request)); - } - -- /** -- * 简单报价:直接从价格日历取售价 × 人数,不走资源价格计算。 -- * 小童 = 儿童售价 × 折扣比例,幼童 = 固定价格。 -- */ -+ @ApiOperation(value = "简单报价(内部)", -+ notes = "直接从价格日历取售价乘以人数,不走资源价格计算。CUSTOM/ROUTE按整单,CORE/GROUP按人头。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,影响计算逻辑):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/{productId}/simple-quote") - public Result> simpleQuote( - @PathVariable Long productId, -@@ -253,6 +260,10 @@ public class InternalProductController { - /** - * Deduct stock (optimistic lock: only succeeds if stock >= count) - */ -+ @ApiOperation(value = "扣减库存(内部)", -+ notes = "内部服务间调用,供 order-service 创建订单时扣减价格日历库存。\n\n" -+ + "使用乐观锁机制:只有当库存 >= count 时才扣减成功。\n" -+ + "扣减失败返回错误(库存不足),调用方需处理失败情况。") - @PostMapping("/{productId}/deduct-stock") - public Result deductStock(@PathVariable Long productId, - @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") String date, -@@ -268,6 +279,9 @@ public class InternalProductController { - /** - * Restore stock (compensation for cancelled/expired orders) - */ -+ @ApiOperation(value = "恢复库存(内部)", -+ notes = "内部服务间调用,供 order-service 订单取消/过期时恢复价格日历库存。\n" -+ + "用于补偿已扣减的库存,恢复数量不校验上限。") - @PostMapping("/{productId}/restore-stock") - public Result restoreStock(@PathVariable Long productId, - @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") String date, -@@ -281,6 +295,9 @@ public class InternalProductController { - * Get itinerary resources (SCENIC/ACTIVITY/HOTEL) for review service. - * Returns deduplicated list of { resourceType, resourceId, resourceName }. - */ -+ @ApiOperation(value = "获取行程关联资源(内部)", -+ notes = "内部服务间调用,供 review-service 获取产品行程中关联的资源列表。\n\n" -+ + "返回去重后的景区(SCENIC)、活动(ACTIVITY)、酒店(HOTEL)资源,用于评价时选择关联的资源对象。") - @GetMapping("/{productId}/itinerary-resources") - public Result>> getItineraryResources(@PathVariable Long productId) { - // Allowed resource types for review -@@ -310,9 +327,11 @@ public class InternalProductController { - return Result.success(result); - } - -- /** -- * 变更定制产品状态(供 order-service 调用:下单→ORDERED / 取消→COMPLETED) -- */ -+ @ApiOperation(value = "变更定制产品状态(内部)", -+ notes = "供 order-service 调用:下单时 COMPLETED→ORDERED,取消时 ORDERED→COMPLETED。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,仅限CUSTOM):CUSTOM=定制产品\n" -+ + "- product_status(产品状态):COMPLETED=已完成, ORDERED=已下单") - @PutMapping("/{productId}/custom-status") - public Result changeCustomProductStatus(@PathVariable Long productId, - @RequestParam String targetStatus) { -@@ -339,6 +358,10 @@ public class InternalProductController { - /** - * Enroll participants (optimistic lock on batch). - */ -+ @ApiOperation(value = "报名入团(内部)", -+ notes = "内部服务间调用,供 order-service 下单时增加批次已报名人数。\n\n" -+ + "使用乐观锁机制:只有当剩余名额 >= peopleCount 时才报名成功。\n" -+ + "报名成功后自动检查是否满员(FULL)或达到成团条件(CONFIRMED)。") - @PostMapping("/batch/{batchId}/enroll") - public Result enrollBatch(@PathVariable Long batchId, - @RequestParam @Min(1) int peopleCount) { -@@ -349,6 +372,9 @@ public class InternalProductController { - /** - * Unenroll participants (compensation for cancellation). - */ -+ @ApiOperation(value = "退出报名(内部)", -+ notes = "内部服务间调用,供 order-service 订单取消/退款时减少批次已报名人数。\n" -+ + "用于补偿已报名的人数,恢复剩余名额。") - @PostMapping("/batch/{batchId}/unenroll") - public Result unenrollBatch(@PathVariable Long batchId, - @RequestParam @Min(1) int peopleCount) { -@@ -356,9 +382,10 @@ public class InternalProductController { - return Result.success(); - } - -- /** -- * Get batch info (for order snapshot). -- */ -+ @ApiOperation(value = "批次信息(内部)", -+ notes = "供 order-service 创建订单时获取批次快照。\n\n" -+ + "**关联字典**:\n" -+ + "- batch_status(批次状态,返回字段):PENDING=待开放, ENROLLING=报名中, CONFIRMED=已成团, FULL=已满员, CLOSED=已关闭, DISBANDED=已解散, IN_PROGRESS=进行中, FINISHED=已结束") - @GetMapping("/batch/{batchId}/info") - public Result> getBatchInfo(@PathVariable Long batchId) { - GroupTourBatch batch = groupTourBatchService.getBatchById(batchId); -@@ -385,6 +412,10 @@ public class InternalProductController { - /** - * GROUP quote: returns adult/child dynamic pricing for a batch. - */ -+ @ApiOperation(value = "GROUP产品报价(内部)", -+ notes = "内部服务间调用,供 order-service 和 mp-service 获取 GROUP 产品按套餐组合的报价。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,仅限GROUP):GROUP=小蒙马拼团") - @GetMapping("/{productId}/group-quote") - public Result getGroupQuote(@PathVariable Long productId, - @RequestParam Long batchId, -@@ -395,6 +426,9 @@ public class InternalProductController { - /** - * C-end calendar data for GROUP products. - */ -+ @ApiOperation(value = "团期日历数据(内部)", -+ notes = "内部服务间调用,供小程序端展示 GROUP 产品的团期日历。\n\n" -+ + "返回可报名批次的出发日期、状态、剩余名额等信息,用于日历选择器展示。") - @GetMapping("/{productId}/batches/calendar") - public Result> getBatchesCalendar(@PathVariable Long productId) { - return Result.success(groupTourBatchService.listCalendar(productId)); -@@ -403,6 +437,9 @@ public class InternalProductController { - /** - * C-end combo list for a batch (套餐列表). - */ -+ @ApiOperation(value = "批次套餐列表(内部)", -+ notes = "内部服务间调用,供小程序端展示 GROUP 产品批次下的套餐组合列表。\n\n" -+ + "每个套餐包含成人/儿童人数搭配、售价、原价、库存和已售数量。") - @GetMapping("/batch/{batchId}/combos") - public Result>> listBatchCombos(@PathVariable Long batchId) { - List combos = comboMapper.selectList( -@@ -431,7 +468,9 @@ public class InternalProductController { - - // ===== 定制师内部接口 ===== - -- @ApiOperation("获取定制师已发布产品ID列表") -+ @ApiOperation(value = "获取定制师已发布产品ID列表", -+ notes = "**关联字典**:\n" -+ + "- product_status(产品状态,筛选条件):PUBLISHED=已上架") - @GetMapping("/designer-published-ids") - public Result> getDesignerPublishedProductIds(@RequestParam Long createBy) { - List ids = productService.getDesignerPublishedProductIds(createBy); -@@ -439,19 +478,28 @@ public class InternalProductController { - return Result.success(strIds); - } - -- @ApiOperation("获取全局产品统计") -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/ItineraryController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/ItineraryController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/ItineraryController.java -index f813a83..7ea5e3b 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/ItineraryController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/ItineraryController.java -@@ -28,7 +28,10 @@ public class ItineraryController { - - // ========================= Day ========================= - -- @ApiOperation("更新行程天") -+ @ApiOperation(value = "更新行程天", -+ notes = "更新指定天的行程信息,如当天主题、概述等。\n" -+ + "行程天在创建产品时根据 tripDays 自动生成,不支持单独增删,只能更新。\n" -+ + "dayNumber 从 1 开始,对应第几天的行程。") - @PutMapping("/item/{productId}/day/{dayNumber}") - public Result updateDay( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -37,7 +40,9 @@ public class ItineraryController { - return Result.success(dayService.updateDay(productId, dayNumber, request)); - } - -- @ApiOperation("获取行程天列表") -+ @ApiOperation(value = "获取行程天列表", -+ notes = "获取产品所有行程天的信息,按 dayNumber 升序排列。\n" -+ + "每一天包含当天主题、概述等信息,不包含节点详情(节点通过单独接口获取)。") - @GetMapping("/item/{productId}/days") - public Result> listDays(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(dayService.listDays(productId)); -@@ -45,7 +50,14 @@ public class ItineraryController { - - // ========================= Node ========================= - -- @ApiOperation("添加行程节点") -+ @ApiOperation(value = "添加行程节点", -+ notes = "在指定天添加一个行程节点。节点是行程的最小单元,可关联资源服务中的景区、酒店、活动等。\n\n" -+ + "**节点类型**:TRANSPORT(交通)/SCENIC(景区)/DINING(餐饮)/ACTIVITY(活动)/" -+ + "PHOTOGRAPHY(摄影)/HOTEL(酒店)/FREE(自由活动)/CUSTOM(自定义)\n\n" -+ + "**CUSTOM 定制产品特有**:可通过 familyIds 指定节点所属的家庭分组,实现按家庭分配行程。\n" -+ + "新建节点自动追加到当天最后位置,可通过排序接口调整顺序。\n\n" -+ + "**关联字典**:\n" -+ + "- city(城市,资源面板筛选用):用于在添加节点时按城市筛选可选资源") - @PostMapping("/item/{productId}/day/{dayNumber}/node") - public Result createNode( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -54,7 +66,12 @@ public class ItineraryController { - return Result.success(nodeService.createNode(productId, dayNumber, request)); - } - -- @ApiOperation("更新行程节点") -+ @ApiOperation(value = "更新行程节点", -+ notes = "更新行程节点信息,仅传入需要修改的字段。\n" -+ + "可修改节点名称、时间、关联资源、图片、描述等。\n\n" -+ + "**关联字典**:\n" -+ + "- city(城市):资源面板城市筛选\n" -+ + "- cities(城市ID映射):城市名称预览") - @PutMapping("/node/{nodeId}") - public Result updateNode( - @ApiParam("行程节点ID") @PathVariable Long nodeId, -@@ -62,14 +79,17 @@ public class ItineraryController { - return Result.success(nodeService.updateNode(nodeId, request)); - } - -- @ApiOperation("删除行程节点") -+ @ApiOperation(value = "删除行程节点", -+ notes = "删除指定行程节点,同天其他节点的排序自动调整。") - @DeleteMapping("/node/{nodeId}") - public Result deleteNode(@ApiParam("行程节点ID") @PathVariable Long nodeId) { - nodeService.deleteNode(nodeId); - return Result.success(); - } - -- @ApiOperation("行程节点拖拽排序") -+ @ApiOperation(value = "行程节点拖拽排序", -+ notes = "重新排列指定天的所有行程节点顺序。前端拖拽排序后,将新的节点ID顺序全量提交。\n" -+ + "nodeIds 列表中的顺序即为新的排序顺序(从上到下)。") - @PutMapping("/item/{productId}/day/{dayNumber}/nodes/sort") - public Result sortNodes( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -79,13 +99,17 @@ public class ItineraryController { - return Result.success(); - } - -- @ApiOperation("复制行程节点") -+ @ApiOperation(value = "复制行程节点", -+ notes = "复制指定节点到同一天的末尾位置,包括节点的所有属性(名称、资源关联、图片等)。\n" -+ + "适用场景:同一天有相似的行程安排时快速复制。") - @PostMapping("/node/{nodeId}/copy") - public Result copyNode(@ApiParam("行程节点ID") @PathVariable Long nodeId) { - return Result.success(nodeService.copyNode(nodeId)); - } - -- @ApiOperation("移动行程节点到其他天") -+ @ApiOperation(value = "移动行程节点到其他天", -+ notes = "将节点从当前天移动到目标天的末尾位置。\n" -+ + "移动后原天和目标天的节点排序自动调整。") - @PutMapping("/node/{nodeId}/move") - public Result moveNode( - @ApiParam("行程节点ID") @PathVariable Long nodeId, -@@ -93,7 +117,12 @@ public class ItineraryController { - return Result.success(nodeService.moveNode(nodeId, request.getTargetDayNumber())); - } - -- @ApiOperation("获取某天的节点列表") -+ @ApiOperation(value = "获取某天的节点列表", -+ notes = "获取指定天的所有行程节点,按排序顺序返回。\n" -+ + "每个节点包含类型、名称、时间、关联资源信息、图片等完整数据。\n\n" -+ + "**关联字典**:\n" -+ + "- city(城市):资源面板城市筛选\n" -+ + "- cities(城市ID映射):城市名称预览") - @GetMapping("/item/{productId}/day/{dayNumber}/nodes") - public Result> listNodes( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -103,7 +132,10 @@ public class ItineraryController { - - // ========================= Hotel ========================= - -- @ApiOperation("添加每日住宿") -+ @ApiOperation(value = "添加每日住宿", -+ notes = "为指定天添加住宿安排,关联资源服务中的酒店和房型。\n" -+ + "每天可以有多个住宿选项(如不同档次),参与成本自动计算。\n" -+ + "住宿费用会体现在价格日历的成本计算中。") - @PostMapping("/item/{productId}/day/{dayNumber}/hotel") - public Result addHotel( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -112,7 +144,8 @@ public class ItineraryController { - return Result.success(hotelService.addHotel(productId, dayNumber, request)); - } - -- @ApiOperation("更新每日住宿") -+ @ApiOperation(value = "更新每日住宿", -+ notes = "更新住宿记录的酒店、房型、数量等信息。") - @PutMapping("/hotel/{id}") - public Result updateHotel( - @ApiParam("住宿记录ID") @PathVariable Long id, -@@ -120,14 +153,16 @@ public class ItineraryController { - return Result.success(hotelService.updateHotel(id, request)); - } - -- @ApiOperation("删除每日住宿") -+ @ApiOperation(value = "删除每日住宿", -+ notes = "删除指定住宿记录。删除后该天的住宿成本会从报价中移除。") - @DeleteMapping("/hotel/{id}") - public Result deleteHotel(@ApiParam("住宿记录ID") @PathVariable Long id) { - hotelService.deleteHotel(id); - return Result.success(); - } - -- @ApiOperation("获取某天的住宿列表") -+ @ApiOperation(value = "获取某天的住宿列表", -+ notes = "获取指定天的所有住宿安排,包含酒店名称、房型、数量等信息。") - @GetMapping("/item/{productId}/day/{dayNumber}/hotels") - public Result> listHotels( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -137,7 +172,9 @@ public class ItineraryController { - - // ========================= Dining ========================= - -- @ApiOperation("添加每日餐厅推荐") -+ @ApiOperation(value = "添加每日餐厅推荐", -+ notes = "为指定天添加餐饮推荐,关联资源服务中的餐厅。\n" -+ + "用于展示当天的用餐安排,可按早/午/晚分类。") - @PostMapping("/item/{productId}/day/{dayNumber}/dining") - public Result addDiningOption( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -146,7 +183,8 @@ public class ItineraryController { - return Result.success(diningOptionService.addDiningOption(productId, dayNumber, request)); - } - -- @ApiOperation("更新餐饮推荐") -+ @ApiOperation(value = "更新餐饮推荐", -+ notes = "更新餐饮推荐的餐厅、用餐类型(早/午/晚)、描述等信息。") - @PutMapping("/dining/{id}") - public Result updateDiningOption( - @ApiParam("餐饮推荐ID") @PathVariable Long id, -@@ -154,7 +192,8 @@ public class ItineraryController { - return Result.success(diningOptionService.updateDiningOption(id, request)); - } - -- @ApiOperation("获取某天的餐厅推荐列表") -+ @ApiOperation(value = "获取某天的餐厅推荐列表", -+ notes = "获取指定天的所有餐饮推荐,包含餐厅名称、用餐类型、描述等信息。") - @GetMapping("/item/{productId}/day/{dayNumber}/dining") - public Result> listDining( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -162,7 +201,8 @@ public class ItineraryController { - return Result.success(diningOptionService.listDiningOptions(productId, dayNumber)); - } - -- @ApiOperation("删除餐饮推荐") -+ @ApiOperation(value = "删除餐饮推荐", -+ notes = "删除指定的餐饮推荐记录。") - @DeleteMapping("/dining/{id}") - public Result deleteDiningOption(@ApiParam("餐饮推荐ID") @PathVariable Long id) { - diningOptionService.deleteDiningOption(id); -@@ -171,7 +211,9 @@ public class ItineraryController { - - // ========================= Supplies ========================= - -- @ApiOperation("添加物资配品") -+ @ApiOperation(value = "添加物资配品", -+ notes = "为产品添加物资配品(如帐篷、睡袋、登山杖等),关联资源服务中的物资。\n" -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/MpProductController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/MpProductController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/MpProductController.java -index 526bc16..94a6723 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/MpProductController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/MpProductController.java -@@ -31,19 +31,33 @@ public class MpProductController { - private final ProductService productService; - private final QuoteCalculatorService quoteCalculatorService; - -- @ApiOperation("产品列表") -+ @ApiOperation(value = "产品列表(C端)", -+ notes = "小程序端产品列表接口,仅返回已上架(PUBLISHED)的产品。\n\n" -+ + "支持按产品类型、季节、行程天数、目的地、产品线、支付模式、定制师等筛选。\n" -+ + "默认按 sortOrder 排序,也可按价格或行程天数排序。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,筛选条件):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/list") - public Result> listProducts(@ApiParam("产品查询请求") @Valid MpProductQueryRequest query) { - return Result.success(productService.listPublishedProducts(query)); - } - -- @ApiOperation("产品详情") -+ @ApiOperation(value = "产品详情(C端)", -+ notes = "小程序端产品详情接口,仅返回已上架(PUBLISHED)的产品。\n" -+ + "包含完整的行程信息、定价配置、费用说明、创作者寄语等。\n" -+ + "未上架的产品会返回 404 错误。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @GetMapping("/{productId}") - public Result getProduct(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(productService.getPublishedProduct(productId)); - } - -- @ApiOperation("报价计算") -+ @ApiOperation(value = "报价计算(C端)", -+ notes = "小程序端报价计算接口,根据用户选择的日期和人数计算总价。\n" -+ + "内部会校验产品是否存在且已上架。\n" -+ + "详细计算逻辑参见管理后台的报价计算接口说明。") - @PostMapping("/{productId}/quote") - public Result calculateQuote( - @ApiParam("产品ID") @PathVariable Long productId, -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/PricingController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/PricingController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/PricingController.java -index cdd0cb8..1599755 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/PricingController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/PricingController.java -@@ -28,7 +28,18 @@ public class PricingController { - - // ========== 定价规则 ========== - -- @ApiOperation("保存定价规则") -+ @ApiOperation(value = "保存定价规则", -+ notes = "保存或更新产品的定价配置(一个产品仅一条定价记录,重复调用为覆盖更新)。\n\n" -+ + "**定价模式**:\n" -+ + "- AUTO:自动计算,通过公式引擎根据行程资源价格自动测算成本和售价\n" -+ + "- MANUAL:手动定价,直接在价格日历中手动设置每日价格\n" -+ + "- CUSTOM:定制定价,设置整单总价(customTotalPrice),不按人头\n\n" -+ + "**利润模式**(AUTO 模式下生效):\n" -+ + "- FIXED:固定金额加价,售价 = 成本 + profitAmount\n" -+ + "- PERCENT:百分比加价,售价 = 成本 × (1 + markupPercent/100)\n\n" -+ + "**支付方式**:FULL=全款支付,DEPOSIT=定金+尾款(需设置 depositRatio 或 depositAmount)\n\n" -+ + "**关联字典**:\n" -+ + "- vehicle_type(车型):费用配置中车辆相关成本计算") - @PostMapping("/pricing") - public Result savePricing( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -36,7 +47,11 @@ public class PricingController { - return Result.success(pricingService.savePricing(productId, request)); - } - -- @ApiOperation("获取定价规则") -+ @ApiOperation(value = "获取定价规则", -+ notes = "获取产品的定价配置,包括定价模式、利润设置、儿童/婴儿价格、支付方式等。\n" -+ + "如果产品尚未设置定价规则,返回 null。\n\n" -+ + "**关联字典**:\n" -+ + "- vehicle_type(车型):费用配置中车辆相关成本显示") - @GetMapping("/pricing") - public Result getPricing(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(pricingService.getPricing(productId)); -@@ -44,7 +59,11 @@ public class PricingController { - - // ========== 价格日历 ========== - -- @ApiOperation("获取月度价格日历") -+ @ApiOperation(value = "获取月度价格日历", -+ notes = "获取指定月份的价格日历数据列表。\n\n" -+ + "每条数据包含:日期、成人售价/成本价、儿童售价/成本价、库存、状态(OPEN/CLOSED)等。\n" -+ + "**CORE/GROUP 产品**:价格为单人价格,按人头 × 价格计算总价。\n" -+ + "**CUSTOM/ROUTE 产品**:价格为整单总价,不乘以人头数。") - @GetMapping("/price-calendar") - public Result> getMonthCalendar( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -53,7 +72,10 @@ public class PricingController { - return Result.success(calendarService.getMonthCalendar(productId, year, month)); - } - -- @ApiOperation("设置单日价格") -+ @ApiOperation(value = "设置单日价格", -+ notes = "设置或更新指定日期的价格和库存。如果该日期已有记录则更新,否则新建。\n\n" -+ + "可设置成人售价/成本价、儿童售价/成本价、库存数量、状态(OPEN/CLOSED)。\n" -+ + "状态为 CLOSED 的日期不会出现在小程序端的可选日期中。") - @PostMapping("/price-calendar") - public Result setDayPrice( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -61,7 +83,11 @@ public class PricingController { - return Result.success(calendarService.setDayPrice(productId, request)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", -+ notes = "批量设置日期范围内的价格和库存,支持按星期筛选。\n\n" -+ + "指定 startDate 和 endDate 日期范围,可选 selectedWeekdays 过滤星期几。\n" -+ + "示例:设置5月1日-5月31日的工作日(周一到周五=[1,2,3,4,5])价格。\n" -+ + "selectedWeekdays 为空时,范围内所有日期都会被设置。") - @PostMapping("/price-calendar/batch") - public Result> batchSetPrices( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -69,7 +95,13 @@ public class PricingController { - return Result.success(calendarService.batchSetPrices(productId, request)); - } - -- @ApiOperation("测算预览(不写入数据库)") -+ @ApiOperation(value = "测算预览(不写入数据库)", -+ notes = "根据行程中的资源价格日历,自动计算指定日期的成本价和售价,仅预览不保存。\n\n" -+ + "用于在设置价格日历前预览自动计算的结果。\n" -+ + "计算逻辑:汇总当天所有行程节点关联资源的价格 → 应用公式引擎 → 加上利润。\n" -+ + "GROUP 产品需要传 adultCount 参数(影响均摊计算)。\n\n" -+ + "**关联字典**:\n" -+ + "- vehicle_type(车型):车辆费用成本测算") - @PostMapping("/price-calendar/calc-preview") - public Result calcPreview( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -77,13 +109,21 @@ public class PricingController { - return Result.success(calendarService.calcPreview(productId, request)); - } - -- @ApiOperation("重新测算所有自动测算日期的价格") -+ @ApiOperation(value = "重新测算所有自动测算日期的价格", -+ notes = "重新计算价格日历中所有 costAutoCalc=true 的日期的成本价和售价。\n\n" -+ + "适用场景:资源价格调整后,批量刷新所有自动计算的价格日历。\n" -+ + "返回更新的日期数量和详情。手动设置的价格(costAutoCalc=false)不受影响。") - @PostMapping("/price-calendar/recalculate") - public Result> recalculate(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(calendarService.recalculateAll(productId)); - } - -- @ApiOperation("自动计算成本并同步到价格日历") -+ @ApiOperation(value = "自动计算成本并同步到价格日历", -+ notes = "根据出发日期和人数,自动计算成本并将结果写入价格日历。\n\n" -+ + "与测算预览不同,此接口会实际更新价格日历数据。\n" -+ + "计算逻辑:查询各资源的价格日历 → 汇总成本 → 应用公式和利润规则 → 写入结果。\n\n" -+ + "**关联字典**:\n" -+ + "- vehicle_type(车型):车辆费用成本计算") - @PostMapping("/price-calendar/auto-calc") - public Result autoCalcCost( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -100,7 +140,10 @@ public class PricingController { - - // ========== 费用包含/不包含 ========== - -- @ApiOperation("添加费用项") -+ @ApiOperation(value = "添加费用项", -+ notes = "添加产品的费用包含/不包含说明项。\n\n" -+ + "用于在产品详情页展示\"费用包含\"和\"费用不包含\"信息。\n" -+ + "仅用于前端展示,不参与报价计算。") - @PostMapping("/cost-item") - public Result addCostItem( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -108,7 +151,8 @@ public class PricingController { - return Result.success(costItemService.addCostItem(productId, request)); - } - -- @ApiOperation("更新费用项") -+ @ApiOperation(value = "更新费用项", -+ notes = "更新费用包含/不包含说明项的内容。仅用于前端展示,不参与报价计算。") - @PutMapping("/cost-item/{itemId}") - public Result updateCostItem( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -117,7 +161,8 @@ public class PricingController { - return Result.success(costItemService.updateCostItem(itemId, request)); - } - -- @ApiOperation("删除费用项") -+ @ApiOperation(value = "删除费用项", -+ notes = "删除费用包含/不包含说明项。") - @DeleteMapping("/cost-item/{itemId}") - public Result deleteCostItem( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -126,7 +171,8 @@ public class PricingController { - return Result.success(); - } - -- @ApiOperation("获取费用项列表") -+ @ApiOperation(value = "获取费用项列表", -+ notes = "获取产品的所有费用包含/不包含说明项列表。") - @GetMapping("/cost-items") - public Result> listCostItems(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(costItemService.listCostItems(productId)); -@@ -134,7 +180,10 @@ public class PricingController { - - // ========== 额外成本关联 ========== - -- @ApiOperation("添加额外成本关联") -+ @ApiOperation(value = "添加额外成本关联", -+ notes = "关联资源服务中的费用项(cost_item)到产品,参与成本自动计算。\n\n" -+ + "额外成本是指不包含在行程节点中、但需要计入总成本的费用。\n" -+ + "例如:导游服务费、保险费、通讯费等固定运营开支。") - @PostMapping("/extra-cost") - public Result addExtraCost( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -142,7 +191,8 @@ public class PricingController { - return Result.success(extraCostService.addExtraCost(productId, request)); - } - -- @ApiOperation("更新额外成本关联") -+ @ApiOperation(value = "更新额外成本关联", -+ notes = "更新额外成本关联的费用项、数量等信息。修改后会影响成本自动计算结果。") - @PutMapping("/extra-cost/{ecId}") - public Result updateExtraCost( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -151,7 +201,8 @@ public class PricingController { - return Result.success(extraCostService.updateExtraCost(ecId, request)); - } - -- @ApiOperation("删除额外成本关联") -+ @ApiOperation(value = "删除额外成本关联", -+ notes = "删除额外成本关联记录。删除后该费用项不再计入成本自动计算。") - @DeleteMapping("/extra-cost/{ecId}") - public Result removeExtraCost( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -160,7 +211,8 @@ public class PricingController { - return Result.success(); - } - -- @ApiOperation("获取额外成本关联列表") -+ @ApiOperation(value = "获取额外成本关联列表", -+ notes = "获取产品关联的所有额外成本项列表,包含费用项名称、金额等信息。") - @GetMapping("/extra-costs") - public Result> listExtraCosts(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(extraCostService.listExtraCosts(productId)); -@@ -168,7 +220,10 @@ public class PricingController { - -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/ProductController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductController.java -index bc250d7..5f48dff 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductController.java -@@ -28,7 +28,20 @@ public class ProductController { - private final ProductStatusService productStatusService; - private final RouteMapService routeMapService; - -- @ApiOperation("创建产品(草稿)") -+ @ApiOperation(value = "创建产品(草稿)", -+ notes = "创建一个新产品,初始状态为 DRAFT(草稿)。\n\n" -+ + "**产品类型说明**:\n" -+ + "- CORE:核心产品,标准旅游产品,支持上架/下架审批流程\n" -+ + "- GROUP:小蒙马拼团,需配合团期批次管理,按人头计价\n" -+ + "- CUSTOM:定制产品,由定制师为客户量身定制,按单计价\n" -+ + "- ROUTE:线路产品,预设线路模板,按单计价\n\n" -+ + "**注意事项**:\n" -+ + "- 创建后需依次完善行程、定价、价格日历等信息\n" -+ + "- CUSTOM/ROUTE 产品的价格日历存储的是整单总价,不按人头乘算\n" -+ + "- GROUP 产品需额外创建团期批次才能报名\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @PostMapping - public Result createProduct( - @ApiParam("创建产品请求") @Valid @RequestBody ProductCreateRequest request, -@@ -37,13 +50,28 @@ public class ProductController { - return Result.success(productService.createProduct(request, adminId)); - } - -- @ApiOperation("获取产品详情") -+ @ApiOperation(value = "获取产品详情", -+ notes = "获取产品完整信息,包括基本信息、行程天列表、定价配置、费用项等。\n" -+ + "返回数据包含关联的行程节点资源详情,适用于产品编辑页面。\n" -+ + "不过滤产品状态,所有状态的产品都可查看。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态):DRAFT=草稿, PENDING_REVIEW=待审核, REVIEWED=已审核, REJECTED=已驳回, PUBLISHED=已上架, UNPUBLISHED=已下架, COMPLETED=已完成, ORDERED=已下单\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @GetMapping("/{productId}") - public Result getProduct(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(productService.getProduct(productId)); - } - -- @ApiOperation("更新产品") -+ @ApiOperation(value = "更新产品", -+ notes = "更新产品基本信息,仅传入需要修改的字段,未传字段不会被覆盖。\n\n" -+ + "**权限说明**:\n" -+ + "- 普通管理员只能编辑自己创建的产品\n" -+ + "- SUPER_ADMIN 可编辑所有产品\n\n" -+ + "**注意**:行程、定价、价格日历等通过各自独立的接口管理,不在此接口中处理。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @PutMapping("/{productId}") - public Result updateProduct( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -54,7 +82,10 @@ public class ProductController { - return Result.success(productService.updateProduct(productId, request, adminId, role)); - } - -- @ApiOperation("删除产品") -+ @ApiOperation(value = "删除产品", -+ notes = "软删除产品(设置 deleted_at 字段)。\n\n" -+ + "**权限说明**:普通管理员只能删除自己创建的产品,SUPER_ADMIN 可删除所有产品。\n" -+ + "**限制**:已上架(PUBLISHED)的产品不能直接删除,需先下架。") - @DeleteMapping("/{productId}") - public Result deleteProduct( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -65,17 +96,33 @@ public class ProductController { - return Result.success(); - } - -- @ApiOperation("产品列表") -+ @ApiOperation(value = "产品列表", -+ notes = "分页查询产品列表,支持多维度筛选和排序。\n\n" -+ + "**权限说明**:\n" -+ + "- 普通管理员只能看到自己创建的产品\n" -+ + "- SUPER_ADMIN 可看到所有产品\n\n" -+ + "**筛选条件**:关键词(名称/副标题模糊匹配)、产品类型、状态、文件夹、产品线、季节、行程天数。\n" -+ + "支持多状态筛选(statuses 字段,逗号分隔)。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,筛选条件):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态,筛选条件+返回字段):DRAFT=草稿, PENDING_REVIEW=待审核, REVIEWED=已审核, REJECTED=已驳回, PUBLISHED=已上架, UNPUBLISHED=已下架, COMPLETED=已完成, ORDERED=已下单") - @GetMapping("/list") - public Result> listProducts( - @ApiParam("产品查询请求") @Valid ProductQueryRequest query, - HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -- boolean isSuperAdmin = "SUPER_ADMIN".equals(httpRequest.getAttribute("role")); -- return Result.success(productService.listProducts(query, adminId, isSuperAdmin)); -+ String role = (String) httpRequest.getAttribute("role"); -+ boolean canViewAll = "SUPER_ADMIN".equals(role) || "CUSTOMER_SERVICE".equals(role); -+ return Result.success(productService.listProducts(query, adminId, canViewAll)); - } - -- @ApiOperation("复制产品") -+ @ApiOperation(value = "复制产品", -+ notes = "深度复制产品,包括行程天、行程节点、定价配置、住宿、餐饮、物资、人员配置等所有关联数据。\n\n" -+ + "复制后的产品状态为 DRAFT,名称自动添加\"(副本)\"后缀。\n" -+ + "适用场景:基于已有产品快速创建新产品。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,返回字段):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态,复制后固定为 DRAFT)") - @PostMapping("/{productId}/copy") - public Result copyProduct( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -84,7 +131,9 @@ public class ProductController { - return Result.success(productService.copyProduct(productId, adminId)); - } - -- @ApiOperation("移动产品到文件夹") -+ @ApiOperation(value = "移动产品到文件夹", -+ notes = "将产品移动到指定文件夹,或移出文件夹(folderId 传空字符串或 null)。\n" -+ + "文件夹用于组织管理产品,不影响产品的业务逻辑。") - @PutMapping("/{productId}/move") - public Result moveProduct( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -95,7 +144,10 @@ public class ProductController { - return Result.success(); - } - -- @ApiOperation("生成定制产品分享链接") -+ @ApiOperation(value = "生成定制产品分享链接", -+ notes = "为 CUSTOM(定制)产品生成小程序分享链接,用于定制师发送给客户查看方案。\n\n" -+ + "**限制**:仅 CUSTOM 类型且状态为 COMPLETED 的产品可生成。\n" -+ + "**权限**:普通管理员只能为自己创建的产品生成链接,SUPER_ADMIN 不受限制。") - @PostMapping("/{productId}/share-link") - public Result generateShareLink( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -105,7 +157,10 @@ public class ProductController { - return Result.success(productService.generateShareLink(productId, adminId, role)); - } - -- @ApiOperation("手动生成路径图") -+ @ApiOperation(value = "手动生成路径图", -+ notes = "根据产品行程节点的经纬度信息,调用地图API生成行程路径图。\n\n" -+ + "通常在行程编辑完成后手动触发,生成结果为 OSS 图片 URL。\n" -+ + "如果行程节点没有经纬度信息,则无法生成路径图。") - @PostMapping("/{productId}/generate-route-map") - public Result generateRouteMap(@ApiParam("产品ID") @PathVariable Long productId) { - try { -@@ -116,7 +171,20 @@ public class ProductController { - } - } - -- @ApiOperation("产品状态变更(上架/下架等)") -+ @ApiOperation(value = "产品状态变更(上架/下架/完成)", -+ notes = "根据产品类型,状态流转规则不同:\n\n" -+ + "**核心产品(CORE) / 小蒙马(GROUP)**:支持上架/下架,需企微审批\n" -+ + "- DRAFT → PENDING_REVIEW → REVIEWED → PUBLISHED(上架)\n" -+ + "- PUBLISHED → UNPUBLISHED(下架)\n" -+ + "- UNPUBLISHED → PUBLISHED(重新上架)\n" -+ + "- REJECTED → DRAFT(驳回后重新编辑)\n\n" -+ + "**定制产品(CUSTOM)**:仅支持完成,无上架/下架概念\n" -+ + "- DRAFT → COMPLETED(定制师完成设计)\n" -+ + "- COMPLETED → ORDERED(客户下单,系统自动变更)\n" -+ + "- ORDERED → COMPLETED(订单取消/退款后回退)\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,影响状态流转规则):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态,请求+返回字段):DRAFT=草稿, PENDING_REVIEW=待审核, REVIEWED=已审核, REJECTED=已驳回, PUBLISHED=已上架, UNPUBLISHED=已下架, COMPLETED=已完成, ORDERED=已下单") - @PutMapping("/{productId}/status") - public Result changeStatus( - @ApiParam("产品ID") @PathVariable Long productId, -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/ProductFolderController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductFolderController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductFolderController.java -index 2562b23..2b69413 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductFolderController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductFolderController.java -@@ -23,7 +23,9 @@ public class ProductFolderController { - - private final ProductFolderService folderService; - -- @ApiOperation("创建文件夹") -+ @ApiOperation(value = "创建文件夹", -+ notes = "创建产品文件夹,用于组织管理产品。支持多级目录结构。\n" -+ + "文件夹归属于创建人,普通管理员只能看到自己的文件夹。") - @PostMapping - public Result createFolder( - @ApiParam("创建文件夹请求") @Valid @RequestBody FolderCreateRequest request, -@@ -33,7 +35,9 @@ public class ProductFolderController { - return Result.success(folderService.createFolder(request, adminId, ownerName)); - } - -- @ApiOperation("更新文件夹") -+ @ApiOperation(value = "更新文件夹", -+ notes = "更新文件夹名称等信息。\n" -+ + "**权限说明**:普通管理员只能更新自己创建的文件夹,SUPER_ADMIN 可更新任何文件夹。") - @PutMapping("/{folderId}") - public Result updateFolder( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -44,7 +48,9 @@ public class ProductFolderController { - return Result.success(folderService.updateFolder(folderId, request, adminId, isSuperAdmin)); - } - -- @ApiOperation("删除文件夹") -+ @ApiOperation(value = "删除文件夹", -+ notes = "删除文件夹。如果文件夹下有产品,产品会自动移到根目录(folderId 置空)。\n" -+ + "普通管理员只能删除自己的文件夹,SUPER_ADMIN 可删除任何文件夹。") - @DeleteMapping("/{folderId}") - public Result deleteFolder(@ApiParam("文件夹ID") @PathVariable Long folderId, HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -@@ -53,7 +59,10 @@ public class ProductFolderController { - return Result.success(); - } - -- @ApiOperation("获取文件夹树") -+ @ApiOperation(value = "获取文件夹树", -+ notes = "获取当前用户可见的文件夹树形结构。\n" -+ + "普通管理员只能看到自己创建的文件夹,SUPER_ADMIN 可看到所有文件夹。\n" -+ + "返回结构为嵌套的树形列表,包含每个文件夹的子文件夹。") - @GetMapping("/tree") - public Result> getFolderTree(HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/ProductLineController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductLineController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductLineController.java -index 28d7d17..13683ab 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductLineController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductLineController.java -@@ -25,7 +25,9 @@ public class ProductLineController { - - private final ProductLineService lineService; - -- @ApiOperation("创建产品线") -+ @ApiOperation(value = "创建产品线", -+ notes = "创建产品线,用于对产品进行业务分类(如:亲子游、蜜月游、探险游等)。\n" -+ + "产品线在小程序端可作为筛选条件,帮助用户快速找到感兴趣的产品类别。") - @PostMapping - public Result createLine( - @ApiParam("创建产品线请求") @Valid @RequestBody LineCreateRequest request, -@@ -34,7 +36,8 @@ public class ProductLineController { - return Result.success(lineService.createLine(request, adminId)); - } - -- @ApiOperation("更新产品线") -+ @ApiOperation(value = "更新产品线", -+ notes = "更新产品线名称、描述、状态等信息。") - @PutMapping("/{lineId}") - public Result updateLine( - @ApiParam("产品线ID") @PathVariable Long lineId, -@@ -42,26 +45,31 @@ public class ProductLineController { - return Result.success(lineService.updateLine(lineId, request)); - } - -- @ApiOperation("删除产品线") -+ @ApiOperation(value = "删除产品线", -+ notes = "删除产品线(软删除)。已关联产品的产品线仍可删除,但关联产品的产品线字段不会被清空。") - @DeleteMapping("/{lineId}") - public Result deleteLine(@ApiParam("产品线ID") @PathVariable Long lineId) { - lineService.deleteLine(lineId); - return Result.success(); - } - -- @ApiOperation("产品线详情") -+ @ApiOperation(value = "产品线详情", -+ notes = "获取指定产品线的完整信息。") - @GetMapping("/{lineId}") - public Result getLine(@ApiParam("产品线ID") @PathVariable Long lineId) { - return Result.success(lineService.getLine(lineId)); - } - -- @ApiOperation("产品线列表(分页)") -+ @ApiOperation(value = "产品线列表(分页)", -+ notes = "分页查询产品线列表,支持按名称关键词筛选。") - @GetMapping("/list") - public Result> listLines(@ApiParam("产品线查询请求") @Valid LineQueryRequest query) { - return Result.success(lineService.listLines(query)); - } - -- @ApiOperation("所有启用的产品线") -+ @ApiOperation(value = "所有启用的产品线", -+ notes = "获取所有启用状态的产品线,不分页。\n" -+ + "适用于产品编辑时的产品线下拉选择,以及小程序端的筛选项。") - @GetMapping("/active") - public Result> listAllActive() { - return Result.success(lineService.listAllActive()); -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/QuoteController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/QuoteController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/QuoteController.java -index b6676e4..81f33f0 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/QuoteController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/QuoteController.java -@@ -23,7 +23,18 @@ public class QuoteController { - private final QuoteCalculatorService quoteCalculatorService; - private final CostCalculationService costCalculationService; - -- @ApiOperation("计算报价") -+ @ApiOperation(value = "计算报价", -+ notes = "根据出发日期和人数组合,计算产品的完整报价。\n\n" -+ + "**计算流程**:\n" -+ + "1. 从价格日历获取指定日期的单价\n" -+ + "2. 按人数类型分别计算:成人 × 成人价、儿童 × 儿童价\n" -+ + "3. 小童按儿童价 × 折扣比例(childDiscountPercent)计算\n" -+ + "4. 婴儿使用固定价格(babyPrice)\n" -+ + "5. 儿童加床(childNeedBed=true)额外加收 childWithBed 费用\n\n" -+ + "**CUSTOM/ROUTE 产品**:价格日历存的是整单总价,不按人头乘算。\n" -+ + "**GROUP 产品**:建议使用 group-quote 接口,支持套餐组合报价。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,影响计算逻辑):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PostMapping("/quote") - public Result calculateQuote( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -31,7 +42,13 @@ public class QuoteController { - return Result.success(quoteCalculatorService.calculateQuote(productId, request)); - } - -- @ApiOperation("GROUP产品报价(按组合)") -+ @ApiOperation(value = "GROUP产品报价(按套餐组合)", -+ notes = "为 GROUP(小蒙马拼团)产品按团期批次和套餐组合计算报价。\n\n" -+ + "GROUP 产品的价格由批次下的套餐组合(combo)决定,不同组合有不同的成人/儿童人数搭配和价格。\n" -+ + "传入 batchId 指定团期批次,adultCount 用于匹配合适的套餐组合。\n\n" -+ + "**与普通报价的区别**:普通报价从价格日历取单价,GROUP 报价从套餐组合取打包价。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,仅限GROUP):GROUP=小蒙马拼团") - @GetMapping("/group-quote") - public Result calculateGroupQuote( - @ApiParam("产品ID") @PathVariable Long productId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityController.java b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityController.java -index ab64e9e..4015f1e 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityController.java -@@ -26,7 +26,7 @@ public class ActivityController { - - private final ActivityService activityService; - -- @ApiOperation("创建游玩项目") -+ @ApiOperation(value = "创建游玩项目", notes = "新建游玩项目资源(如漂流、骑行、篝火晚会等),初始状态为草稿(status=0)。需通过「提交启用/禁用审批」走企微审批后上架。支持按项收费(PER_ITEM)和按人收费(PER_PERSON)两种计费方式。\n\n**关联字典**:\n- activity_category:活动分类(表单选择)\n- activity_billing_type:计费方式(表单选择)") - @PostMapping("/item") - public Result createActivity( - @ApiParam("游玩项目创建请求") @Valid @RequestBody ActivityCreateRequest request, -@@ -35,19 +35,19 @@ public class ActivityController { - return Result.success(activityService.createActivity(request, adminId)); - } - -- @ApiOperation("游玩项目列表") -+ @ApiOperation(value = "游玩项目列表", notes = "分页查询游玩项目列表,支持按名称、状态、分类等条件筛选。返回摘要信息,按sortOrder倒序+创建时间倒序排列。\n\n**关联字典**:\n- activity_category:活动分类(筛选+列表显示)\n- activity_billing_type:计费方式(列表显示)") - @GetMapping("/items") - public Result> listActivities(@ApiParam("游玩项目查询请求") @Valid ActivityQueryRequest query) { - return Result.success(activityService.listActivities(query)); - } - -- @ApiOperation("游玩项目详情") -+ @ApiOperation(value = "游玩项目详情", notes = "获取游玩项目完整信息,包含富文本内容、素材URL、标签、价格日历等。\n\n**关联字典**:\n- activity_category:活动分类(详情显示)\n- activity_billing_type:计费方式(详情显示)") - @GetMapping("/item/{activityId}") - public Result getActivity(@ApiParam("游玩项目ID") @PathVariable Long activityId) { - return Result.success(activityService.getActivity(activityId)); - } - -- @ApiOperation("更新游玩项目") -+ @ApiOperation(value = "更新游玩项目", notes = "更新游玩项目基本信息,不改变当前状态。已上架的项目修改后仍保持上架。\n\n**关联字典**:\n- activity_category:活动分类(表单选择)\n- activity_billing_type:计费方式(表单选择)") - @PutMapping("/item/{activityId}") - public Result updateActivity( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -57,7 +57,7 @@ public class ActivityController { - return Result.success(activityService.updateActivity(activityId, request, adminId)); - } - -- @ApiOperation("删除游玩项目") -+ @ApiOperation(value = "删除游玩项目", notes = "软删除游玩项目。仅SUPER_ADMIN或创建者可操作。删除后关联的素材引用会被清理。") - @DeleteMapping("/item/{activityId}") - public Result deleteActivity( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -68,7 +68,7 @@ public class ActivityController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交审批。targetStatus=1申请上架,targetStatus=2申请下架。审批通过后自动更新状态,返回审批单号spNo。") - @PostMapping("/item/{activityId}/submit-approval") - public Result> submitApproval( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -80,7 +80,7 @@ public class ActivityController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("启用/禁用切换") -+ @ApiOperation(value = "启用/禁用切换", notes = "直接修改状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/item/{activityId}/status") - public Result updateStatus( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -91,7 +91,7 @@ public class ActivityController { - return Result.success(); - } - -- @ApiOperation("批量启用/禁用") -+ @ApiOperation(value = "批量启用/禁用", notes = "批量修改多个游玩项目的状态,跳过审批流程。") - @PutMapping("/items/batch/status") - public Result batchUpdateStatus( - @ApiParam("游玩项目状态请求") @Valid @RequestBody ActivityStatusRequest request, -@@ -103,7 +103,7 @@ public class ActivityController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个游玩项目。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/items/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityPriceCalendarController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityPriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityPriceCalendarController.java -index 9fec542..3fff48f 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityPriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityPriceCalendarController.java -@@ -25,7 +25,7 @@ public class ActivityPriceCalendarController { - - private final ActivityPriceCalendarService priceService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询游玩项目的每日价格和可接待状态。") - @GetMapping("/item/{activityId}/prices") - public Result getPriceCalendar( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -34,7 +34,7 @@ public class ActivityPriceCalendarController { - return Result.success(priceService.getPriceCalendar(activityId, year, month)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", notes = "在指定日期范围内批量设置成本价和可接待状态。支持按星期过滤和排除特定日期。") - @PutMapping("/item/{activityId}/prices") - public Result batchSetPrices( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -43,7 +43,7 @@ public class ActivityPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改可接待状态") -+ @ApiOperation(value = "批量修改可接待状态", notes = "批量修改指定日期范围内的可接待状态,不影响价格。") - @PutMapping("/item/{activityId}/prices/batch-status") - public Result batchUpdateStatus( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -52,7 +52,7 @@ public class ActivityPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量清除价格") -+ @ApiOperation(value = "批量清除价格", notes = "删除指定日期范围内的所有价格记录。日期格式:yyyy-MM-dd。") - @DeleteMapping("/item/{activityId}/prices") - public Result deletePrices( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityTagController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityTagController.java -index 2a01cd2..80b72a0 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityTagController.java -@@ -27,7 +27,7 @@ public class ActivityTagController { - - private final ActivityTagService tagService; - -- @ApiOperation("获取管理标签列表(分页)") -+ @ApiOperation(value = "获取管理标签列表(分页)", notes = "分页查询游玩项目标签库,支持按关键词搜索。包含预设标签和自定义标签。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class ActivityTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("获取全部标签") -+ @ApiOperation(value = "获取全部标签", notes = "不分页返回所有标签,用于项目编辑时的标签选择下拉。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建管理标签") -+ @ApiOperation(value = "创建管理标签", notes = "创建预设标签,标签名不可重复。可指定颜色(tagColor),默认#409EFF。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class ActivityTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "按名称查找或自动创建标签。用于项目编辑时快速输入新标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class ActivityTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("编辑标签") -+ @ApiOperation(value = "编辑标签", notes = "修改标签名称或颜色,所有关联项目自动生效。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class ActivityTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并自动解除所有项目与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("更新项目标签") -+ @ApiOperation(value = "更新项目标签", notes = "全量替换指定项目的标签列表。传入tagIds为最终关联的标签ID列表,为空则清除所有标签。") - @PutMapping("/item/{activityId}/tags") - public Result updateActivityTags( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -87,7 +87,7 @@ public class ActivityTagController { - return Result.success(); - } - -- @ApiOperation("批量打标签") -+ @ApiOperation(value = "批量打标签", notes = "对多个项目批量添加/移除标签。增量操作,不影响未指定的标签。") - @PutMapping("/items/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalActivityController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalActivityController.java b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalActivityController.java -index e24ce98..1b5dd8f 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalActivityController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalActivityController.java -@@ -17,7 +17,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】游玩项目(Feign调用)") -+@Api(tags = "【内部接口】游玩项目(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/activity") - @RequiredArgsConstructor -@@ -25,7 +25,7 @@ public class InternalActivityController { - - private final ActivityService activityService; - -- @ApiOperation("获取项目简要信息") -+ @ApiOperation(value = "获取项目简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个游玩项目的简要信息,返回ID、名称、分类编码、计费类型、状态。不存在时返回错误。\n\n**关联字典**:\n- activity_category(活动分类,返回字段categoryCode):OUTDOOR=户外, INDOOR=室内, CULTURAL=文化, ADVENTURE=探险\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/item/{activityId}") - public Result> getActivityBrief(@PathVariable Long activityId) { - Activity item = activityService.getActivityEntity(activityId); -@@ -41,7 +41,7 @@ public class InternalActivityController { - return Result.success(brief); - } - -- @ApiOperation("批量获取项目简要信息") -+ @ApiOperation(value = "批量获取项目简要信息", notes = "【仅限内部Feign调用】批量获取游玩项目简要信息,最多500个ID。不存在的ID自动过滤,返回实际找到的项目列表。供产品服务批量查询行程节点绑定的活动资源。\n\n**关联字典**:\n- activity_category(活动分类,返回字段categoryCode):OUTDOOR=户外, INDOOR=室内, CULTURAL=文化, ADVENTURE=探险\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/items/batch") - public Result>> getActivityBatch(@RequestParam @Size(max = 500) List activityIds) { - List> results = activityIds.stream() -@@ -61,9 +61,9 @@ public class InternalActivityController { - return Result.success(results); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo(审批单号)匹配游玩项目并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - activityService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalMpActivityController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalMpActivityController.java b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalMpActivityController.java -index 63164c0..03e9f1d 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalMpActivityController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalMpActivityController.java -@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.*; - /** - * C端活动内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - */ --@Api(tags = "【内部接口】小程序活动(Feign调用)") -+@Api(tags = "【内部接口】小程序活动(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/activity") - @RequiredArgsConstructor -@@ -22,14 +22,14 @@ public class InternalMpActivityController { - - private final ActivityService activityService; - -- @ApiOperation("C端活动列表") -+ @ApiOperation(value = "C端活动列表", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用。强制status=1只返回已上架活动,支持分页和筛选。C端用户通过小程序间接访问。\n\n**关联字典**:\n- activity_category(活动分类,返回字段categoryCode):OUTDOOR=户外, INDOOR=室内, CULTURAL=文化, ADVENTURE=探险\n- environment_type(环境类型,返回字段environmentType):INDOOR=室内, OUTDOOR=户外, MIXED=混合") - @GetMapping("/list") - public Result> listActivities(ActivityQueryRequest query) { - query.setStatus(1); - return Result.success(activityService.listActivities(query)); - } - -- @ApiOperation("C端活动详情") -+ @ApiOperation(value = "C端活动详情", notes = "【仅限内部Feign调用】供mp-service获取活动完整详情,包含封面、轮播图、标签、富文本介绍等。注意:不限制status,由BFF层校验是否展示。\n\n**关联字典**:\n- activity_category(活动分类,返回字段categoryCode):OUTDOOR=户外, INDOOR=室内, CULTURAL=文化, ADVENTURE=探险\n- environment_type(环境类型,返回字段environmentType):INDOOR=室内, OUTDOOR=户外, MIXED=混合") - @GetMapping("/{activityId}") - public Result getActivityDetail(@PathVariable Long activityId) { - ActivityVO vo = activityService.getActivity(activityId); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalMpResourceBriefController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalMpResourceBriefController.java b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalMpResourceBriefController.java -index 3fcaf95..a7c45f5 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalMpResourceBriefController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalMpResourceBriefController.java -@@ -40,7 +40,7 @@ import java.util.stream.Collectors; - */ - @Slf4j - @Validated --@Api(tags = "【内部接口】资源摘要(Feign调用)") -+@Api(tags = "【内部接口】资源摘要(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/resource") - @RequiredArgsConstructor -@@ -60,7 +60,7 @@ public class InternalMpResourceBriefController { - - private final MaterialRefFeignClient materialRefClient; - -- @ApiOperation("批量查询景区摘要") -+ @ApiOperation(value = "批量查询景区摘要", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用(收藏列表/足迹列表),返回最小化信息:id、name、coverUrl、tags。最多500个ID。") - @GetMapping("/scenic/brief") - public Result>> getScenicBrief(@RequestParam @Size(max = 500) List ids) { - if (ids == null || ids.isEmpty()) { -@@ -94,7 +94,7 @@ public class InternalMpResourceBriefController { - return Result.success(result); - } - -- @ApiOperation("批量查询餐厅摘要") -+ @ApiOperation(value = "批量查询餐厅摘要", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用,返回最小化信息。最多500个ID。") - @GetMapping("/restaurant/brief") - public Result>> getRestaurantBrief(@RequestParam @Size(max = 500) List ids) { - if (ids == null || ids.isEmpty()) { -@@ -126,7 +126,7 @@ public class InternalMpResourceBriefController { - return Result.success(result); - } - -- @ApiOperation("批量查询活动摘要") -+ @ApiOperation(value = "批量查询活动摘要", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用,返回最小化信息。最多500个ID。") - @GetMapping("/activity/brief") - public Result>> getActivityBrief(@RequestParam @Size(max = 500) List ids) { - if (ids == null || ids.isEmpty()) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceController.java b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceController.java -index d4158a8..44cd22e 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceController.java -@@ -25,7 +25,7 @@ import org.springframework.web.bind.annotation.*; - *

- */ - @Slf4j --@Api(tags = "【内部接口】资源审批(Feign调用)") -+@Api(tags = "【内部接口】资源审批(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/resource") - @RequiredArgsConstructor -@@ -42,9 +42,9 @@ public class InternalResourceController { - private final StaffService staffService; - - /** 处理审批回调 - 分发到9个资源领域服务 */ -- @ApiOperation("处理审批回调 - 分发到9个资源领域服务") -+ @ApiOperation(value = "处理审批回调 - 分发到9个资源领域服务", notes = "【仅限内部Feign调用】接收企微审批回调结果,按thirdNo(审批单号)在9个资源领域中匹配并更新状态。每个领域服务内部通过approval_no匹配,未找到则忽略(幂等处理)。由hl-callback-service通过MQ消费后调用。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - - // 分发到9个领域服务 - 每个服务内部检查approval_no -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceDetailController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceDetailController.java b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceDetailController.java -index a6adb66..e726a14 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceDetailController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceDetailController.java -@@ -41,7 +41,7 @@ import java.util.stream.Collectors; - * 供产品服务的行程节点获取绑定资源的详细信息(含图片、地址等) - */ - @Slf4j --@Api(tags = "【内部接口】资源详情(Feign调用)") -+@Api(tags = "【内部接口】资源详情(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/resource") - @RequiredArgsConstructor -@@ -69,7 +69,7 @@ public class InternalResourceDetailController { - * @param activityIds 活动ID列表 - * @return resourceType:resourceId → ResourceDetailDTO - */ -- @ApiOperation("批量查询资源详情(行程节点用)") -+ @ApiOperation(value = "批量查询资源详情(行程节点用)", notes = "【仅限内部Feign调用】供产品服务获取行程节点绑定资源的详细信息。按类型分组查询,返回Map。包含封面、轮播图URL、地址、坐标、标签、富文本介绍等完整信息。\n\n**关联字典**:\n- city(城市,返回字段city)") - @GetMapping("/batch-details") - public Result> batchDetails( - @RequestParam(required = false) List scenicIds, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourcePriceController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourcePriceController.java b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourcePriceController.java -index 366168b..e1ddd03 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourcePriceController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourcePriceController.java -@@ -53,7 +53,7 @@ import java.util.stream.Collectors; - @RestController - @RequestMapping("/internal/resource/prices") - @RequiredArgsConstructor --@Api(tags = "【内部接口】资源价格(Feign调用)") -+@Api(tags = "【内部接口】资源价格(Feign调用)", hidden = true) - public class InternalResourcePriceController { - - private final ScenicPriceCalendarMapper scenicPriceMapper; -@@ -71,7 +71,7 @@ public class InternalResourcePriceController { - private final SuppliesItemMapper suppliesItemMapper; - private final SuppliesService suppliesService; - -- /** 查询景区价格 */ -+ /** 查询景区价格 - 按景区ID和日期范围查询价格日历的成本价 */ - @PostMapping("/scenic") - public Result> getScenicPrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -108,7 +108,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询酒店价格(按hotelId查最低房型价格) */ -+ /** 查询酒店价格 - 按hotelId查询日期范围内最低房型的成本价(取所有房型中最低价) */ - @PostMapping("/hotel") - public Result> getHotelPrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -143,7 +143,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询房型价格(按roomTypeId精确查询) */ -+ /** 查询房型价格 - 按roomTypeId精确查询日期范围内的成本价(取最低价) */ - @PostMapping("/room-type") - public Result> getRoomTypePrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -178,7 +178,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询活动价格 */ -+ /** 查询活动价格 - 按活动ID和日期范围查询价格日历的成本价 */ - @PostMapping("/activity") - public Result> getActivityPrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -214,7 +214,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询车辆价格 */ -+ /** 查询车辆价格 - 按车型ID和日期范围查询价格日历的成本价 */ - @PostMapping("/vehicle") - public Result> getVehiclePrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -250,7 +250,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询服务项价格 */ -+ /** 查询服务项价格 - 按服务项ID和日期范围查询价格日历的成本价 */ - @PostMapping("/service") - public Result> getServicePrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -283,13 +283,13 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询餐厅价格(餐厅无价格日历,返回空) */ -+ /** 查询餐厅价格 - 餐厅无独立价格日历,始终返回空列表(餐费通过费用项管理) */ - @PostMapping("/restaurant") - public Result> getRestaurantPrices(@RequestBody PriceQuery query) { - return Result.success(new ArrayList<>()); - } - -- /** 查询服务人员价格(按人员类型) */ -+ /** 查询服务人员价格 - 按staffType(人员类型)和日期范围查询价格日历的成本价(人员价格按类型而非个人) */ - @PostMapping("/staff") - public Result> getStaffPrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -321,7 +321,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询酒店下所有房型(简要信息) */ -+ /** 查询酒店下所有已启用房型 - 返回roomTypeId、name、maxOccupancy、basePrice,按sortOrder排序 */ - @GetMapping("/room-types-by-hotel/{hotelId}") - public Result> getRoomTypesByHotel(@PathVariable Long hotelId) { - List roomTypes = roomTypeMapper.selectList( -@@ -336,7 +336,7 @@ public class InternalResourcePriceController { - return Result.success(vos); - } - -- /** 查询所有可用车型(简要信息) */ -+ /** 查询所有已启用车型 - 返回vehicleId、name、seatCount、basePrice,按sortOrder排序,供产品服务车辆下拉选择使用 */ - @GetMapping("/vehicle-models") - public Result> getVehicleModels() { - List vehicles = vehicleModelMapper.selectList( -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceStatsController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceStatsController.java b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceStatsController.java -index 019a26f..3ef23db 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceStatsController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceStatsController.java -@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RestController; - import java.util.HashMap; - import java.util.Map; - --@Api(tags = "【内部接口】资源统计(Feign调用)") -+@Api(tags = "【内部接口】资源统计(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/resource") - @RequiredArgsConstructor -@@ -24,7 +24,7 @@ public class InternalResourceStatsController { - private final RoomTypeMapper roomTypeMapper; - private final VehicleModelMapper vehicleModelMapper; - -- @ApiOperation("获取酒店统计") -+ @ApiOperation(value = "获取酒店统计", notes = "【仅限内部Feign调用】返回酒店总数和房型总数,供管理后台仪表盘展示。") - @GetMapping("/hotel/stats") - public Result> getHotelStats() { - long totalHotels = hotelMapper.selectCount(null); -@@ -36,7 +36,7 @@ public class InternalResourceStatsController { - return Result.success(stats); - } - -- @ApiOperation("获取车辆统计") -+ @ApiOperation(value = "获取车辆统计", notes = "【仅限内部Feign调用】返回车型总数,供管理后台仪表盘展示。") - @GetMapping("/vehicle/stats") - public Result> getVehicleStats() { - long totalVehicles = vehicleModelMapper.selectCount(null); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostItemController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostItemController.java b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostItemController.java -index ce21f8c..b138078 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostItemController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostItemController.java -@@ -28,7 +28,7 @@ public class CostItemController { - - private final CostItemService costItemService; - -- @ApiOperation("创建费用项") -+ @ApiOperation(value = "创建费用项", notes = "新建费用项(如门票成本、餐费、保险费等),用于产品报价计算。费用项有独立的价格日历,价格变更会记录变更日志。创建后需走企微审批上架。\n\n**关联字典**:\n- cost_category:费用分类(表单选择)\n- cost_apply_role:适用角色(表单选择)\n- cost_unit:计量单位(表单选择)") - @PostMapping("/item") - public Result createCostItem(@ApiParam("费用项创建请求") @Valid @RequestBody CostItemCreateRequest request, - HttpServletRequest httpRequest) { -@@ -36,19 +36,19 @@ public class CostItemController { - return Result.success(costItemService.createCostItem(request, adminId)); - } - -- @ApiOperation("费用项列表") -+ @ApiOperation(value = "费用项列表", notes = "分页查询费用项列表,支持按名称、状态等条件筛选。\n\n**关联字典**:\n- cost_category:费用分类(筛选+列表显示)\n- cost_apply_role:适用角色(筛选+列表显示)\n- cost_unit:计量单位(列表显示)") - @GetMapping("/items") - public Result> listCostItems(@ApiParam("费用项查询请求") @Valid CostItemQueryRequest query) { - return Result.success(costItemService.listCostItems(query)); - } - -- @ApiOperation("费用项详情") -+ @ApiOperation(value = "费用项详情", notes = "获取费用项完整信息,包含当前价格、引用计数等。\n\n**关联字典**:\n- cost_category:费用分类(详情显示)\n- cost_apply_role:适用角色(详情显示)\n- cost_unit:计量单位(详情显示)") - @GetMapping("/item/{costId}") - public Result getCostItem(@ApiParam("费用项ID") @PathVariable Long costId) { - return Result.success(costItemService.getCostItem(costId)); - } - -- @ApiOperation("更新费用项") -+ @ApiOperation(value = "更新费用项", notes = "更新费用项信息。如果修改了价格,会自动记录价格变更日志。\n\n**关联字典**:\n- cost_category:费用分类(表单选择)\n- cost_apply_role:适用角色(表单选择)\n- cost_unit:计量单位(表单选择)") - @PutMapping("/item/{costId}") - public Result updateCostItem(@ApiParam("费用项ID") @PathVariable Long costId, - @ApiParam("费用项更新请求") @Valid @RequestBody CostItemUpdateRequest request, -@@ -57,7 +57,7 @@ public class CostItemController { - return Result.success(costItemService.updateCostItem(costId, request, adminId)); - } - -- @ApiOperation("删除费用项") -+ @ApiOperation(value = "删除费用项", notes = "软删除费用项。仅SUPER_ADMIN或创建者可操作。被产品引用(refCount>0)的费用项不建议删除。") - @DeleteMapping("/item/{costId}") - public Result deleteCostItem(@ApiParam("费用项ID") @PathVariable Long costId, HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -@@ -66,7 +66,7 @@ public class CostItemController { - return Result.success(); - } - -- @ApiOperation("提交审批") -+ @ApiOperation(value = "提交审批", notes = "向企微OA提交费用项启用/禁用审批。targetStatus=1申请上架,targetStatus=2申请下架。返回审批单号spNo。") - @PostMapping("/item/{costId}/submit-approval") - public Result> submitApproval(@ApiParam("费用项ID") @PathVariable Long costId, - @ApiParam("审批提交请求体") @Valid @RequestBody ApprovalSubmitRequest request, -@@ -76,13 +76,13 @@ public class CostItemController { - return Result.success(java.util.Map.of("spNo", spNo)); - } - -- @ApiOperation("启用的费用项列表") -+ @ApiOperation(value = "启用的费用项列表", notes = "查询所有已启用(status=1)的费用项,不分页。用于产品编排时选择费用项的下拉列表。\n\n**关联字典**:\n- cost_category:费用分类(列表显示)\n- cost_apply_role:适用角色(列表显示)\n- cost_unit:计量单位(列表显示)") - @GetMapping("/items/enabled") - public Result> listEnabledCostItems() { - return Result.success(costItemService.listEnabledCostItems()); - } - -- @ApiOperation("费用项价格变更记录") -+ @ApiOperation(value = "费用项价格变更记录", notes = "查询费用项的历史价格变更记录,按时间倒序排列。用于追溯价格调整历史。") - @GetMapping("/item/{costId}/price-logs") - public Result> getPriceLogs(@ApiParam("费用项ID") @PathVariable Long costId) { - return Result.success(costItemService.getPriceLogs(costId)); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostPriceCalendarController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostPriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostPriceCalendarController.java -index 862c1b2..95007f0 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostPriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostPriceCalendarController.java -@@ -26,7 +26,7 @@ public class CostPriceCalendarController { - - private final CostPriceCalendarService priceCalendarService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询费用项的每日价格。费用项价格日历用于产品报价计算时按日期获取成本价。") - @GetMapping("/item/{costId}/prices") - public Result getPriceCalendar(@ApiParam("费用项ID") @PathVariable Long costId, - @ApiParam("年份") @RequestParam @Min(2020) @Max(2100) Integer year, -@@ -34,7 +34,7 @@ public class CostPriceCalendarController { - return Result.success(priceCalendarService.getPriceCalendar(costId, year, month)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", notes = "在指定日期范围内批量设置费用项的成本价。") - @PutMapping("/item/{costId}/prices") - public Result batchSetPrices(@ApiParam("费用项ID") @PathVariable Long costId, - @ApiParam("价格日历设置请求") @Valid @RequestBody PriceCalendarSetRequest request) { -@@ -42,7 +42,7 @@ public class CostPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("清除价格日历") -+ @ApiOperation(value = "清除价格日历", notes = "删除指定日期范围内费用项的价格记录。日期格式:yyyy-MM-dd。") - @DeleteMapping("/item/{costId}/prices") - public Result deletePrices(@ApiParam("费用项ID") @PathVariable Long costId, - @ApiParam("开始日期") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/InternalCostController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/InternalCostController.java b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/InternalCostController.java -index 5e27f64..361c8de 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/InternalCostController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/InternalCostController.java -@@ -20,7 +20,7 @@ import java.util.Map; - - @Slf4j - @Validated --@Api(tags = "【内部接口】费用项(Feign调用)") -+@Api(tags = "【内部接口】费用项(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/cost") - @RequiredArgsConstructor -@@ -28,21 +28,21 @@ public class InternalCostController { - - private final CostItemService costItemService; - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配费用项并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - costItemService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); - } - -- @ApiOperation("批量获取费用项") -+ @ApiOperation(value = "批量获取费用项", notes = "【仅限内部Feign调用】批量获取费用项完整信息(含名称、分类、计费类型、基础价格等),最多500个ID。供产品服务批量查询产品关联的费用项。\n\n**关联字典**:\n- cost_unit(计费单位,返回字段unit):PER_PERSON=元/人, PER_VEHICLE=元/台, PER_DAY=元/天, PER_TIME=元/次, PER_ROOM=元/间, PER_TABLE=元/桌, FIXED=固定金额\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/items/batch") - public Result> batchGetCostItems(@RequestParam @Size(max = 500) List costIds) { - return Result.success(costItemService.batchGetCostItems(costIds)); - } - -- @ApiOperation("按日期获取费用项价格") -+ @ApiOperation(value = "按日期获取费用项价格", notes = "【仅限内部Feign调用】按指定日期批量查询费用项的成本价格。返回Map。优先取价格日历,无日历则取basePrice。供产品服务报价计算器使用。") - @GetMapping("/items/prices-by-date") - public Result> getByDatePrices( - @RequestParam @Size(max = 500) List costIds, -@@ -50,7 +50,7 @@ public class InternalCostController { - return Result.success(costItemService.getByDatePrices(costIds, date)); - } - -- @ApiOperation("更新引用计数") -+ @ApiOperation(value = "更新引用计数", notes = "【仅限内部Feign调用】更新费用项的引用计数。delta>0表示新增引用,delta<0表示减少引用。供产品服务在关联/取消关联费用项时调用,用于统计资源被使用次数。") - @PostMapping("/item/{costId}/ref-count") - public Result updateRefCount(@PathVariable Long costId, @RequestParam int delta) { - costItemService.updateRefCount(costId, delta); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelController.java -index 4a0c2c5..7faaef1 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelController.java -@@ -26,7 +26,7 @@ public class HotelController { - - private final HotelService hotelService; - -- @ApiOperation("创建住宿") -+ @ApiOperation(value = "创建住宿", notes = "新建住宿资源(酒店/民宿/营地等),初始状态为草稿(status=0)。创建后需通过「提交启用/禁用审批」走企微OA审批流程才能上架。住宿下可继续创建房型(RoomType),房型有独立的价格日历。\n\n**关联字典**:\n- hotel_type:住宿类型(表单选择)\n- hotel_star_level:酒店星级(表单选择)\n- hotel_facility:酒店设施(表单多选)") - @PostMapping("/item") - public Result createHotel( - @ApiParam("住宿创建请求") @Valid @RequestBody HotelCreateRequest request, -@@ -35,25 +35,25 @@ public class HotelController { - return Result.success(hotelService.createHotel(request, adminId)); - } - -- @ApiOperation("住宿列表") -+ @ApiOperation(value = "住宿列表", notes = "分页查询住宿列表,支持按名称关键词、状态、住宿类型等条件筛选。返回列表摘要信息,按sortOrder倒序+创建时间倒序排列。\n\n**关联字典**:\n- hotel_type:住宿类型(筛选+列表显示)\n- hotel_star_level:酒店星级(筛选+列表显示)\n- hotel_facility:酒店设施(列表显示)") - @GetMapping("/items") - public Result> listHotels(@ApiParam("住宿查询请求") @Valid HotelQueryRequest query) { - return Result.success(hotelService.listHotels(query)); - } - -- @ApiOperation("所有启用的住宿(不分页,仅ID和名称)") -+ @ApiOperation(value = "所有启用的住宿(不分页,仅ID和名称)", notes = "返回所有已上架(status=1)的住宿简要信息,用于下拉选择框。每项只含hotelId和name字段。适用于房型管理时选择所属住宿、产品编排时绑定住宿资源等场景。") - @GetMapping("/items/all-simple") - public Result>> listAllSimple() { - return Result.success(hotelService.listAllSimple()); - } - -- @ApiOperation("住宿详情") -+ @ApiOperation(value = "住宿详情", notes = "获取住宿完整信息,包含素材URL、标签列表、房型列表等。素材ID会自动解析为OSS访问地址。\n\n**关联字典**:\n- hotel_type:住宿类型(详情显示)\n- hotel_star_level:酒店星级(详情显示)\n- hotel_facility:酒店设施(详情显示)") - @GetMapping("/item/{hotelId}") - public Result getHotel(@ApiParam("住宿ID") @PathVariable Long hotelId) { - return Result.success(hotelService.getHotel(hotelId)); - } - -- @ApiOperation("更新住宿") -+ @ApiOperation(value = "更新住宿", notes = "更新住宿基本信息。更新不会改变当前状态,已上架的住宿修改后仍保持上架状态。\n\n**关联字典**:\n- hotel_type:住宿类型(表单选择)\n- hotel_star_level:酒店星级(表单选择)\n- hotel_facility:酒店设施(表单多选)") - @PutMapping("/item/{hotelId}") - public Result updateHotel( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -63,7 +63,7 @@ public class HotelController { - return Result.success(hotelService.updateHotel(hotelId, request, adminId)); - } - -- @ApiOperation("删除住宿") -+ @ApiOperation(value = "删除住宿", notes = "软删除住宿。仅SUPER_ADMIN或创建者可操作。删除住宿会同时删除其下所有房型和价格日历数据。") - @DeleteMapping("/item/{hotelId}") - public Result deleteHotel( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -74,7 +74,7 @@ public class HotelController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交住宿启用/禁用审批。targetStatus=1申请上架,targetStatus=2申请下架。审批通过后自动更新状态。返回企微审批单号spNo。") - @PostMapping("/item/{hotelId}/submit-approval") - public Result> submitApproval( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -86,7 +86,7 @@ public class HotelController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("启用/禁用切换") -+ @ApiOperation(value = "启用/禁用切换", notes = "直接修改住宿状态(跳过审批),仅限SUPER_ADMIN使用。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/item/{hotelId}/status") - public Result updateStatus( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -97,7 +97,7 @@ public class HotelController { - return Result.success(); - } - -- @ApiOperation("批量启用/禁用") -+ @ApiOperation(value = "批量启用/禁用", notes = "批量修改多个住宿的状态,跳过审批流程。hotelIds为住宿ID列表(字符串格式)。") - @PutMapping("/items/batch/status") - public Result batchUpdateStatus( - @ApiParam("住宿状态请求") @Valid @RequestBody HotelStatusRequest request, -@@ -109,7 +109,7 @@ public class HotelController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个住宿及其关联的房型和价格日历。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/items/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelTagController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelTagController.java -index 3b229f8..02e8708 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelTagController.java -@@ -27,7 +27,7 @@ public class HotelTagController { - - private final HotelTagService tagService; - -- @ApiOperation("预设标签列表(分页)") -+ @ApiOperation(value = "预设标签列表(分页)", notes = "分页查询住宿标签库,支持按关键词搜索。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class HotelTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("所有标签列表") -+ @ApiOperation(value = "所有标签列表", notes = "不分页返回所有标签,用于住宿编辑时的标签选择。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建标签") -+ @ApiOperation(value = "创建标签", notes = "创建预设标签,标签名不可重复。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class HotelTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("查找或创建自定义标签") -+ @ApiOperation(value = "查找或创建自定义标签", notes = "按名称查找标签,不存在则自动创建。用于住宿编辑时快速输入新标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class HotelTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("更新标签") -+ @ApiOperation(value = "更新标签", notes = "修改标签名称或颜色,所有关联住宿自动生效。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class HotelTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并解除所有住宿与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("设置住宿标签") -+ @ApiOperation(value = "设置住宿标签", notes = "全量替换指定住宿的标签列表。") - @PutMapping("/item/{hotelId}/tags") - public Result updateHotelTags( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -87,7 +87,7 @@ public class HotelTagController { - return Result.success(); - } - -- @ApiOperation("批量添加/移除标签") -+ @ApiOperation(value = "批量添加/移除标签", notes = "对多个住宿批量添加/移除标签。增量操作,不影响未指定的标签。") - @PutMapping("/items/batch/tags") - public Result batchUpdateTags(@ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { - List hotelIds = request.getHotelIds().stream() -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalHotelController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalHotelController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalHotelController.java -index c758f6e..4b81939 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalHotelController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalHotelController.java -@@ -18,7 +18,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】住宿(Feign调用)") -+@Api(tags = "【内部接口】住宿(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/hotel") - @RequiredArgsConstructor -@@ -27,7 +27,7 @@ public class InternalHotelController { - private final HotelService hotelService; - private final RoomTypeService roomTypeService; - -- @ApiOperation("获取住宿简要信息") -+ @ApiOperation(value = "获取住宿简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个住宿的简要信息,返回ID、名称、住宿类型、状态。不存在时返回错误。\n\n**关联字典**:\n- hotel_type(住宿类型,返回字段hotelType):HOTEL=酒店, GUESTHOUSE=民宿, RESORT=度假村, CAMP=营地, HOMESTAY=农家院\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/item/{hotelId}") - public Result> getHotelBrief(@PathVariable Long hotelId) { - Hotel item = hotelService.getHotelEntity(hotelId); -@@ -42,7 +42,7 @@ public class InternalHotelController { - return Result.success(brief); - } - -- @ApiOperation("批量获取住宿简要信息") -+ @ApiOperation(value = "批量获取住宿简要信息", notes = "【仅限内部Feign调用】批量获取住宿简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询行程节点绑定的住宿资源。\n\n**关联字典**:\n- hotel_type(住宿类型,返回字段hotelType):HOTEL=酒店, GUESTHOUSE=民宿, RESORT=度假村, CAMP=营地, HOMESTAY=农家院\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/items/batch") - public Result>> getHotelBatch(@RequestParam @Size(max = 500) List hotelIds) { - List> results = hotelIds.stream() -@@ -61,9 +61,9 @@ public class InternalHotelController { - return Result.success(results); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配住宿和房型并更新启用/禁用状态。住宿和房型共享同一审批模板,此接口同时尝试匹配两者。由hl-callback-service通过MQ消费后调用。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - hotelService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - // Also try room type (same template, same callback) -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalMpHotelController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalMpHotelController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalMpHotelController.java -index ce4fd47..2a820f5 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalMpHotelController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalMpHotelController.java -@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.*; - /** - * C端住宿内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - */ --@Api(tags = "【内部接口】小程序酒店(Feign调用)") -+@Api(tags = "【内部接口】小程序酒店(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/hotel") - @RequiredArgsConstructor -@@ -22,7 +22,7 @@ public class InternalMpHotelController { - - private final HotelService hotelService; - -- @ApiOperation("C端住宿列表") -+ @ApiOperation(value = "C端住宿列表", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用。强制status=1只返回已上架住宿,支持分页和筛选。C端用户通过小程序间接访问。\n\n**关联字典**:\n- hotel_type(住宿类型,返回字段hotelType):HOTEL=酒店, GUESTHOUSE=民宿, RESORT=度假村, CAMP=营地, HOMESTAY=农家院\n- hotel_star(星级,返回字段starLevel):FIVE=五星, FOUR=四星, THREE=三星, UNRATED=未评级") - @GetMapping("/list") - public Result> listHotels(HotelQueryRequest query) { - // Force status=1 for C-side (only show published hotels) -@@ -30,7 +30,7 @@ public class InternalMpHotelController { - return Result.success(hotelService.listHotels(query)); - } - -- @ApiOperation("C端住宿详情") -+ @ApiOperation(value = "C端住宿详情", notes = "【仅限内部Feign调用】供mp-service获取住宿完整详情,包含房型列表、封面、轮播图、地址等。注意:不限制status,由BFF层校验是否展示。\n\n**关联字典**:\n- hotel_type(住宿类型,返回字段hotelType):HOTEL=酒店, GUESTHOUSE=民宿, RESORT=度假村, CAMP=营地, HOMESTAY=农家院\n- hotel_star(星级,返回字段starLevel):FIVE=五星, FOUR=四星, THREE=三星, UNRATED=未评级") - @GetMapping("/{hotelId}") - public Result getHotelDetail(@PathVariable Long hotelId) { - HotelVO vo = hotelService.getHotel(hotelId); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomPriceCalendarController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomPriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomPriceCalendarController.java -index cf6df6c..d883d85 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomPriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomPriceCalendarController.java -@@ -25,7 +25,7 @@ public class RoomPriceCalendarController { - - private final RoomPriceCalendarService priceCalendarService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询房型的每日价格和可售状态。每个房型有独立的价格日历。") - @GetMapping("/room-type/{roomTypeId}/prices") - public Result getPriceCalendar( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -@@ -34,7 +34,7 @@ public class RoomPriceCalendarController { - return Result.success(priceCalendarService.getPriceCalendar(roomTypeId, year, month)); - } - -- @ApiOperation("批量设置价格日历") -+ @ApiOperation(value = "批量设置价格日历", notes = "在指定日期范围内批量设置房型的成本价和可售状态。支持按星期过滤和排除特定日期。") - @PutMapping("/room-type/{roomTypeId}/prices") - public Result batchSetPrices( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -@@ -43,7 +43,7 @@ public class RoomPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改日期可售状态") -+ @ApiOperation(value = "批量修改日期可售状态", notes = "批量修改指定日期范围内房型的可售状态,不影响价格。") - @PutMapping("/room-type/{roomTypeId}/prices/batch-status") - public Result batchUpdateStatus( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -@@ -52,7 +52,7 @@ public class RoomPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("删除价格日历") -+ @ApiOperation(value = "删除价格日历", notes = "删除指定日期范围内房型的所有价格记录。日期格式:yyyy-MM-dd。") - @DeleteMapping("/room-type/{roomTypeId}/prices") - public Result deletePrices( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomTypeController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomTypeController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomTypeController.java -index 2048f4c..0d9cf42 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomTypeController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomTypeController.java -@@ -26,7 +26,7 @@ public class RoomTypeController { - - private final RoomTypeService roomTypeService; - -- @ApiOperation("创建房型") -+ @ApiOperation(value = "创建房型", notes = "在指定住宿下创建房型(如标准间、大床房、套房等)。每个房型有独立的价格日历、最大入住人数(maxOccupancy)和基础价格(basePrice)。房型初始状态为草稿(status=0),需独立审批后才能启用。创建后可通过「提交房型启用审批」接口提交企微OA审批。\n\n**关联字典**:\n- room_category:房型分类(表单选择)\n- bed_type:床型(表单选择)\n- window_type:窗户类型(表单选择)\n- bathroom_type:卫浴类型(表单选择)\n- room_facility:房间设施(表单多选)") - @PostMapping("/{hotelId}/room-type") - public Result createRoomType( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -36,19 +36,19 @@ public class RoomTypeController { - return Result.success(roomTypeService.createRoomType(hotelId, request, adminId)); - } - -- @ApiOperation("房型列表") -+ @ApiOperation(value = "房型列表", notes = "获取指定住宿下的所有房型列表(不分页),按sortOrder排序。\n\n**关联字典**:\n- room_category:房型分类(列表/详情显示)\n- bed_type:床型(列表/详情显示)\n- window_type:窗户类型(列表/详情显示)\n- bathroom_type:卫浴类型(列表/详情显示)\n- room_facility:房间设施(列表/详情显示)") - @GetMapping("/{hotelId}/room-types") - public Result> listRoomTypes(@ApiParam("住宿ID") @PathVariable Long hotelId) { - return Result.success(roomTypeService.listRoomTypes(hotelId)); - } - -- @ApiOperation("房型详情") -+ @ApiOperation(value = "房型详情", notes = "获取房型完整信息,包含价格、入住人数、素材等。\n\n**关联字典**:\n- room_category:房型分类(列表/详情显示)\n- bed_type:床型(列表/详情显示)\n- window_type:窗户类型(列表/详情显示)\n- bathroom_type:卫浴类型(列表/详情显示)\n- room_facility:房间设施(列表/详情显示)") - @GetMapping("/room-type/{roomTypeId}") - public Result getRoomType(@ApiParam("房型ID") @PathVariable Long roomTypeId) { - return Result.success(roomTypeService.getRoomType(roomTypeId)); - } - -- @ApiOperation("更新房型") -+ @ApiOperation(value = "更新房型", notes = "更新房型基本信息,不改变当前状态。\n\n**关联字典**:\n- room_category:房型分类(表单选择)\n- bed_type:床型(表单选择)\n- window_type:窗户类型(表单选择)\n- bathroom_type:卫浴类型(表单选择)\n- room_facility:房间设施(表单多选)") - @PutMapping("/room-type/{roomTypeId}") - public Result updateRoomType( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -@@ -58,14 +58,14 @@ public class RoomTypeController { - return Result.success(roomTypeService.updateRoomType(roomTypeId, request, adminId)); - } - -- @ApiOperation("删除房型") -+ @ApiOperation(value = "删除房型", notes = "软删除房型及其价格日历数据。") - @DeleteMapping("/room-type/{roomTypeId}") - public Result deleteRoomType(@ApiParam("房型ID") @PathVariable Long roomTypeId) { - roomTypeService.deleteRoomType(roomTypeId); - return Result.success(); - } - -- @ApiOperation("启用/禁用房型") -+ @ApiOperation(value = "启用/禁用房型", notes = "直接修改房型状态(跳过审批)。status=0禁用,status=1启用。禁用后该房型不会出现在C端展示中。") - @PutMapping("/room-type/{roomTypeId}/status") - public Result updateRoomTypeStatus( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -@@ -74,7 +74,7 @@ public class RoomTypeController { - return Result.success(); - } - -- @ApiOperation("提交房型启用/禁用审批") -+ @ApiOperation(value = "提交房型启用/禁用审批", notes = "向企微OA提交房型启用/禁用审批。审批流程与住宿共享同一模板。返回审批单号spNo。") - @PostMapping("/room-type/{roomTypeId}/submit-approval") - public Result> submitRoomTypeApproval( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalMpRestaurantController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalMpRestaurantController.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalMpRestaurantController.java -index 41d485f..df17f5c 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalMpRestaurantController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalMpRestaurantController.java -@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.*; - /** - * C端餐厅内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - */ --@Api(tags = "【内部接口】小程序餐厅(Feign调用)") -+@Api(tags = "【内部接口】小程序餐厅(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/restaurant") - @RequiredArgsConstructor -@@ -22,7 +22,7 @@ public class InternalMpRestaurantController { - - private final RestaurantService restaurantService; - -- @ApiOperation("C端餐厅列表") -+ @ApiOperation(value = "C端餐厅列表", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用。强制status=1只返回已上架餐厅,支持分页和筛选。C端用户通过小程序间接访问。\n\n**关联字典**:\n- restaurant_category(餐厅分类,返回字段categoryCode):CHINESE=中餐, WESTERN=西餐, BBQ=烧烤, HOTPOT=火锅, LOCAL=当地特色") - @GetMapping("/list") - public Result> listRestaurants(RestaurantQueryRequest query) { - // Force status=1 for C-side (only show published restaurants) -@@ -30,7 +30,7 @@ public class InternalMpRestaurantController { - return Result.success(restaurantService.listRestaurants(query)); - } - -- @ApiOperation("C端餐厅详情") -+ @ApiOperation(value = "C端餐厅详情", notes = "【仅限内部Feign调用】供mp-service获取餐厅完整详情,包含封面、轮播图、标签、地址、富文本介绍等。注意:不限制status,由BFF层校验是否展示。\n\n**关联字典**:\n- restaurant_category(餐厅分类,返回字段categoryCode):CHINESE=中餐, WESTERN=西餐, BBQ=烧烤, HOTPOT=火锅, LOCAL=当地特色") - @GetMapping("/{restaurantId}") - public Result getRestaurantDetail(@PathVariable Long restaurantId) { - RestaurantVO vo = restaurantService.getRestaurant(restaurantId); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalRestaurantController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalRestaurantController.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalRestaurantController.java -index ac8e4db..a87aaea 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalRestaurantController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalRestaurantController.java -@@ -17,7 +17,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】餐厅(Feign调用)") -+@Api(tags = "【内部接口】餐厅(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/restaurant") - @RequiredArgsConstructor -@@ -25,7 +25,7 @@ public class InternalRestaurantController { - - private final RestaurantService restaurantService; - -- @ApiOperation("\u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f") -+ @ApiOperation(value = "\u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f", notes = "\u3010\u4ec5\u9650\u5185\u90e8Feign\u8c03\u7528\u3011\u4f9b\u4ea7\u54c1\u670d\u52a1\u83b7\u53d6\u5355\u4e2a\u9910\u5385\u7684\u7b80\u8981\u4fe1\u606f\uff0c\u8fd4\u56deID\u3001\u540d\u79f0\u3001\u5206\u7c7b\u7f16\u7801\u3001\u57ce\u5e02\u3001\u72b6\u6001\u3002\u4e0d\u5b58\u5728\u65f6\u8fd4\u56de\u9519\u8bef\u3002\n\n**\u5173\u8054\u5b57\u5178**\uff1a\n- restaurant_category\uff08\u9910\u5385\u5206\u7c7b\uff0c\u8fd4\u56de\u5b57\u6bb5categoryCode\uff09\uff1aCHINESE=\u4e2d\u9910, WESTERN=\u897f\u9910, BBQ=\u70e7\u70e4, HOTPOT=\u706b\u9505, LOCAL=\u5f53\u5730\u7279\u8272\n- common_status\uff08\u72b6\u6001\uff0c\u8fd4\u56de\u5b57\u6bb5status\uff09\uff1aACTIVE=\u542f\u7528, INACTIVE=\u505c\u7528") - @GetMapping("/item/{restaurantId}") - public Result> getRestaurantBrief(@PathVariable Long restaurantId) { - Restaurant restaurant = restaurantService.getRestaurantEntity(restaurantId); -@@ -41,7 +41,7 @@ public class InternalRestaurantController { - return Result.success(brief); - } - -- @ApiOperation("\u6279\u91cf\u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f") -+ @ApiOperation(value = "\u6279\u91cf\u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f", notes = "\u3010\u4ec5\u9650\u5185\u90e8Feign\u8c03\u7528\u3011\u6279\u91cf\u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f\uff0c\u6700\u591a500\u4e2aID\u3002\u4e0d\u5b58\u5728\u7684ID\u81ea\u52a8\u8fc7\u6ee4\u3002\u4f9b\u4ea7\u54c1\u670d\u52a1\u6279\u91cf\u67e5\u8be2\u884c\u7a0b\u8282\u70b9\u7ed1\u5b9a\u7684\u9910\u5385\u8d44\u6e90\u3002\n\n**\u5173\u8054\u5b57\u5178**\uff1a\n- restaurant_category\uff08\u9910\u5385\u5206\u7c7b\uff0c\u8fd4\u56de\u5b57\u6bb5categoryCode\uff09\uff1aCHINESE=\u4e2d\u9910, WESTERN=\u897f\u9910, BBQ=\u70e7\u70e4, HOTPOT=\u706b\u9505, LOCAL=\u5f53\u5730\u7279\u8272\n- common_status\uff08\u72b6\u6001\uff0c\u8fd4\u56de\u5b57\u6bb5status\uff09\uff1aACTIVE=\u542f\u7528, INACTIVE=\u505c\u7528") - @GetMapping("/items/batch") - public Result>> getRestaurantsBatch(@RequestParam @Size(max = 500) List restaurantIds) { - List> results = restaurantIds.stream() -@@ -61,9 +61,9 @@ public class InternalRestaurantController { - return Result.success(results); - } - -- @ApiOperation("\u5904\u7406\u5ba1\u6279\u56de\u8c03\u7ed3\u679c") -+ @ApiOperation(value = "\u5904\u7406\u5ba1\u6279\u56de\u8c03\u7ed3\u679c", notes = "\u3010\u4ec5\u9650\u5185\u90e8Feign\u8c03\u7528\u3011\u63a5\u6536\u4f01\u5faeOA\u5ba1\u6279\u56de\u8c03\uff0c\u6309thirdNo\u5339\u914d\u9910\u5385\u5e76\u66f4\u65b0\u542f\u7528/\u7981\u7528\u72b6\u6001\u3002\u7531hl-callback-service\u901a\u8fc7MQ\u6d88\u8d39\u540e\u8c03\u7528\uff0c\u5e42\u7b49\u5904\u7406\u3002\n\n**\u5173\u8054\u5b57\u5178**\uff1a\n- approval_sp_status\uff08\u5ba1\u6279\u72b6\u6001\uff0c\u8bf7\u6c42\u5b57\u6bb5spStatus\uff09") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - restaurantService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantController.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantController.java -index eb8164c..7c8961f 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantController.java -@@ -26,7 +26,7 @@ public class RestaurantController { - - private final RestaurantService restaurantService; - -- @ApiOperation("创建餐厅") -+ @ApiOperation(value = "创建餐厅", notes = "新建餐厅资源,初始状态为草稿(status=0)。餐厅没有价格日历,费用通过产品报价中的费用项管理。需走企微审批流程上架。\n\n**关联字典**:\n- restaurant_category:餐厅分类(表单选择)\n- cuisine_type:菜系类型(表单多选)\n- environment_type:环境类型(表单多选)\n- restaurant_facility:餐厅设施(表单多选)\n\n**纯文本字段**:\n- cityName:城市名称(手动输入,如「拉萨」「海拉尔」)") - @PostMapping("/item") - public Result createRestaurant( - @ApiParam("餐厅创建请求") @Valid @RequestBody RestaurantCreateRequest request, -@@ -35,19 +35,19 @@ public class RestaurantController { - return Result.success(restaurantService.createRestaurant(request, adminId)); - } - -- @ApiOperation("餐厅列表") -+ @ApiOperation(value = "餐厅列表", notes = "分页查询餐厅列表,支持按名称、状态、分类、城市等条件筛选。\n\n**关联字典**:\n- restaurant_category:餐厅分类(筛选+列表显示)\n- cuisine_type:菜系类型(列表显示)\n- environment_type:环境类型(列表显示)\n- restaurant_facility:餐厅设施(列表显示)") - @GetMapping("/items") - public Result> listRestaurants(@ApiParam("餐厅查询请求") @Valid RestaurantQueryRequest query) { - return Result.success(restaurantService.listRestaurants(query)); - } - -- @ApiOperation("餐厅详情") -+ @ApiOperation(value = "餐厅详情", notes = "获取餐厅完整信息,包含素材URL、标签、富文本介绍等。\n\n**关联字典**:\n- restaurant_category:餐厅分类(详情显示)\n- cuisine_type:菜系类型(详情显示)\n- environment_type:环境类型(详情显示)\n- restaurant_facility:餐厅设施(详情显示)") - @GetMapping("/item/{restaurantId}") - public Result getRestaurant(@ApiParam("餐厅ID") @PathVariable Long restaurantId) { - return Result.success(restaurantService.getRestaurant(restaurantId)); - } - -- @ApiOperation("更新餐厅") -+ @ApiOperation(value = "更新餐厅", notes = "更新餐厅基本信息,不改变当前状态。\n\n**关联字典**:\n- restaurant_category:餐厅分类(表单选择)\n- cuisine_type:菜系类型(表单多选)\n- environment_type:环境类型(表单多选)\n- restaurant_facility:餐厅设施(表单多选)\n\n**纯文本字段**:\n- cityName:城市名称(手动输入)") - @PutMapping("/item/{restaurantId}") - public Result updateRestaurant( - @ApiParam("餐厅ID") @PathVariable Long restaurantId, -@@ -57,7 +57,7 @@ public class RestaurantController { - return Result.success(restaurantService.updateRestaurant(restaurantId, request, adminId)); - } - -- @ApiOperation("删除餐厅") -+ @ApiOperation(value = "删除餐厅", notes = "软删除餐厅。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/item/{restaurantId}") - public Result deleteRestaurant( - @ApiParam("餐厅ID") @PathVariable Long restaurantId, -@@ -68,7 +68,7 @@ public class RestaurantController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交审批。targetStatus=1申请上架,targetStatus=2申请下架。返回审批单号spNo。") - @PostMapping("/item/{restaurantId}/submit-approval") - public Result> submitApproval( - @ApiParam("餐厅ID") @PathVariable Long restaurantId, -@@ -80,7 +80,7 @@ public class RestaurantController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("上下架切换") -+ @ApiOperation(value = "上下架切换", notes = "直接修改状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/item/{restaurantId}/status") - public Result updateStatus( - @ApiParam("餐厅ID") @PathVariable Long restaurantId, -@@ -91,7 +91,7 @@ public class RestaurantController { - return Result.success(); - } - -- @ApiOperation("批量上下架") -+ @ApiOperation(value = "批量上下架", notes = "批量修改多个餐厅的状态,跳过审批流程。") - @PutMapping("/items/batch/status") - public Result batchUpdateStatus( - @ApiParam("餐厅状态请求") @Valid @RequestBody RestaurantStatusRequest request, -@@ -103,7 +103,7 @@ public class RestaurantController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个餐厅。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/items/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantTagController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantTagController.java -index 05b1056..7f96d5a 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantTagController.java -@@ -27,7 +27,7 @@ public class RestaurantTagController { - - private final RestaurantTagService tagService; - -- @ApiOperation("\u83b7\u53d6\u7ba1\u7406\u6807\u7b7e\u5217\u8868\uff08\u5206\u9875\uff09") -+ @ApiOperation(value = "\u83b7\u53d6\u7ba1\u7406\u6807\u7b7e\u5217\u8868\uff08\u5206\u9875\uff09", notes = "\u5206\u9875\u67e5\u8be2\u9910\u5385\u6807\u7b7e\u5e93\uff0c\u652f\u6301\u6309\u5173\u952e\u8bcd\u641c\u7d22\u3002\u5305\u542b\u9884\u8bbe\u6807\u7b7e\u548c\u81ea\u5b9a\u4e49\u6807\u7b7e\u3002") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("\u9875\u7801") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class RestaurantTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("\u83b7\u53d6\u5168\u90e8\u6807\u7b7e") -+ @ApiOperation(value = "\u83b7\u53d6\u5168\u90e8\u6807\u7b7e", notes = "\u4e0d\u5206\u9875\u8fd4\u56de\u6240\u6709\u6807\u7b7e\uff0c\u7528\u4e8e\u9910\u5385\u7f16\u8f91\u65f6\u7684\u6807\u7b7e\u9009\u62e9\u4e0b\u62c9\u3002") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("\u521b\u5efa\u7ba1\u7406\u6807\u7b7e") -+ @ApiOperation(value = "\u521b\u5efa\u7ba1\u7406\u6807\u7b7e", notes = "\u521b\u5efa\u9884\u8bbe\u6807\u7b7e\uff0c\u6807\u7b7e\u540d\u4e0d\u53ef\u91cd\u590d\u3002\u53ef\u6307\u5b9a\u989c\u8272(tagColor)\uff0c\u9ed8\u8ba4#409EFF\u3002") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class RestaurantTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("\u89e3\u6790\u81ea\u5b9a\u4e49\u6807\u7b7e") -+ @ApiOperation(value = "\u89e3\u6790\u81ea\u5b9a\u4e49\u6807\u7b7e", notes = "\u6309\u540d\u79f0\u67e5\u627e\u6216\u81ea\u52a8\u521b\u5efa\u6807\u7b7e\u3002\u7528\u4e8e\u9910\u5385\u7f16\u8f91\u65f6\u5feb\u901f\u8f93\u5165\u65b0\u6807\u7b7e\u3002") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class RestaurantTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("\u7f16\u8f91\u6807\u7b7e") -+ @ApiOperation(value = "\u7f16\u8f91\u6807\u7b7e", notes = "\u4fee\u6539\u6807\u7b7e\u540d\u79f0\u6216\u989c\u8272\uff0c\u6240\u6709\u5173\u8054\u9910\u5385\u81ea\u52a8\u751f\u6548\u3002") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class RestaurantTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("\u5220\u9664\u6807\u7b7e") -+ @ApiOperation(value = "\u5220\u9664\u6807\u7b7e", notes = "\u5220\u9664\u6807\u7b7e\u5e76\u89e3\u9664\u6240\u6709\u9910\u5385\u4e0e\u8be5\u6807\u7b7e\u7684\u5173\u8054\u3002") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("\u66f4\u65b0\u9910\u5385\u6807\u7b7e") -+ @ApiOperation(value = "\u66f4\u65b0\u9910\u5385\u6807\u7b7e", notes = "\u5168\u91cf\u66ff\u6362\u6307\u5b9a\u9910\u5385\u7684\u6807\u7b7e\u5217\u8868\u3002\u4f20\u5165tagIds\u4e3a\u6700\u7ec8\u5173\u8054\u7684\u6807\u7b7eID\u5217\u8868\uff0c\u4e3a\u7a7a\u5219\u6e05\u9664\u6240\u6709\u6807\u7b7e\u3002") - @PutMapping("/item/{restaurantId}/tags") - public Result updateRestaurantTags( - @ApiParam("餐厅ID") @PathVariable Long restaurantId, -@@ -87,7 +87,7 @@ public class RestaurantTagController { - return Result.success(); - } - -- @ApiOperation("\u6279\u91cf\u6253\u6807\u7b7e") -+ @ApiOperation(value = "\u6279\u91cf\u6253\u6807\u7b7e", notes = "\u5bf9\u591a\u4e2a\u9910\u5385\u6279\u91cf\u6dfb\u52a0/\u79fb\u9664\u6807\u7b7e\u3002\u589e\u91cf\u64cd\u4f5c\uff0c\u4e0d\u5f71\u54cd\u672a\u6307\u5b9a\u7684\u6807\u7b7e\u3002") - @PutMapping("/items/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalMpScenicController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalMpScenicController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalMpScenicController.java -index dbe9f19..a28ef38 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalMpScenicController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalMpScenicController.java -@@ -17,7 +17,7 @@ import java.util.List; - /** - * C端景区内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - */ --@Api(tags = "【内部接口】小程序景区(Feign调用)") -+@Api(tags = "【内部接口】小程序景区(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/scenic") - @RequiredArgsConstructor -@@ -25,21 +25,21 @@ public class InternalMpScenicController { - - private final ScenicSpotService scenicSpotService; - -- @ApiOperation("C端景区列表") -+ @ApiOperation(value = "C端景区列表", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用。强制status=1只返回已上架景区,支持分页、城市筛选和关键词搜索。C端用户通过小程序间接访问。\n\ncityName为纯文本筛选字段,非字典。") - @GetMapping("/list") - public Result> listScenic(ScenicSpotQueryRequest query) { - query.setStatus(1); - return Result.success(scenicSpotService.listSpots(query)); - } - -- @ApiOperation("C端景区详情") -+ @ApiOperation(value = "C端景区详情", notes = "【仅限内部Feign调用】供mp-service获取景区完整详情,包含封面、轮播图、标签、季节内容、富文本介绍、坐标等。注意:不限制status,由BFF层校验是否展示。") - @GetMapping("/{scenicId}") - public Result getScenicDetail(@PathVariable Long scenicId) { - ScenicSpotVO vo = scenicSpotService.getSpot(scenicId); - return Result.success(vo); - } - -- @ApiOperation("C端附近景区") -+ @ApiOperation(value = "C端附近景区", notes = "【仅限内部Feign调用】根据指定景区的坐标查询附近的景区列表。radius为搜索半径(km,默认50),limit为最大返回数(默认10)。按距离排序,返回名称、封面、距离等信息。") - @GetMapping("/{scenicId}/nearby") - public Result> getNearbyScenic( - @PathVariable Long scenicId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalScenicController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalScenicController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalScenicController.java -index a902ee1..9f47695 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalScenicController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalScenicController.java -@@ -22,7 +22,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】景区(Feign调用)") -+@Api(tags = "【内部接口】景区(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/scenic") - @RequiredArgsConstructor -@@ -31,7 +31,7 @@ public class InternalScenicController { - private final ScenicSpotService spotService; - private final ScenicPriceCalendarService priceService; - -- @ApiOperation("获取景区简要信息") -+ @ApiOperation(value = "获取景区简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个景区的简要信息,返回ID、名称、荣誉称号、城市、状态。不存在时返回错误。\n\n**关联字典**:\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/spot/{scenicId}") - public Result> getSpotBrief(@PathVariable Long scenicId) { - ScenicSpot spot = spotService.getSpotEntity(scenicId); -@@ -47,7 +47,7 @@ public class InternalScenicController { - return Result.success(brief); - } - -- @ApiOperation("批量获取景区简要信息") -+ @ApiOperation(value = "批量获取景区简要信息", notes = "【仅限内部Feign调用】批量获取景区简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询行程节点绑定的景区资源。\n\n**关联字典**:\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/spots/batch") - public Result>> getSpotsBatch(@RequestParam @Size(max = 500) List scenicIds) { - List> results = scenicIds.stream() -@@ -67,7 +67,7 @@ public class InternalScenicController { - return Result.success(results); - } - -- @ApiOperation("查询某日价格") -+ @ApiOperation(value = "查询某日价格", notes = "【仅限内部Feign调用】查询景区指定日期的价格日历信息,包含成本价、售价、库存、状态。date格式为yyyy-MM-dd。供产品服务报价计算和库存校验使用。") - @GetMapping("/spot/{scenicId}/price/{date}") - public Result getPriceForDate( - @PathVariable Long scenicId, -@@ -76,7 +76,7 @@ public class InternalScenicController { - return Result.success(price); - } - -- @ApiOperation("判断某日是否可售") -+ @ApiOperation(value = "判断某日是否可售", notes = "【仅限内部Feign调用】判断景区指定日期是否可售(价格日历存在且状态为启用且库存>0)。供订单服务下单前校验使用。") - @GetMapping("/spot/{scenicId}/available/{date}") - public Result isAvailable( - @PathVariable Long scenicId, -@@ -84,7 +84,7 @@ public class InternalScenicController { - return Result.success(priceService.isAvailable(scenicId, LocalDate.parse(date))); - } - -- @ApiOperation("扣减库存") -+ @ApiOperation(value = "扣减库存", notes = "【仅限内部Feign调用】扣减景区指定日期的库存数量。下单成功时由订单服务调用。库存不足时返回false。使用乐观锁防止超卖。") - @PutMapping("/spot/{scenicId}/stock/deduct") - public Result deductStock( - @PathVariable Long scenicId, -@@ -94,7 +94,7 @@ public class InternalScenicController { - return Result.success(success); - } - -- @ApiOperation("恢复库存") -+ @ApiOperation(value = "恢复库存", notes = "【仅限内部Feign调用】恢复景区指定日期的库存数量。订单取消或退款时由订单服务调用,将之前扣减的库存加回。") - @PutMapping("/spot/{scenicId}/stock/restore") - public Result restoreStock( - @PathVariable Long scenicId, -@@ -104,9 +104,9 @@ public class InternalScenicController { - return Result.success(); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配景区并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - spotService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicPriceCalendarController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicPriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicPriceCalendarController.java -index 8e2b1cb..62d7de0 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicPriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicPriceCalendarController.java -@@ -25,7 +25,7 @@ public class ScenicPriceCalendarController { - - private final ScenicPriceCalendarService priceService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询景区的每日价格和可售状态。返回指定年月中所有已设置价格的日期,未设置的日期不返回。用于前端日历组件渲染。") - @GetMapping("/spot/{scenicId}/prices") - public Result getPriceCalendar( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -34,7 +34,7 @@ public class ScenicPriceCalendarController { - return Result.success(priceService.getPriceCalendar(scenicId, year, month)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", notes = "在指定日期范围内批量设置成本价、库存和可售状态。支持weekdayOnly/weekendOnly/selectedWeekdays过滤特定星期,支持excludeDates排除特定日期。已有价格的日期会被覆盖更新。") - @PutMapping("/spot/{scenicId}/prices") - public Result batchSetPrices( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -43,7 +43,7 @@ public class ScenicPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改可售状态") -+ @ApiOperation(value = "批量修改可售状态", notes = "批量修改指定日期范围内的可售状态,不影响价格和库存。status=0不可售,status=1可售。用于临时关闭/开放某些日期的售卖。") - @PutMapping("/spot/{scenicId}/prices/status") - public Result batchUpdateStatus( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -52,7 +52,7 @@ public class ScenicPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量清除价格") -+ @ApiOperation(value = "批量清除价格", notes = "删除指定日期范围内的所有价格记录。删除后该日期范围将显示为未设置状态。日期格式:yyyy-MM-dd。") - @DeleteMapping("/spot/{scenicId}/prices") - public Result deletePrices( - @ApiParam("景区ID") @PathVariable Long scenicId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSeasonController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSeasonController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSeasonController.java -index 8933ec2..ab7ad78 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSeasonController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSeasonController.java -@@ -22,13 +22,13 @@ public class ScenicSeasonController { - - private final ScenicSeasonService seasonService; - -- @ApiOperation("获取景区全部季节内容") -+ @ApiOperation(value = "获取景区全部季节内容", notes = "返回景区的所有季节内容列表(春/夏/秋/冬)。季节内容是景区独有功能,其他资源类型没有此概念。每个季节可设置独立的封面、轮播图、亮点描述和游玩攻略。") - @GetMapping("/spot/{scenicId}/seasons") - public Result> getSeasons(@ApiParam("景区ID") @PathVariable Long scenicId) { - return Result.success(seasonService.getSeasons(scenicId)); - } - -- @ApiOperation("保存/更新季节内容") -+ @ApiOperation(value = "保存/更新季节内容", notes = "创建或更新指定景区的季节内容。seasonType为季节标识(如spring/summer/autumn/winter)。如果该季节已存在则更新,不存在则创建。支持设置季节别名(如「樱花季」)、月份范围、独立封面和轮播图。") - @PutMapping("/spot/{scenicId}/season/{seasonType}") - public Result saveSeason( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -39,7 +39,7 @@ public class ScenicSeasonController { - return Result.success(seasonService.saveSeason(scenicId, seasonType, request, adminId)); - } - -- @ApiOperation("删除季节内容") -+ @ApiOperation(value = "删除季节内容", notes = "删除指定景区的某个季节内容,同时清理关联的素材引用。") - @DeleteMapping("/spot/{scenicId}/season/{seasonType}") - public Result deleteSeason( - @ApiParam("景区ID") @PathVariable Long scenicId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSpotController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSpotController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSpotController.java -index b8aff01..c2da355 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSpotController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSpotController.java -@@ -26,7 +26,7 @@ public class ScenicSpotController { - - private final ScenicSpotService spotService; - -- @ApiOperation("创建景区") -+ @ApiOperation(value = "创建景区", notes = "新建一个景区资源,初始状态为草稿(status=0)。创建后需通过「提交启用审批」接口走企微OA审批流程才能上架。支持富文本字段(featureIntro/detailContent等),素材ID从素材库获取。\n\n**关联字典**:\n- scenic_facility:景区设施(表单多选)\n- scenic_honor:景区荣誉(表单多选)") - @PostMapping("/spot") - public Result createSpot( - @ApiParam("景区创建请求") @Valid @RequestBody ScenicSpotCreateRequest request, -@@ -35,19 +35,19 @@ public class ScenicSpotController { - return Result.success(spotService.createSpot(request, adminId)); - } - -- @ApiOperation("景区列表") -+ @ApiOperation(value = "景区列表", notes = "分页查询景区列表,支持按名称关键词、状态(0草稿/1上架/2下架)、城市等条件筛选。返回列表摘要信息(不含富文本详情),按sortOrder倒序+创建时间倒序排列。\n\n**关联字典**:\n- scenic_facility:景区设施(列表显示)\n- scenic_honor:景区荣誉(列表显示)") - @GetMapping("/spots") - public Result> listSpots(@ApiParam("景区查询请求") @Valid ScenicSpotQueryRequest query) { - return Result.success(spotService.listSpots(query)); - } - -- @ApiOperation("景区详情") -+ @ApiOperation(value = "景区详情", notes = "获取景区完整信息,包含富文本内容、素材URL、标签列表、季节内容等。素材ID会自动解析为OSS访问地址。\n\n**关联字典**:\n- scenic_facility:景区设施(详情显示)\n- scenic_honor:景区荣誉(详情显示)") - @GetMapping("/spot/{scenicId}") - public Result getSpot(@ApiParam("景区ID") @PathVariable Long scenicId) { - return Result.success(spotService.getSpot(scenicId)); - } - -- @ApiOperation("更新景区") -+ @ApiOperation(value = "更新景区", notes = "更新景区基本信息和富文本内容。更新不会改变当前状态。如果景区已上架,修改后仍保持上架状态,无需重新审批。\n\n**关联字典**:\n- scenic_facility:景区设施(表单多选)\n- scenic_honor:景区荣誉(表单多选)") - @PutMapping("/spot/{scenicId}") - public Result updateSpot( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -57,7 +57,7 @@ public class ScenicSpotController { - return Result.success(spotService.updateSpot(scenicId, request, adminId)); - } - -- @ApiOperation("删除景区") -+ @ApiOperation(value = "删除景区", notes = "软删除景区(设置deleted_at)。仅SUPER_ADMIN角色或创建者本人可删除。已上架的景区需先下架再删除。删除后会同时清理关联的素材引用。") - @DeleteMapping("/spot/{scenicId}") - public Result deleteSpot( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -68,7 +68,7 @@ public class ScenicSpotController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交审批申请。targetStatus=1表示申请上架,targetStatus=2表示申请下架。提交后景区进入PENDING_APPROVAL状态,企微审批通过/拒绝后通过回调自动更新状态。返回企微审批单号spNo。同一景区不可重复提交未完成的审批。") - @PostMapping("/spot/{scenicId}/submit-approval") - public Result> submitApproval( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -80,7 +80,7 @@ public class ScenicSpotController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("上下架切换") -+ @ApiOperation(value = "上下架切换", notes = "直接修改景区状态(跳过审批流程),仅限SUPER_ADMIN使用。普通管理员应使用「提交启用/禁用审批」接口。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/spot/{scenicId}/status") - public Result updateStatus( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -91,7 +91,7 @@ public class ScenicSpotController { - return Result.success(); - } - -- @ApiOperation("批量上下架") -+ @ApiOperation(value = "批量上下架", notes = "批量修改多个景区的状态。scenicIds为景区ID列表(字符串格式),status为目标状态。跳过审批流程,适用于批量管理场景。") - @PutMapping("/spots/batch/status") - public Result batchUpdateStatus( - @ApiParam("景区状态请求") @Valid @RequestBody ScenicStatusRequest request, -@@ -103,7 +103,7 @@ public class ScenicSpotController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个景区。权限校验同单个删除:仅SUPER_ADMIN或创建者可操作。部分失败不影响其他景区的删除。") - @DeleteMapping("/spots/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicTagController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicTagController.java -index eda0e91..1410edc 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicTagController.java -@@ -27,7 +27,7 @@ public class ScenicTagController { - - private final ScenicTagService tagService; - -- @ApiOperation("获取管理标签列表(分页)") -+ @ApiOperation(value = "获取管理标签列表(分页)", notes = "分页查询景区标签库中的所有标签,支持按关键词搜索。标签分为预设标签(管理员创建)和自定义标签(adhoc接口创建),此接口返回全部类型。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class ScenicTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("获取全部标签") -+ @ApiOperation(value = "获取全部标签", notes = "不分页返回所有标签,用于景区编辑时的标签选择下拉列表。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建管理标签") -+ @ApiOperation(value = "创建管理标签", notes = "创建预设标签,标签名不可重复。可指定颜色(tagColor),默认为#409EFF。预设标签在标签管理页面展示和维护。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class ScenicTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "输入标签名称,如果已存在则直接返回,不存在则自动创建。用于景区编辑时快速输入新标签,避免先到标签管理页面创建。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class ScenicTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("编辑标签") -+ @ApiOperation(value = "编辑标签", notes = "修改标签名称或颜色。修改后所有关联此标签的景区会自动生效。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class ScenicTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并自动解除所有景区与该标签的关联关系。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("更新景区标签") -+ @ApiOperation(value = "更新景区标签", notes = "全量替换指定景区的标签列表。传入tagIds为该景区最终要关联的标签ID列表,为空则清除所有标签。") - @PutMapping("/spot/{scenicId}/tags") - public Result updateScenicTags( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -87,7 +87,7 @@ public class ScenicTagController { - return Result.success(); - } - -- @ApiOperation("批量打标签") -+ @ApiOperation(value = "批量打标签", notes = "对多个景区批量添加或移除标签。addTagIds为要添加的标签,removeTagIds为要移除的标签,两者可同时使用。增量操作,不影响未指定的标签。") - @PutMapping("/spots/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/service/controller/InternalServiceController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/InternalServiceController.java b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/InternalServiceController.java -index 95c02bf..4125c0d 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/InternalServiceController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/InternalServiceController.java -@@ -17,7 +17,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】增值服务(Feign调用)") -+@Api(tags = "【内部接口】增值服务(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/service") - @RequiredArgsConstructor -@@ -25,7 +25,7 @@ public class InternalServiceController { - - private final ServiceItemService serviceItemService; - -- @ApiOperation("获取服务简要信息") -+ @ApiOperation(value = "获取服务简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个增值服务的简要信息,返回ID、名称、分类编码、计费类型、是否收费、状态。不存在时返回错误。\n\n**关联字典**:\n- service_unit(计费单位,返回字段billingType):PER_PERSON=元/人, PER_TIME=元/次, PER_DAY=元/天, PER_VEHICLE=元/台, FIXED=固定金额\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/item/{serviceId}") - public Result> getServiceBrief(@PathVariable Long serviceId) { - ServiceItem item = serviceItemService.getServiceItemEntity(serviceId); -@@ -42,7 +42,7 @@ public class InternalServiceController { - return Result.success(brief); - } - -- @ApiOperation("批量获取服务简要信息") -+ @ApiOperation(value = "批量获取服务简要信息", notes = "【仅限内部Feign调用】批量获取增值服务简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询产品关联的服务项。\n\n**关联字典**:\n- service_unit(计费单位,返回字段billingType):PER_PERSON=元/人, PER_TIME=元/次, PER_DAY=元/天, PER_VEHICLE=元/台, FIXED=固定金额\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/items/batch") - public Result>> getServiceBatch(@RequestParam @Size(max = 500) List serviceIds) { - List> results = serviceIds.stream() -@@ -63,9 +63,9 @@ public class InternalServiceController { - return Result.success(results); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配增值服务并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - serviceItemService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceItemController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceItemController.java b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceItemController.java -index 6750979..52e1bb9 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceItemController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceItemController.java -@@ -26,7 +26,7 @@ public class ServiceItemController { - - private final ServiceItemService serviceItemService; - -- @ApiOperation("创建服务") -+ @ApiOperation(value = "创建增值服务", notes = "新建增值服务项目(如保险、签证代办、接送机等),初始状态为草稿(status=0)。支持免费(isPaid=false)和付费两种模式,付费服务有独立的价格日历。需走企微审批上架。\n\n**关联字典**:\n- service_category:服务分类(表单选择)\n- billing_type_service:服务计费方式(表单选择)\n- service_unit:服务计量单位(表单选择)") - @PostMapping("/item") - public Result createServiceItem( - @ApiParam("服务创建请求") @Valid @RequestBody ServiceCreateRequest request, -@@ -35,19 +35,19 @@ public class ServiceItemController { - return Result.success(serviceItemService.createServiceItem(request, adminId)); - } - -- @ApiOperation("服务列表") -+ @ApiOperation(value = "增值服务列表", notes = "分页查询增值服务列表,支持按名称、状态、分类等条件筛选。\n\n**关联字典**:\n- service_category:服务分类(筛选+列表显示)\n- billing_type_service:服务计费方式(列表显示)\n- service_unit:服务计量单位(列表显示)") - @GetMapping("/items") - public Result> listServiceItems(@ApiParam("服务查询请求") @Valid ServiceQueryRequest query) { - return Result.success(serviceItemService.listServiceItems(query)); - } - -- @ApiOperation("服务详情") -+ @ApiOperation(value = "增值服务详情", notes = "获取增值服务完整信息,包含素材URL、标签、计费方式等。\n\n**关联字典**:\n- service_category:服务分类(详情显示)\n- billing_type_service:服务计费方式(详情显示)\n- service_unit:服务计量单位(详情显示)") - @GetMapping("/item/{serviceId}") - public Result getServiceItem(@ApiParam("服务ID") @PathVariable Long serviceId) { - return Result.success(serviceItemService.getServiceItem(serviceId)); - } - -- @ApiOperation("更新服务") -+ @ApiOperation(value = "更新增值服务", notes = "更新增值服务基本信息,不改变当前状态。\n\n**关联字典**:\n- service_category:服务分类(表单选择)\n- billing_type_service:服务计费方式(表单选择)\n- service_unit:服务计量单位(表单选择)") - @PutMapping("/item/{serviceId}") - public Result updateServiceItem( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -57,7 +57,7 @@ public class ServiceItemController { - return Result.success(serviceItemService.updateServiceItem(serviceId, request, adminId)); - } - -- @ApiOperation("删除服务") -+ @ApiOperation(value = "删除增值服务", notes = "软删除增值服务。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/item/{serviceId}") - public Result deleteServiceItem( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -68,7 +68,7 @@ public class ServiceItemController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交审批。targetStatus=1申请上架,targetStatus=2申请下架。返回审批单号spNo。") - @PostMapping("/item/{serviceId}/submit-approval") - public Result> submitApproval( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -80,7 +80,7 @@ public class ServiceItemController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("启用/禁用切换") -+ @ApiOperation(value = "启用/禁用切换", notes = "直接修改状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/item/{serviceId}/status") - public Result updateStatus( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -91,7 +91,7 @@ public class ServiceItemController { - return Result.success(); - } - -- @ApiOperation("批量启用/禁用") -+ @ApiOperation(value = "批量启用/禁用", notes = "批量修改多个增值服务的状态,跳过审批流程。") - @PutMapping("/items/batch/status") - public Result batchUpdateStatus( - @ApiParam("服务状态请求") @Valid @RequestBody ServiceStatusRequest request, -@@ -103,7 +103,7 @@ public class ServiceItemController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个增值服务。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/items/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServicePriceCalendarController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServicePriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServicePriceCalendarController.java -index e96654d..a2f52d3 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServicePriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServicePriceCalendarController.java -@@ -25,7 +25,7 @@ public class ServicePriceCalendarController { - - private final ServicePriceCalendarService priceService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询增值服务的每日价格和可售状态。仅付费服务(isPaid=true)需要设置价格日历。") - @GetMapping("/item/{serviceId}/prices") - public Result getPriceCalendar( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -34,7 +34,7 @@ public class ServicePriceCalendarController { - return Result.success(priceService.getPriceCalendar(serviceId, year, month)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", notes = "在指定日期范围内批量设置服务的成本价和可售状态。") - @PutMapping("/item/{serviceId}/prices") - public Result batchSetPrices( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -43,7 +43,7 @@ public class ServicePriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改可售状态") -+ @ApiOperation(value = "批量修改可售状态", notes = "批量修改日期范围内的可售状态,不影响价格。") - @PutMapping("/item/{serviceId}/prices/batch-status") - public Result batchUpdateStatus( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -52,7 +52,7 @@ public class ServicePriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量清除价格") -+ @ApiOperation(value = "批量清除价格", notes = "删除指定日期范围内的价格记录。日期格式:yyyy-MM-dd。") - @DeleteMapping("/item/{serviceId}/prices") - public Result deletePrices( - @ApiParam("服务ID") @PathVariable Long serviceId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceTagController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceTagController.java -index cf3865a..5dca328 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceTagController.java -@@ -27,7 +27,7 @@ public class ServiceTagController { - - private final ServiceTagService tagService; - -- @ApiOperation("获取管理标签列表(分页)") -+ @ApiOperation(value = "获取管理标签列表(分页)", notes = "分页查询增值服务标签库,支持按关键词搜索。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class ServiceTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("获取全部标签") -+ @ApiOperation(value = "获取全部标签", notes = "不分页返回所有标签,用于服务编辑时的标签选择。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建管理标签") -+ @ApiOperation(value = "创建管理标签", notes = "创建预设标签,标签名不可重复。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class ServiceTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "按名称查找或自动创建标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class ServiceTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("编辑标签") -+ @ApiOperation(value = "编辑标签", notes = "修改标签名称或颜色,所有关联服务自动生效。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class ServiceTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并解除所有服务与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("更新服务标签") -+ @ApiOperation(value = "更新服务标签", notes = "全量替换指定服务的标签列表。") - @PutMapping("/item/{serviceId}/tags") - public Result updateServiceTags( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -87,7 +87,7 @@ public class ServiceTagController { - return Result.success(); - } - -- @ApiOperation("批量打标签") -+ @ApiOperation(value = "批量打标签", notes = "对多个服务批量添加/移除标签。增量操作。") - @PutMapping("/items/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/InternalStaffController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/InternalStaffController.java b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/InternalStaffController.java -index 7c8bb51..ce700da 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/InternalStaffController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/InternalStaffController.java -@@ -19,7 +19,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】服务人员(Feign调用)") -+@Api(tags = "【内部接口】服务人员(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/staff") - @RequiredArgsConstructor -@@ -28,7 +28,7 @@ public class InternalStaffController { - private final StaffService staffService; - private final StaffMapper staffMapper; - -- @ApiOperation("获取人员简要信息") -+ @ApiOperation(value = "获取人员简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个服务人员的简要信息,返回ID、姓名、人员类型、手机号、状态。不存在时返回错误。\n\n**关联字典**:\n- staff_type(人员类型,返回字段staffType):GUIDE=导游, DRIVER=司机, PHOTOGRAPHER=摄影师, CHEF=厨师\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/{staffId}") - public Result> getStaffBrief(@PathVariable Long staffId) { - Staff staff = staffService.getStaffEntity(staffId); -@@ -44,7 +44,7 @@ public class InternalStaffController { - return Result.success(brief); - } - -- @ApiOperation("批量获取人员简要信息") -+ @ApiOperation(value = "批量获取人员简要信息", notes = "【仅限内部Feign调用】批量获取服务人员简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询团批关联的服务人员。\n\n**关联字典**:\n- staff_type(人员类型,返回字段staffType):GUIDE=导游, DRIVER=司机, PHOTOGRAPHER=摄影师, CHEF=厨师\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/batch") - public Result>> getStaffBatch(@RequestParam @Size(max = 500) List staffIds) { - List> results = staffIds.stream() -@@ -64,7 +64,7 @@ public class InternalStaffController { - return Result.success(results); - } - -- @ApiOperation("按人员类型查询") -+ @ApiOperation(value = "按人员类型查询", notes = "【仅限内部Feign调用】按staffType查询第一个匹配的服务人员。staffType如:GUIDE(导游)、DRIVER(司机)、PHOTOGRAPHER(摄影师)等。未找到时返回null。\n\n**关联字典**:\n- staff_type(人员类型,请求参数+返回字段staffType):GUIDE=导游, DRIVER=司机, PHOTOGRAPHER=摄影师, CHEF=厨师\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/by-type/{staffType}") - public Result> getStaffByType(@PathVariable String staffType) { - Staff staff = staffService.getStaffByType(staffType); -@@ -80,9 +80,9 @@ public class InternalStaffController { - return Result.success(brief); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配服务人员并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - staffService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -@@ -91,7 +91,7 @@ public class InternalStaffController { - /** - * Batch get staff basic info by comma-separated IDs (for product-service batch staff snapshot). - */ -- @ApiOperation("批量获取人员基本信息(逗号分隔ID)") -+ @ApiOperation(value = "批量获取人员基本信息(逗号分隔ID)", notes = "【仅限内部Feign调用】通过逗号分隔的ID字符串批量获取人员基本信息(含staffId、name、phone、staffType、coverMaterialId)。供产品服务团批人员快照使用。与/batch接口不同,此接口接收逗号分隔字符串而非数组。\n\n**关联字典**:\n- staff_type(人员类型,返回字段staffType):GUIDE=导游, DRIVER=司机, PHOTOGRAPHER=摄影师, CHEF=厨师") - @GetMapping("/batch-basic") - public Result>> batchGetStaffBasic(@RequestParam String staffIds) { - List ids = Arrays.stream(staffIds.split(",")) -@@ -122,7 +122,7 @@ public class InternalStaffController { - * List available staff (status=1), optionally filter by staffType. - * Used by admin batch staff selection dropdown. - */ -- @ApiOperation("列出可用人员(用于下拉选择)") -+ @ApiOperation(value = "列出可用人员(用于下拉选择)", notes = "【仅限内部Feign调用】列出所有status=1的可用服务人员,可按staffType筛选。按sortOrder和staffId排序。供管理后台团批分配人员的下拉选择框使用。\n\n**关联字典**:\n- staff_type(人员类型,请求参数+返回字段staffType):GUIDE=导游, DRIVER=司机, PHOTOGRAPHER=摄影师, CHEF=厨师") - @GetMapping("/list-available") - public Result>> listAvailableStaff( - @RequestParam(required = false) String staffType) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffController.java b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffController.java -index f90638f..be01710 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffController.java -@@ -24,7 +24,7 @@ public class StaffController { - - private final StaffService staffService; - -- @ApiOperation("创建服务人员") -+ @ApiOperation(value = "创建服务人员", notes = "新建服务人员(导游/领队/摄影师/助理等)。人员类型(staffType)决定了其在价格日历中的归类。需走企微审批上架后才能被产品引用。\n\n**关联字典**:\n- staff_type:人员类型(表单选择)\n- guide_level:导游等级(表单选择)\n- driver_license_type:驾照类型(表单选择)\n- language:语言能力(表单多选)\n- guide_specialty:导游专长(表单多选)\n- guide_service_area:服务区域(表单多选)") - @PostMapping - public Result createStaff(@ApiParam("服务人员创建请求") @Valid @RequestBody StaffCreateRequest request, - HttpServletRequest httpRequest) { -@@ -32,19 +32,19 @@ public class StaffController { - return Result.success(staffService.createStaff(request, adminId)); - } - -- @ApiOperation("服务人员列表") -+ @ApiOperation(value = "服务人员列表", notes = "分页查询服务人员列表,支持按姓名、状态、人员类型等条件筛选。\n\n**关联字典**:\n- staff_type:人员类型(筛选+列表显示)\n- guide_level:导游等级(列表显示)\n- driver_license_type:驾照类型(列表显示)\n- language:语言能力(列表显示)\n- guide_specialty:导游专长(列表显示)\n- guide_service_area:服务区域(列表显示)") - @GetMapping("/list") - public Result> listStaff(@ApiParam("服务人员查询请求") @Valid StaffQueryRequest query) { - return Result.success(staffService.listStaff(query)); - } - -- @ApiOperation("服务人员详情") -+ @ApiOperation(value = "服务人员详情", notes = "获取服务人员完整信息,包含素材URL、标签、技能描述等。\n\n**关联字典**:\n- staff_type:人员类型(详情显示)\n- guide_level:导游等级(详情显示)\n- driver_license_type:驾照类型(详情显示)\n- language:语言能力(详情显示)\n- guide_specialty:导游专长(详情显示)\n- guide_service_area:服务区域(详情显示)") - @GetMapping("/{staffId}") - public Result getStaff(@ApiParam("人员ID") @PathVariable Long staffId) { - return Result.success(staffService.getStaff(staffId)); - } - -- @ApiOperation("更新服务人员") -+ @ApiOperation(value = "更新服务人员", notes = "更新服务人员基本信息,不改变当前状态。\n\n**关联字典**:\n- staff_type:人员类型(表单选择)\n- guide_level:导游等级(表单选择)\n- driver_license_type:驾照类型(表单选择)\n- language:语言能力(表单多选)\n- guide_specialty:导游专长(表单多选)\n- guide_service_area:服务区域(表单多选)") - @PutMapping("/{staffId}") - public Result updateStaff(@ApiParam("人员ID") @PathVariable Long staffId, - @ApiParam("服务人员更新请求") @Valid @RequestBody StaffUpdateRequest request, -@@ -53,7 +53,7 @@ public class StaffController { - return Result.success(staffService.updateStaff(staffId, request, adminId)); - } - -- @ApiOperation("删除服务人员") -+ @ApiOperation(value = "删除服务人员", notes = "软删除服务人员。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/{staffId}") - public Result deleteStaff(@ApiParam("人员ID") @PathVariable Long staffId, HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -@@ -62,7 +62,7 @@ public class StaffController { - return Result.success(); - } - -- @ApiOperation("提交审批") -+ @ApiOperation(value = "提交审批", notes = "向企微OA提交人员启用/禁用审批。targetStatus=1申请启用,targetStatus=2申请禁用。返回审批单号spNo。") - @PostMapping("/{staffId}/submit-approval") - public Result> submitApproval(@ApiParam("人员ID") @PathVariable Long staffId, - @ApiParam("审批提交请求体") @Valid @RequestBody ApprovalSubmitRequest request, -@@ -72,7 +72,7 @@ public class StaffController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("更新状态") -+ @ApiOperation(value = "更新状态", notes = "直接修改人员状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=启用,2=禁用。") - @PutMapping("/{staffId}/status") - public Result updateStatus(@ApiParam("人员ID") @PathVariable Long staffId, - @ApiParam("状态请求体") @Valid @RequestBody StaffStatusRequest request, -@@ -82,14 +82,14 @@ public class StaffController { - return Result.success(); - } - -- @ApiOperation("批量更新状态") -+ @ApiOperation(value = "批量更新状态", notes = "批量修改多个服务人员的状态,跳过审批流程。") - @PutMapping("/batch/status") - public Result batchUpdateStatus(@ApiParam("批量状态请求体") @Valid @RequestBody StaffStatusRequest request) { - staffService.batchUpdateStatus(request.getStaffIds(), request.getStatus()); - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个服务人员。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/batch") - public Result batchDelete(@ApiParam("批量删除请求体") @Valid @RequestBody StaffBatchDeleteRequest request, - HttpServletRequest httpRequest) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffPriceCalendarController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffPriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffPriceCalendarController.java -index 2993bef..a762de1 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffPriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffPriceCalendarController.java -@@ -27,7 +27,7 @@ public class StaffPriceCalendarController { - - private final StaffPriceCalendarService priceCalendarService; - -- @ApiOperation("查询价格日历(按人员类型)") -+ @ApiOperation(value = "查询价格日历(按人员类型)", notes = "按月查询指定人员类型的每日服务费用和可调度状态。注意:价格日历按人员类型维度管理,非按个人维度。同一类型的所有人员共享同一套价格。\n\n**关联字典**:\n- staff_type(人员类型)→ staffType路径参数") - @GetMapping("/type/{staffType}/prices") - public Result getPriceCalendar( - @ApiParam("人员类型: GUIDE/GUIDE_ASSISTANT/PHOTOGRAPHER/LEADER/OTHER") @PathVariable String staffType, -@@ -36,7 +36,7 @@ public class StaffPriceCalendarController { - return Result.success(priceCalendarService.getPriceCalendar(staffType, year, month)); - } - -- @ApiOperation("批量设置价格(按人员类型)") -+ @ApiOperation(value = "批量设置价格(按人员类型)", notes = "在指定日期范围内批量设置该类型人员的服务成本价和可调度状态。\n\n**关联字典**:\n- staff_type(人员类型)→ staffType路径参数") - @PutMapping("/type/{staffType}/prices") - public Result batchSetPrices( - @ApiParam("人员类型: GUIDE/GUIDE_ASSISTANT/PHOTOGRAPHER/LEADER/OTHER") @PathVariable String staffType, -@@ -45,7 +45,7 @@ public class StaffPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改调度状态(按人员类型)") -+ @ApiOperation(value = "批量修改调度状态(按人员类型)", notes = "批量修改日期范围内的可调度状态,不影响价格。\n\n**关联字典**:\n- staff_type(人员类型)→ staffType路径参数") - @PutMapping("/type/{staffType}/prices/batch-status") - public Result batchUpdateStatus( - @ApiParam("人员类型: GUIDE/GUIDE_ASSISTANT/PHOTOGRAPHER/LEADER/OTHER") @PathVariable String staffType, -@@ -54,7 +54,7 @@ public class StaffPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("清除价格日历(按人员类型)") -+ @ApiOperation(value = "清除价格日历(按人员类型)", notes = "删除指定日期范围内该类型人员的价格记录。日期格式:yyyy-MM-dd。\n\n**关联字典**:\n- staff_type(人员类型)→ staffType路径参数") - @DeleteMapping("/type/{staffType}/prices") - public Result deletePrices( - @ApiParam("人员类型: GUIDE/GUIDE_ASSISTANT/PHOTOGRAPHER/LEADER/OTHER") @PathVariable String staffType, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffTagController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffTagController.java -index beceb5f..ff68d2c 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffTagController.java -@@ -26,7 +26,7 @@ public class StaffTagController { - - private final StaffTagService tagService; - -- @ApiOperation("预设标签列表(分页)") -+ @ApiOperation(value = "预设标签列表(分页)", notes = "分页查询服务人员标签库,支持按关键词搜索。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -35,13 +35,13 @@ public class StaffTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("全部标签列表") -+ @ApiOperation(value = "全部标签列表", notes = "不分页返回所有标签,用于人员编辑时的标签选择。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建标签") -+ @ApiOperation(value = "创建标签", notes = "创建预设标签,标签名不可重复。") - @PostMapping("/tag") - public Result createTag(@ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, - HttpServletRequest httpRequest) { -@@ -49,7 +49,7 @@ public class StaffTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "按名称查找或自动创建标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag(@ApiParam("标签名称请求体") @Valid @RequestBody TagCreateRequest request, - HttpServletRequest httpRequest) { -@@ -57,21 +57,21 @@ public class StaffTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("更新标签") -+ @ApiOperation(value = "更新标签", notes = "修改标签名称或颜色。") - @PutMapping("/tag/{tagId}") - public Result updateTag(@ApiParam("标签ID") @PathVariable Long tagId, - @ApiParam("标签更新请求") @Valid @RequestBody TagUpdateRequest request) { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并解除所有人员与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("设置人员标签") -+ @ApiOperation(value = "设置人员标签", notes = "全量替换指定人员的标签列表。") - @PutMapping("/{staffId}/tags") - public Result updateStaffTags(@ApiParam("人员ID") @PathVariable Long staffId, - @ApiParam("标签ID列表请求") @Valid @RequestBody StaffTagUpdateRequest request) { -@@ -79,7 +79,7 @@ public class StaffTagController { - return Result.success(); - } - -- @ApiOperation("批量添加/移除标签") -+ @ApiOperation(value = "批量添加/移除标签", notes = "对多个人员批量添加/移除标签。增量操作。") - @PutMapping("/batch/tags") - public Result batchUpdateTags(@ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { - tagService.batchUpdateTags(request.getStaffIds(), request.getAddTagIds(), request.getRemoveTagIds()); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/InternalSuppliesController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/InternalSuppliesController.java b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/InternalSuppliesController.java -index 5467d19..e827b51 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/InternalSuppliesController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/InternalSuppliesController.java -@@ -17,7 +17,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】备品(Feign调用)") -+@Api(tags = "【内部接口】备品(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/supplies") - @RequiredArgsConstructor -@@ -25,7 +25,7 @@ public class InternalSuppliesController { - - private final SuppliesService suppliesService; - -- @ApiOperation("获取备品简要信息") -+ @ApiOperation(value = "获取备品简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个备品的简要信息,返回ID、名称、分类编码、计费类型、状态。不存在时返回错误。\n\n**关联字典**:\n- supplies_category(备品分类,返回字段categoryCode):CAMPING=露营, CLOTHING=服装, EQUIPMENT=装备, SAFETY=安全\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/item/{suppliesId}") - public Result> getSuppliesBrief(@PathVariable Long suppliesId) { - SuppliesItem item = suppliesService.getSuppliesEntity(suppliesId); -@@ -41,7 +41,7 @@ public class InternalSuppliesController { - return Result.success(brief); - } - -- @ApiOperation("批量获取备品简要信息") -+ @ApiOperation(value = "批量获取备品简要信息", notes = "【仅限内部Feign调用】批量获取备品简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询产品关联的备品资源。\n\n**关联字典**:\n- supplies_category(备品分类,返回字段categoryCode):CAMPING=露营, CLOTHING=服装, EQUIPMENT=装备, SAFETY=安全\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/items/batch") - public Result>> getSuppliesBatch(@RequestParam @Size(max = 500) List suppliesIds) { - List> results = suppliesIds.stream() -@@ -61,9 +61,9 @@ public class InternalSuppliesController { - return Result.success(results); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配备品并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - suppliesService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesController.java b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesController.java -index 435f28b..964e6fc 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesController.java -@@ -26,7 +26,7 @@ public class SuppliesController { - - private final SuppliesService suppliesService; - -- @ApiOperation("创建备品") -+ @ApiOperation(value = "创建备品", notes = "新建备品资源(帐篷、睡袋、炊具等物资),初始状态为草稿(status=0)。需走企微审批上架。支持按件(PER_ITEM)和按人(PER_PERSON)计费。\n\n**关联字典**:\n- supplies_category:备品分类(表单选择)\n- billing_type:计费方式(表单选择)") - @PostMapping("/item") - public Result createSupplies( - @ApiParam("备品创建请求") @Valid @RequestBody SuppliesCreateRequest request, -@@ -35,19 +35,19 @@ public class SuppliesController { - return Result.success(suppliesService.createSupplies(request, adminId)); - } - -- @ApiOperation("备品列表") -+ @ApiOperation(value = "备品列表", notes = "分页查询备品列表,支持按名称、状态、分类等条件筛选。\n\n**关联字典**:\n- supplies_category:备品分类(筛选+列表显示)\n- billing_type:计费方式(列表显示)") - @GetMapping("/items") - public Result> listSupplies(@ApiParam("备品查询请求") @Valid SuppliesQueryRequest query) { - return Result.success(suppliesService.listSupplies(query)); - } - -- @ApiOperation("备品详情") -+ @ApiOperation(value = "备品详情", notes = "获取备品完整信息,包含素材URL、标签等。\n\n**关联字典**:\n- supplies_category:备品分类(详情显示)\n- billing_type:计费方式(详情显示)") - @GetMapping("/item/{suppliesId}") - public Result getSupplies(@ApiParam("备品ID") @PathVariable Long suppliesId) { - return Result.success(suppliesService.getSupplies(suppliesId)); - } - -- @ApiOperation("更新备品") -+ @ApiOperation(value = "更新备品", notes = "更新备品基本信息,不改变当前状态。\n\n**关联字典**:\n- supplies_category:备品分类(表单选择)\n- billing_type:计费方式(表单选择)") - @PutMapping("/item/{suppliesId}") - public Result updateSupplies( - @ApiParam("备品ID") @PathVariable Long suppliesId, -@@ -57,7 +57,7 @@ public class SuppliesController { - return Result.success(suppliesService.updateSupplies(suppliesId, request, adminId)); - } - -- @ApiOperation("删除备品") -+ @ApiOperation(value = "删除备品", notes = "软删除备品。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/item/{suppliesId}") - public Result deleteSupplies( - @ApiParam("备品ID") @PathVariable Long suppliesId, -@@ -68,7 +68,7 @@ public class SuppliesController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交审批。targetStatus=1申请上架,targetStatus=2申请下架。返回审批单号spNo。") - @PostMapping("/item/{suppliesId}/submit-approval") - public Result> submitApproval( - @ApiParam("备品ID") @PathVariable Long suppliesId, -@@ -80,7 +80,7 @@ public class SuppliesController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("上下架切换") -+ @ApiOperation(value = "上下架切换", notes = "直接修改状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/item/{suppliesId}/status") - public Result updateStatus( - @ApiParam("备品ID") @PathVariable Long suppliesId, -@@ -91,7 +91,7 @@ public class SuppliesController { - return Result.success(); - } - -- @ApiOperation("批量上下架") -+ @ApiOperation(value = "批量上下架", notes = "批量修改多个备品的状态,跳过审批流程。") - @PutMapping("/items/batch/status") - public Result batchUpdateStatus( - @ApiParam("备品状态请求") @Valid @RequestBody SuppliesStatusRequest request, -@@ -103,7 +103,7 @@ public class SuppliesController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个备品。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/items/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesTagController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesTagController.java -index 7529058..8095ade 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesTagController.java -@@ -27,7 +27,7 @@ public class SuppliesTagController { - - private final SuppliesTagService tagService; - -- @ApiOperation("获取管理标签列表(分页)") -+ @ApiOperation(value = "获取管理标签列表(分页)", notes = "分页查询备品标签库,支持按关键词搜索。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class SuppliesTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("获取全部标签") -+ @ApiOperation(value = "获取全部标签", notes = "不分页返回所有标签,用于备品编辑时的标签选择下拉。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建管理标签") -+ @ApiOperation(value = "创建管理标签", notes = "创建预设标签,标签名不可重复。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class SuppliesTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "按名称查找或自动创建标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class SuppliesTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("编辑标签") -+ @ApiOperation(value = "编辑标签", notes = "修改标签名称或颜色,所有关联备品自动生效。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class SuppliesTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并解除所有备品与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("更新备品标签") -+ @ApiOperation(value = "更新备品标签", notes = "全量替换指定备品的标签列表。") - @PutMapping("/item/{suppliesId}/tags") - public Result updateSuppliesTags( - @ApiParam("备品ID") @PathVariable Long suppliesId, -@@ -87,7 +87,7 @@ public class SuppliesTagController { - return Result.success(); - } - -- @ApiOperation("批量打标签") -+ @ApiOperation(value = "批量打标签", notes = "对多个备品批量添加/移除标签。增量操作。") - @PutMapping("/items/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/InternalVehicleController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/InternalVehicleController.java b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/InternalVehicleController.java -index 4e672d1..a0dc396 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/InternalVehicleController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/InternalVehicleController.java -@@ -17,7 +17,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】车型(Feign调用)") -+@Api(tags = "【内部接口】车型(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/vehicle") - @RequiredArgsConstructor -@@ -25,7 +25,7 @@ public class InternalVehicleController { - - private final VehicleModelService vehicleModelService; - -- @ApiOperation("获取车型简要信息") -+ @ApiOperation(value = "获取车型简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个车型的简要信息,返回ID、名称、车辆类型、品牌、座位数、状态。不存在时返回错误。\n\n**关联字典**:\n- vehicle_type(车辆类型,返回字段vehicleType):CAR=小轿车, SUV=越野车, VAN=商务车, BUS=大巴, MINIBUS=中巴\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/model/{vehicleId}") - public Result> getVehicleBrief(@PathVariable Long vehicleId) { - VehicleModel model = vehicleModelService.getVehicleEntity(vehicleId); -@@ -42,7 +42,7 @@ public class InternalVehicleController { - return Result.success(brief); - } - -- @ApiOperation("批量获取车型简要信息") -+ @ApiOperation(value = "批量获取车型简要信息", notes = "【仅限内部Feign调用】批量获取车型简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询行程关联的车辆资源。\n\n**关联字典**:\n- vehicle_type(车辆类型,返回字段vehicleType):CAR=小轿车, SUV=越野车, VAN=商务车, BUS=大巴, MINIBUS=中巴\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/models/batch") - public Result>> getVehicleBatch(@RequestParam @Size(max = 500) List vehicleIds) { - List> results = vehicleIds.stream() -@@ -63,7 +63,7 @@ public class InternalVehicleController { - return Result.success(results); - } - -- @ApiOperation("按车辆类型查询车辆") -+ @ApiOperation(value = "按车辆类型查询车辆", notes = "【仅限内部Feign调用】按vehicleType查询第一个匹配的车型。vehicleType如:SEDAN(轿车)、SUV、MPV、BUS(大巴)、MINIBUS(中巴)等。未找到时返回null。\n\n**关联字典**:\n- vehicle_type(车辆类型,请求参数+返回字段vehicleType):CAR=小轿车, SUV=越野车, VAN=商务车, BUS=大巴, MINIBUS=中巴\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/model/by-type/{vehicleType}") - public Result> getVehicleByType(@PathVariable String vehicleType) { - VehicleModel model = vehicleModelService.getVehicleByType(vehicleType); -@@ -80,7 +80,7 @@ public class InternalVehicleController { - return Result.success(brief); - } - -- @ApiOperation("按名称查询车辆") -+ @ApiOperation(value = "按名称查询车辆", notes = "【仅限内部Feign调用】按车型名称精确查询车辆信息。未找到时返回null。供产品服务通过名称关联车型使用。\n\n**关联字典**:\n- vehicle_type(车辆类型,返回字段vehicleType):CAR=小轿车, SUV=越野车, VAN=商务车, BUS=大巴, MINIBUS=中巴\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/model/by-name/{name}") - public Result> getVehicleByName(@PathVariable String name) { - VehicleModel model = vehicleModelService.getVehicleByName(name); -@@ -97,9 +97,9 @@ public class InternalVehicleController { - return Result.success(brief); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配车型并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - vehicleModelService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleModelController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleModelController.java b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleModelController.java -index de59d9f..37797fd 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleModelController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleModelController.java -@@ -25,7 +25,7 @@ public class VehicleModelController { - - private final VehicleModelService vehicleModelService; - -- @ApiOperation("创建车型") -+ @ApiOperation(value = "创建车型", notes = "新建车型资源(如7座商务车、14座中巴等),初始状态为草稿(status=0)。车型有独立的价格日历用于报价计算。需走企微审批上架。\n\n**关联字典**:\n- vehicle_type:车辆类型(表单选择)") - @PostMapping("/model") - public Result createVehicle(@ApiParam("车型创建请求") @Valid @RequestBody VehicleCreateRequest request, - HttpServletRequest httpRequest) { -@@ -33,26 +33,26 @@ public class VehicleModelController { - return Result.success(vehicleModelService.createVehicle(request, adminId)); - } - -- @ApiOperation("车型列表") -+ @ApiOperation(value = "车型列表", notes = "分页查询车型列表,支持按名称、状态、车辆类型等条件筛选。\n\n**关联字典**:\n- vehicle_type:车辆类型(筛选+列表显示)") - @GetMapping("/models") - public Result> listVehicles(@ApiParam("车型查询请求") @Valid VehicleQueryRequest query) { - return Result.success(vehicleModelService.listVehicles(query)); - } - -- @ApiOperation("车型全量列表(不分页,用于下拉选择)") -+ @ApiOperation(value = "车型全量列表(不分页,用于下拉选择)", notes = "返回所有车型列表,可选按状态筛选。适用于产品编排时选择车型的下拉选择框。不分页返回全部数据。\n\n**关联字典**:\n- vehicle_type:车辆类型(列表显示)") - @GetMapping("/models/all") - public Result> listAllVehicles( - @ApiParam("状态筛选:1=上架") @RequestParam(required = false) Integer status) { - return Result.success(vehicleModelService.listAllVehicles(status)); - } - -- @ApiOperation("车型详情") -+ @ApiOperation(value = "车型详情", notes = "获取车型完整信息,包含座位数、品牌、素材URL、标签等。\n\n**关联字典**:\n- vehicle_type:车辆类型(详情显示)") - @GetMapping("/model/{vehicleId}") - public Result getVehicle(@ApiParam("车型ID") @PathVariable Long vehicleId) { - return Result.success(vehicleModelService.getVehicle(vehicleId)); - } - -- @ApiOperation("更新车型") -+ @ApiOperation(value = "更新车型", notes = "更新车型基本信息,不改变当前状态。\n\n**关联字典**:\n- vehicle_type:车辆类型(表单选择)") - @PutMapping("/model/{vehicleId}") - public Result updateVehicle(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("车型更新请求") @Valid @RequestBody VehicleUpdateRequest request, -@@ -61,7 +61,7 @@ public class VehicleModelController { - return Result.success(vehicleModelService.updateVehicle(vehicleId, request, adminId)); - } - -- @ApiOperation("删除车型") -+ @ApiOperation(value = "删除车型", notes = "软删除车型。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/model/{vehicleId}") - public Result deleteVehicle(@ApiParam("车型ID") @PathVariable Long vehicleId, HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -@@ -70,7 +70,7 @@ public class VehicleModelController { - return Result.success(); - } - -- @ApiOperation("提交审批") -+ @ApiOperation(value = "提交审批", notes = "向企微OA提交车型启用/禁用审批。targetStatus=1申请上架,targetStatus=2申请下架。返回审批单号spNo。") - @PostMapping("/model/{vehicleId}/submit-approval") - public Result> submitApproval(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("审批提交请求体") @Valid @RequestBody ApprovalSubmitRequest request, -@@ -80,7 +80,7 @@ public class VehicleModelController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("更新状态") -+ @ApiOperation(value = "更新状态", notes = "直接修改车型状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/model/{vehicleId}/status") - public Result updateStatus(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("状态请求体") @Valid @RequestBody VehicleStatusRequest request, -@@ -90,7 +90,7 @@ public class VehicleModelController { - return Result.success(); - } - -- @ApiOperation("批量更新状态") -+ @ApiOperation(value = "批量更新状态", notes = "批量修改多个车型的状态,跳过审批流程。") - @PutMapping("/models/batch/status") - public Result batchUpdateStatus(@ApiParam("批量状态请求体") @Valid @RequestBody VehicleStatusRequest request, - HttpServletRequest httpRequest) { -@@ -98,7 +98,7 @@ public class VehicleModelController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个车型。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/models/batch") - public Result batchDelete(@ApiParam("批量删除请求体") @Valid @RequestBody VehicleBatchDeleteRequest request, - HttpServletRequest httpRequest) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehiclePriceCalendarController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehiclePriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehiclePriceCalendarController.java -index 52a68eb..c1bcfba 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehiclePriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehiclePriceCalendarController.java -@@ -27,7 +27,7 @@ public class VehiclePriceCalendarController { - - private final VehiclePriceCalendarService priceCalendarService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询车型的每日租赁价格和可调度状态。") - @GetMapping("/model/{vehicleId}/prices") - public Result getPriceCalendar(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("年份") @RequestParam @Min(2020) @Max(2100) Integer year, -@@ -35,7 +35,7 @@ public class VehiclePriceCalendarController { - return Result.success(priceCalendarService.getPriceCalendar(vehicleId, year, month)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", notes = "在指定日期范围内批量设置车型的租赁成本价和可调度状态。") - @PutMapping("/model/{vehicleId}/prices") - public Result batchSetPrices(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("价格日历设置请求") @Valid @RequestBody PriceCalendarSetRequest request) { -@@ -43,7 +43,7 @@ public class VehiclePriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改调度状态") -+ @ApiOperation(value = "批量修改调度状态", notes = "批量修改日期范围内车型的可调度状态,不影响价格。") - @PutMapping("/model/{vehicleId}/prices/batch-status") - public Result batchUpdateStatus(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("价格日历状态请求") @Valid @RequestBody PriceCalendarStatusRequest request) { -@@ -51,7 +51,7 @@ public class VehiclePriceCalendarController { - return Result.success(); - } - -- @ApiOperation("清除价格日历") -+ @ApiOperation(value = "清除价格日历", notes = "删除指定日期范围内车型的价格记录。日期格式:yyyy-MM-dd。") - @DeleteMapping("/model/{vehicleId}/prices") - public Result deletePrices(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("开始日期") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleTagController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleTagController.java -index a7a1b49..b2ad988 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleTagController.java -@@ -26,7 +26,7 @@ public class VehicleTagController { - - private final VehicleTagService tagService; - -- @ApiOperation("预设标签列表(分页)") -+ @ApiOperation(value = "预设标签列表(分页)", notes = "分页查询车型标签库,支持按关键词搜索。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -35,13 +35,13 @@ public class VehicleTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("全部标签列表") -+ @ApiOperation(value = "全部标签列表", notes = "不分页返回所有标签,用于车型编辑时的标签选择。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建标签") -+ @ApiOperation(value = "创建标签", notes = "创建预设标签,标签名不可重复。") - @PostMapping("/tag") - public Result createTag(@ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, - HttpServletRequest httpRequest) { -@@ -49,7 +49,7 @@ public class VehicleTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "按名称查找或自动创建标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag(@ApiParam("标签名称请求体") @Valid @RequestBody TagCreateRequest request, - HttpServletRequest httpRequest) { -@@ -57,21 +57,21 @@ public class VehicleTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("更新标签") -+ @ApiOperation(value = "更新标签", notes = "修改标签名称或颜色。") - @PutMapping("/tag/{tagId}") - public Result updateTag(@ApiParam("标签ID") @PathVariable Long tagId, - @ApiParam("标签更新请求") @Valid @RequestBody TagUpdateRequest request) { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并解除所有车型与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("设置车型标签") -+ @ApiOperation(value = "设置车型标签", notes = "全量替换指定车型的标签列表。") - @PutMapping("/model/{vehicleId}/tags") - public Result updateVehicleTags(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("标签ID列表请求") @Valid @RequestBody VehicleTagUpdateRequest request) { -@@ -79,7 +79,7 @@ public class VehicleTagController { - return Result.success(); - } - -- @ApiOperation("批量添加/移除标签") -+ @ApiOperation(value = "批量添加/移除标签", notes = "对多个车型批量添加/移除标签。增量操作。") - @PutMapping("/models/batch/tags") - public Result batchUpdateTags(@ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { - tagService.batchUpdateTags(request.getVehicleIds(), request.getAddTagIds(), request.getRemoveTagIds()); -``` - -### `hl-review-service/src/main/java/com/hulalv/review/controller/AdminReviewController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-review-service/src/main/java/com/hulalv/review/controller/AdminReviewController.java b/hl-review-service/src/main/java/com/hulalv/review/controller/AdminReviewController.java -index 1781646..ad503eb 100644 ---- a/hl-review-service/src/main/java/com/hulalv/review/controller/AdminReviewController.java -+++ b/hl-review-service/src/main/java/com/hulalv/review/controller/AdminReviewController.java -@@ -25,19 +25,19 @@ public class AdminReviewController { - - private final ReviewService reviewService; - -- @ApiOperation("评价列表(支持好中差评/有图/有视频筛选)") -+ @ApiOperation(value = "评价列表(支持好中差评/有图/有视频筛选)", notes = "分页查询全部评价(含待审核/已通过/已拒绝),支持按评价等级、是否有图/视频、目标类型筛选\n\n**关联字典**:\n- review_status:评价审核状态(列表筛选+显示)\n- rating_level:评价等级(列表筛选+显示)") - @GetMapping("/list") - public Result> listReviews(@ApiParam("评价查询条件") ReviewQueryRequest request) { - return Result.success(reviewService.listReviews(request)); - } - -- @ApiOperation("评价详情") -+ @ApiOperation(value = "评价详情", notes = "**关联字典**:\n- review_status:评价审核状态(显示)\n- rating_level:评价等级(显示)") - @GetMapping("/{reviewId}") - public Result getReviewDetail(@ApiParam("评价ID") @PathVariable Long reviewId) { - return Result.success(reviewService.getReviewDetail(reviewId)); - } - -- @ApiOperation("通过评价") -+ @ApiOperation(value = "通过评价", notes = "审核通过评价,通过后评价在小程序端公开展示。状态流转:PENDING_REVIEW → APPROVED") - @PostMapping("/{reviewId}/approve") - public Result approve(@ApiParam("评价ID") @PathVariable Long reviewId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -47,7 +47,7 @@ public class AdminReviewController { - return Result.success(); - } - -- @ApiOperation("拒绝评价") -+ @ApiOperation(value = "拒绝评价", notes = "审核拒绝评价,需填写拒绝原因。拒绝后评价不公开展示。状态流转:PENDING_REVIEW → REJECTED") - @PostMapping("/{reviewId}/reject") - public Result reject(@ApiParam("评价ID") @PathVariable Long reviewId, - @ApiParam("拒绝请求") @Valid @RequestBody RejectRequest body, -@@ -59,7 +59,7 @@ public class AdminReviewController { - return Result.success(); - } - -- @ApiOperation("覆盖通过(机器拒绝的)") -+ @ApiOperation(value = "覆盖通过(机器拒绝的)", notes = "对阿里云内容审核自动拒绝的评价进行人工覆盖通过。状态流转:AUTO_REJECTED → APPROVED") - @PostMapping("/{reviewId}/override-approve") - public Result overrideApprove(@ApiParam("评价ID") @PathVariable Long reviewId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -69,7 +69,8 @@ public class AdminReviewController { - return Result.success(); - } - -- @ApiOperation("回复评价(每条评价仅可回复一次)") -+ @ApiOperation(value = "回复评价(每条评价仅可回复一次)", -+ notes = "管理员回复用户评价,回复内容在小程序端公开展示。每条评价仅允许回复一次,不可修改。\n\n**权限**:需管理员登录。") - @PostMapping("/{reviewId}/reply") - public Result adminReply(@ApiParam("评价ID") @PathVariable Long reviewId, - @ApiParam("回复内容") @Valid @RequestBody AdminReplyRequest body, -``` - -### `hl-review-service/src/main/java/com/hulalv/review/controller/InternalMpReviewController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-review-service/src/main/java/com/hulalv/review/controller/InternalMpReviewController.java b/hl-review-service/src/main/java/com/hulalv/review/controller/InternalMpReviewController.java -index b3dd6a3..62fb7d0 100644 ---- a/hl-review-service/src/main/java/com/hulalv/review/controller/InternalMpReviewController.java -+++ b/hl-review-service/src/main/java/com/hulalv/review/controller/InternalMpReviewController.java -@@ -19,7 +19,7 @@ import javax.validation.Valid; - import java.util.List; - import java.util.Map; - --@Api(tags = "【内部接口】小程序评价(Feign调用)") -+@Api(tags = "【内部接口】小程序评价(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/review") - @RequiredArgsConstructor -@@ -27,7 +27,7 @@ public class InternalMpReviewController { - - private final ReviewService reviewService; - -- @ApiOperation("创建评价(仅针对产品,每个订单仅可评价一次)") -+ @ApiOperation(value = "创建评价(仅针对产品,每个订单仅可评价一次)", notes = "**关联字典**:\n- review_status:评价审核状态(返回字段)\n- rating_level:评价等级(返回字段)") - @PostMapping("/create") - public Result createReview(@Valid @RequestBody CreateReviewRequest body, - HttpServletRequest request) { -@@ -35,13 +35,14 @@ public class InternalMpReviewController { - return Result.success(reviewService.createReview(userId, body)); - } - -- @ApiOperation("检查订单是否已评价") -+ @ApiOperation(value = "检查订单是否已评价", -+ notes = "内部服务间调用。检查指定订单是否已有评价记录,用于小程序端订单详情页控制评价入口的显示。") - @GetMapping("/order/{orderId}/reviewed") - public Result isOrderReviewed(@PathVariable Long orderId) { - return Result.success(reviewService.isOrderReviewed(orderId)); - } - -- @ApiOperation("我的评价列表") -+ @ApiOperation(value = "我的评价列表", notes = "**关联字典**:\n- review_status:评价审核状态(显示)\n- rating_level:评价等级(显示)") - @GetMapping("/my") - public Result> getMyReviews(MpReviewQueryRequest query, - HttpServletRequest request) { -@@ -49,13 +50,13 @@ public class InternalMpReviewController { - return Result.success(reviewService.getMyReviews(userId, query)); - } - -- @ApiOperation("某目标的已通过评价(公开,支持好中差评/有图/有视频筛选)") -+ @ApiOperation(value = "某目标的已通过评价(公开,支持好中差评/有图/有视频筛选)", notes = "**关联字典**:\n- rating_level:评价等级(筛选+显示)") - @GetMapping("/target") - public Result> getTargetReviews(@Valid TargetReviewQueryRequest query) { - return Result.success(reviewService.getTargetReviews(query)); - } - -- @ApiOperation("关键词搜索评价(公开)") -+ @ApiOperation(value = "关键词搜索评价(公开)", notes = "**关联字典**:\n- rating_level:评价等级(显示)") - @GetMapping("/search") - public Result> searchReviews( - @ApiParam("搜索关键词") @RequestParam String keyword, -@@ -66,14 +67,15 @@ public class InternalMpReviewController { - return Result.success(reviewService.searchReviews(keyword, targetType, targetId, page, pageSize)); - } - -- @ApiOperation("首页精选评价") -+ @ApiOperation(value = "首页精选评价", notes = "**关联字典**:\n- rating_level:评价等级(显示)") - @GetMapping("/featured") - public Result> getFeaturedReviews( - @ApiParam("数量限制") @RequestParam(defaultValue = "5") Integer limit) { - return Result.success(reviewService.getFeaturedReviews(limit)); - } - -- @ApiOperation("订单可评价目标列表") -+ @ApiOperation(value = "订单可评价目标列表", -+ notes = "内部服务间调用。返回订单关联的可评价目标(产品、定制师等),用于评价页面选择评价对象。已评价的目标不会重复出现。") - @GetMapping("/order/{orderId}/reviewable-targets") - public Result>> getReviewableTargets( - @PathVariable Long orderId, HttpServletRequest request) { -@@ -81,7 +83,8 @@ public class InternalMpReviewController { - return Result.success(reviewService.getReviewableTargets(orderId, userId)); - } - -- @ApiOperation("点赞/取消点赞评价") -+ @ApiOperation(value = "点赞/取消点赞评价", -+ notes = "内部服务间调用。切换当前用户对评价的点赞状态(toggle),返回最新点赞状态和点赞总数。") - @PostMapping("/{reviewId}/like") - public Result> toggleLike(@PathVariable Long reviewId, - HttpServletRequest request) { -@@ -89,7 +92,8 @@ public class InternalMpReviewController { - return Result.success(reviewService.toggleLike(reviewId, userId)); - } - -- @ApiOperation("检查是否已点赞") -+ @ApiOperation(value = "检查是否已点赞", -+ notes = "内部服务间调用。检查当前用户是否已对指定评价点赞,用于小程序端渲染点赞按钮状态。") - @GetMapping("/{reviewId}/like/check") - public Result checkLiked(@PathVariable Long reviewId, - HttpServletRequest request) { -@@ -97,7 +101,8 @@ public class InternalMpReviewController { - return Result.success(reviewService.checkLiked(reviewId, userId)); - } - -- @ApiOperation("同步评价点赞数(供通用点赞服务回调)") -+ @ApiOperation(value = "同步评价点赞数(供通用点赞服务回调)", -+ notes = "内部服务间调用。通用点赞服务(user-service)发生点赞变化后回调此接口,同步更新评价表的点赞计数字段。") - @PostMapping("/{reviewId}/sync-like-count") - public Result syncLikeCount(@PathVariable Long reviewId, - @RequestParam int likeCount) { -``` - -### `hl-review-service/src/main/java/com/hulalv/review/controller/InternalReviewController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-review-service/src/main/java/com/hulalv/review/controller/InternalReviewController.java b/hl-review-service/src/main/java/com/hulalv/review/controller/InternalReviewController.java -index 0567412..7e5f1cb 100644 ---- a/hl-review-service/src/main/java/com/hulalv/review/controller/InternalReviewController.java -+++ b/hl-review-service/src/main/java/com/hulalv/review/controller/InternalReviewController.java -@@ -21,7 +21,7 @@ import java.util.List; - import java.util.Map; - import java.util.stream.Collectors; - --@Api(tags = "【内部接口】评价统计(Feign调用)") -+@Api(tags = "【内部接口】评价统计(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/review") - @RequiredArgsConstructor -@@ -29,14 +29,14 @@ public class InternalReviewController { - - private final ReviewService reviewService; - -- @ApiOperation("目标评价统计(平均分,数量)") -+ @ApiOperation(value = "目标评价统计(平均分,数量)", notes = "**关联字典**:\n- rating_level:评价等级(统计维度)") - @GetMapping("/target-stats") - public Result getTargetStats(@RequestParam String targetType, - @RequestParam Long targetId) { - return Result.success(reviewService.getTargetStats(targetType, targetId)); - } - -- @ApiOperation("目标已通过评价列表") -+ @ApiOperation(value = "目标已通过评价列表", notes = "**关联字典**:\n- rating_level:评价等级(显示)") - @GetMapping("/target-list") - public Result> getTargetReviews( - @RequestParam String targetType, -@@ -46,7 +46,7 @@ public class InternalReviewController { - return Result.success(reviewService.getTargetReviewsInternal(targetType, targetId, page, pageSize)); - } - -- @ApiOperation("批量目标评价统计(聚合多个targetId)") -+ @ApiOperation(value = "批量目标评价统计(聚合多个targetId)", notes = "**关联字典**:\n- rating_level:评价等级(统计维度)") - @GetMapping("/stats-by-targets") - public Result getStatsByTargetIds( - @RequestParam String targetType, -@@ -55,7 +55,7 @@ public class InternalReviewController { - return Result.success(reviewService.getStatsByTargetIds(targetType, ids)); - } - -- @ApiOperation("批量目标已通过评价列表(聚合多个targetId)") -+ @ApiOperation(value = "批量目标已通过评价列表(聚合多个targetId)", notes = "**关联字典**:\n- rating_level:评价等级(显示)") - @GetMapping("/reviews-by-targets") - public Result> getReviewsByTargetIds( - @RequestParam String targetType, -@@ -66,13 +66,13 @@ public class InternalReviewController { - return Result.success(reviewService.getReviewsByTargetIds(targetType, ids, page, pageSize)); - } - -- @ApiOperation("产品精选评价(最高评分+最高点赞+统计)") -+ @ApiOperation(value = "产品精选评价(最高评分+最高点赞+统计)", notes = "**关联字典**:\n- rating_level:评价等级(显示)") - @GetMapping("/product-highlights") - public Result> getProductHighlights(@RequestParam Long productId) { - return Result.success(reviewService.getProductHighlightReviews(productId)); - } - -- @ApiOperation("定制师已通过评价列表") -+ @ApiOperation(value = "定制师已通过评价列表", notes = "**关联字典**:\n- rating_level:评价等级(筛选+显示)") - @GetMapping("/customizer-reviews") - public Result> getCustomizerReviews( - @RequestParam Long customizerId, -@@ -82,7 +82,8 @@ public class InternalReviewController { - return Result.success(reviewService.getCustomizerReviews(customizerId, page, pageSize, ratingLevel)); - } - -- @ApiOperation("定制师评价统计(总数/平均分/好评率)") -+ @ApiOperation(value = "定制师评价统计(总数/平均分/好评率)", -+ notes = "内部服务间调用。返回指定定制师的评价汇总统计:总评价数、平均评分、好评率等。用于定制师主页展示服务评价。") - @GetMapping("/customizer-review-stats") - public Result> getCustomizerReviewStats( - @RequestParam Long customizerId) { -``` - -### `hl-task-service/src/main/java/com/hulalv/task/controller/BoardController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-task-service/src/main/java/com/hulalv/task/controller/BoardController.java b/hl-task-service/src/main/java/com/hulalv/task/controller/BoardController.java -index 75b6a7a..0629ed1 100644 ---- a/hl-task-service/src/main/java/com/hulalv/task/controller/BoardController.java -+++ b/hl-task-service/src/main/java/com/hulalv/task/controller/BoardController.java -@@ -33,7 +33,7 @@ public class BoardController { - - // ======================= Board CRUD ======================= - -- @ApiOperation("获取可见看板列表") -+ @ApiOperation(value = "获取可见看板列表", notes = "返回当前管理员可见的看板列表:超级管理员可见所有看板,普通管理员仅可见自己创建的或作为成员的看板") - @GetMapping("/boards") - public Result> getBoards(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -41,7 +41,7 @@ public class BoardController { - return Result.success(boardService.getVisibleBoards(adminId, role)); - } - -- @ApiOperation("看板详情") -+ @ApiOperation(value = "看板详情", notes = "返回看板基本信息(名称、描述、创建者),不含任务数据。查看任务请使用「获取看板任务」接口") - @GetMapping("/board/{boardId}") - public Result getBoardDetail(@ApiParam("看板ID") @PathVariable Long boardId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -49,7 +49,8 @@ public class BoardController { - return Result.success(boardService.getBoardDetail(boardId, adminId, role)); - } - -- @ApiOperation("创建自定义看板") -+ @ApiOperation(value = "创建自定义看板", -+ notes = "创建自定义看板,自动添加创建者为看板成员,并创建默认状态列(待办、进行中、已完成)。\n\n**权限**:需管理员登录。") - @OperationLog(value = "创建看板", module = "任务看板") - @PostMapping("/board") - public Result createBoard(@ApiParam("创建看板请求") @Valid @RequestBody CreateBoardRequest req, HttpServletRequest request) { -@@ -57,7 +58,8 @@ public class BoardController { - return Result.success(boardService.createBoard(req, adminId)); - } - -- @ApiOperation("更新看板") -+ @ApiOperation(value = "更新看板", -+ notes = "更新看板的名称和描述。仅看板创建者或超级管理员可操作。\n\n**权限**:需管理员登录,且为看板创建者或超级管理员。") - @OperationLog(value = "编辑看板", module = "任务看板") - @PutMapping("/board/{boardId}") - public Result updateBoard(@ApiParam("看板ID") @PathVariable Long boardId, -@@ -68,7 +70,7 @@ public class BoardController { - return Result.success(boardService.updateBoard(boardId, req, adminId, role)); - } - -- @ApiOperation("删除看板") -+ @ApiOperation(value = "删除看板", notes = "删除看板及其下所有状态列和任务(级联删除)。仅看板创建者或超级管理员可操作") - @OperationLog(value = "删除看板", module = "任务看板") - @DeleteMapping("/board/{boardId}") - public Result deleteBoard(@ApiParam("看板ID") @PathVariable Long boardId, HttpServletRequest request) { -@@ -80,13 +82,14 @@ public class BoardController { - - // ======================= Status columns ======================= - -- @ApiOperation("获取看板状态列") -+ @ApiOperation(value = "获取看板状态列", notes = "返回看板的所有状态列(如待办、进行中、已完成),按排序字段升序排列。拖拽任务到不同状态列实现状态流转") - @GetMapping("/board/{boardId}/statuses") - public Result> getStatuses(@ApiParam("看板ID") @PathVariable Long boardId) { - return Result.success(boardStatusService.getStatuses(boardId)); - } - -- @ApiOperation("创建状态列") -+ @ApiOperation(value = "创建状态列", -+ notes = "在看板中创建新的状态列(如测试中、待发布等),自动排到末尾。任务通过拖拽在不同状态列间流转。\n\n**权限**:需管理员登录且为看板成员。") - @OperationLog(value = "新增状态列", module = "任务看板") - @PostMapping("/board/{boardId}/status") - public Result createStatus(@ApiParam("看板ID") @PathVariable Long boardId, -@@ -97,7 +100,8 @@ public class BoardController { - return Result.success(boardStatusService.createStatus(boardId, req, adminId, role)); - } - -- @ApiOperation("更新状态列") -+ @ApiOperation(value = "更新状态列", -+ notes = "更新状态列的名称和颜色。\n\n**权限**:需管理员登录且为看板成员。") - @OperationLog(value = "编辑状态列", module = "任务看板") - @PutMapping("/status/{statusId}") - public Result updateStatus(@ApiParam("状态列ID") @PathVariable Long statusId, -@@ -108,7 +112,7 @@ public class BoardController { - return Result.success(boardStatusService.updateStatus(statusId, req, adminId, role)); - } - -- @ApiOperation("删除状态列") -+ @ApiOperation(value = "删除状态列", notes = "删除看板的状态列。如果状态列下有任务则不允许删除,需先移动或删除任务") - @OperationLog(value = "删除状态列", module = "任务看板") - @DeleteMapping("/status/{statusId}") - public Result deleteStatus(@ApiParam("状态列ID") @PathVariable Long statusId, -@@ -119,7 +123,7 @@ public class BoardController { - return Result.success(); - } - -- @ApiOperation("状态列排序") -+ @ApiOperation(value = "状态列排序", notes = "批量更新状态列的排序顺序。传入状态列ID数组,数组下标即为新的排序值。操作完成后通过WebSocket推送STATUS_REORDERED事件") - @PutMapping("/board/{boardId}/status/sort") - public Result sortStatuses(@ApiParam("看板ID") @PathVariable Long boardId, - @ApiParam("状态列排序请求") @Valid @RequestBody StatusSortRequest req, -@@ -133,13 +137,14 @@ public class BoardController { - - // ======================= Board Members ======================= - -- @ApiOperation("获取看板成员") -+ @ApiOperation(value = "获取看板成员", notes = "返回看板的所有成员列表,包含成员的管理员ID和姓名") - @GetMapping("/board/{boardId}/members") - public Result> getMembers(@ApiParam("看板ID") @PathVariable Long boardId) { - return Result.success(boardMemberService.getMembers(boardId)); - } - -- @ApiOperation("添加成员") -+ @ApiOperation(value = "添加成员", -+ notes = "批量添加管理员为看板成员,成为成员后可以查看看板、创建和操作任务。\n\n**权限**:需管理员登录,且为看板创建者或超级管理员。") - @OperationLog(value = "添加看板成员", module = "任务看板") - @PostMapping("/board/{boardId}/members") - public Result addMembers(@ApiParam("看板ID") @PathVariable Long boardId, -@@ -151,7 +156,7 @@ public class BoardController { - return Result.success(); - } - -- @ApiOperation("移除成员") -+ @ApiOperation(value = "移除成员", notes = "从看板中移除指定成员。仅看板创建者或超级管理员可操作,不能移除创建者自己") - @OperationLog(value = "移除看板成员", module = "任务看板") - @DeleteMapping("/board/{boardId}/member/{targetAdminId}") - public Result removeMember(@ApiParam("看板ID") @PathVariable Long boardId, -``` - -### `hl-task-service/src/main/java/com/hulalv/task/controller/TaskController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-task-service/src/main/java/com/hulalv/task/controller/TaskController.java b/hl-task-service/src/main/java/com/hulalv/task/controller/TaskController.java -index 8593e4d..c85aeca 100644 ---- a/hl-task-service/src/main/java/com/hulalv/task/controller/TaskController.java -+++ b/hl-task-service/src/main/java/com/hulalv/task/controller/TaskController.java -@@ -31,7 +31,7 @@ public class TaskController { - - // ======================= Tasks ======================= - -- @ApiOperation("获取看板任务(按状态分组)") -+ @ApiOperation(value = "获取看板任务(按状态分组)", notes = "返回看板下所有任务,按状态列分组。支持按优先级(HIGH/MEDIUM/LOW)和负责人筛选,每组内按排序值升序排列\n\n**关联字典**:\n- task_priority:任务优先级(列表筛选+显示)") - @GetMapping("/board/{boardId}/tasks") - public Result> getBoardTasks(@ApiParam("看板ID") @PathVariable Long boardId, - @ApiParam("优先级") @RequestParam(required = false) String priority, -@@ -42,7 +42,7 @@ public class TaskController { - return Result.success(taskService.getBoardTasks(boardId, adminId, role, priority, assigneeId)); - } - -- @ApiOperation("任务详情") -+ @ApiOperation(value = "任务详情", notes = "返回任务完整信息,包含子任务列表、负责人信息、附件列表等\n\n**关联字典**:\n- task_priority:任务优先级(显示)") - @GetMapping("/{taskId}") - public Result getTaskDetail(@ApiParam("任务ID") @PathVariable Long taskId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -50,7 +50,7 @@ public class TaskController { - return Result.success(taskService.getTaskDetail(taskId, adminId, role)); - } - -- @ApiOperation("创建任务") -+ @ApiOperation(value = "创建任务", notes = "在指定看板和状态列下创建任务。创建成功后通过WebSocket推送TASK_CREATED事件,并通知被分配的负责人\n\n**关联字典**:\n- task_priority:任务优先级(创建时选择)") - @OperationLog(value = "创建任务", module = "任务看板") - @PostMapping - public Result createTask(@ApiParam("创建任务请求") @Valid @RequestBody CreateTaskRequest req, HttpServletRequest request) { -@@ -62,7 +62,8 @@ public class TaskController { - return Result.success(vo); - } - -- @ApiOperation("更新任务") -+ @ApiOperation(value = "更新任务", -+ notes = "更新任务的标题、描述、优先级、截止日期、负责人等信息。更新后通过WebSocket推送TASK_UPDATED事件,如果修改了负责人则额外通知新负责人。\n\n**权限**:需管理员登录且为看板成员。\n\n**关联字典**:\n- task_priority:任务优先级(编辑时选择)") - @OperationLog(value = "编辑任务", module = "任务看板") - @PutMapping("/{taskId}") - public Result updateTask(@ApiParam("任务ID") @PathVariable Long taskId, -@@ -78,7 +79,7 @@ public class TaskController { - return Result.success(vo); - } - -- @ApiOperation("变更任务状态") -+ @ApiOperation(value = "变更任务状态", notes = "将任务移动到指定状态列(拖拽操作),自动记录状态变更到时间线,并通过WebSocket推送TASK_STATUS_CHANGED事件") - @PutMapping("/{taskId}/status") - public Result changeStatus(@ApiParam("任务ID") @PathVariable Long taskId, - @ApiParam("变更状态请求") @Valid @RequestBody ChangeStatusRequest req, -@@ -91,7 +92,7 @@ public class TaskController { - return Result.success(); - } - -- @ApiOperation("任务排序") -+ @ApiOperation(value = "任务排序", notes = "更新任务在同一状态列内的排序位置,用于拖拽排序") - @PutMapping("/{taskId}/sort") - public Result sortTasks(@ApiParam("任务ID") @PathVariable Long taskId, - @ApiParam("任务排序请求") @Valid @RequestBody TaskSortRequest req, -@@ -102,7 +103,8 @@ public class TaskController { - return Result.success(); - } - -- @ApiOperation("删除任务") -+ @ApiOperation(value = "删除任务", -+ notes = "删除任务及其所有子任务、评论和时间线记录(级联删除)。删除后通过WebSocket推送TASK_DELETED事件。\n\n**权限**:需管理员登录且为看板成员。") - @OperationLog(value = "删除任务", module = "任务看板") - @DeleteMapping("/{taskId}") - public Result deleteTask(@ApiParam("任务ID") @PathVariable Long taskId, HttpServletRequest request) { -@@ -117,7 +119,8 @@ public class TaskController { - - // ======================= Subtasks ======================= - -- @ApiOperation("创建子任务") -+ @ApiOperation(value = "创建子任务", -+ notes = "在指定任务下创建子任务(待办项),用于拆分任务的执行步骤。子任务默认为未完成状态。\n\n**权限**:需管理员登录且为看板成员。") - @PostMapping("/{taskId}/subtask") - public Result createSubtask(@ApiParam("任务ID") @PathVariable Long taskId, - @ApiParam("创建子任务请求") @Valid @RequestBody CreateSubtaskRequest req, -@@ -128,7 +131,7 @@ public class TaskController { - return Result.success(vo); - } - -- @ApiOperation("切换子任务完成状态") -+ @ApiOperation(value = "切换子任务完成状态", notes = "切换子任务的完成/未完成状态(toggle),完成状态切换会自动记录到任务时间线") - @PutMapping("/subtask/{subtaskId}/toggle") - public Result toggleSubtask(@ApiParam("子任务ID") @PathVariable Long subtaskId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -137,7 +140,8 @@ public class TaskController { - return Result.success(); - } - -- @ApiOperation("删除子任务") -+ @ApiOperation(value = "删除子任务", -+ notes = "删除指定子任务。\n\n**权限**:需管理员登录且为看板成员。") - @DeleteMapping("/subtask/{subtaskId}") - public Result deleteSubtask(@ApiParam("子任务ID") @PathVariable Long subtaskId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -148,7 +152,7 @@ public class TaskController { - - // ======================= Timeline (comments + activities) ======================= - -- @ApiOperation("获取任务时间线") -+ @ApiOperation(value = "获取任务时间线", notes = "返回任务的完整操作记录,包含评论和系统自动记录的状态变更、人员分配等活动,按时间正序排列") - @GetMapping("/{taskId}/timeline") - public Result> getTimeline(@ApiParam("任务ID") @PathVariable Long taskId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -156,7 +160,7 @@ public class TaskController { - return Result.success(commentService.getTimeline(taskId, adminId, role)); - } - -- @ApiOperation("添加评论") -+ @ApiOperation(value = "添加评论", notes = "在任务时间线中添加评论,添加后自动通知任务负责人") - @PostMapping("/{taskId}/comment") - public Result addComment(@ApiParam("任务ID") @PathVariable Long taskId, - @ApiParam("创建评论请求") @Valid @RequestBody CreateCommentRequest req, -@@ -168,7 +172,7 @@ public class TaskController { - return Result.success(item); - } - -- @ApiOperation("删除评论") -+ @ApiOperation(value = "删除评论", notes = "仅评论作者本人可删除自己的评论,系统自动生成的活动记录不可删除") - @DeleteMapping("/comment/{commentId}") - public Result deleteComment(@ApiParam("评论ID") @PathVariable Long commentId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminAgreementController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminAgreementController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminAgreementController.java -index 10fe201..c012fce 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminAgreementController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminAgreementController.java -@@ -22,7 +22,9 @@ public class AdminAgreementController { - - private final AgreementService agreementService; - -- @ApiOperation("协议列表") -+ @ApiOperation(value = "协议列表", notes = "分页查询用户协议列表,支持按关键词和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):请求参数status和返回字段status(0=禁用, 1=启用)") - @GetMapping - public Result> listAgreements( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -32,20 +34,30 @@ public class AdminAgreementController { - return Result.success(agreementService.listAgreements(page, pageSize, keyword, status)); - } - -- @ApiOperation("协议详情") -+ @ApiOperation(value = "协议详情", -+ notes = "获取指定用户协议的详细信息,包括标题、内容(富文本)、版本号等。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- common_status(通用状态):返回字段status(0=禁用, 1=启用)") - @GetMapping("/{id}") - public Result getAgreement(@ApiParam("协议ID") @PathVariable Long id) { - return Result.success(agreementService.getAgreement(id)); - } - -- @ApiOperation("新增协议") -+ @ApiOperation(value = "新增协议", -+ notes = "创建新的用户协议,如用户服务协议、隐私政策等。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:协议类型(type)需唯一,同一类型不能重复创建。内容支持富文本。") - @OperationLog(value = "新增协议", module = "用户协议管理") - @PostMapping - public Result createAgreement(@Valid @RequestBody AgreementRequest request) { - return Result.success(agreementService.createAgreement(request)); - } - -- @ApiOperation("编辑协议") -+ @ApiOperation(value = "编辑协议", -+ notes = "更新指定用户协议的标题、内容、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:修改后小程序端会实时展示新内容。") - @OperationLog(value = "编辑协议", module = "用户协议管理") - @PutMapping("/{id}") - public Result updateAgreement(@ApiParam("协议ID") @PathVariable Long id, -@@ -53,7 +65,10 @@ public class AdminAgreementController { - return Result.success(agreementService.updateAgreement(id, request)); - } - -- @ApiOperation("删除协议") -+ @ApiOperation(value = "删除协议", -+ notes = "删除指定的用户协议记录(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序端将无法查看该协议。") - @OperationLog(value = "删除协议", module = "用户协议管理") - @DeleteMapping("/{id}") - public Result deleteAgreement(@ApiParam("协议ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminBannerController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminBannerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminBannerController.java -index 5c47fa0..eec06ab 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminBannerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminBannerController.java -@@ -23,7 +23,9 @@ public class AdminBannerController { - - private final BannerService bannerService; - -- @ApiOperation("Banner列表") -+ @ApiOperation(value = "Banner列表", notes = "分页查询Banner列表,支持按关键词和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):请求参数status和返回字段status(0=禁用, 1=启用)") - @GetMapping - public Result> listBanners( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -34,13 +36,20 @@ public class AdminBannerController { - return Result.success(result); - } - -- @ApiOperation("Banner详情") -+ @ApiOperation(value = "Banner详情", -+ notes = "获取指定Banner的详细信息,包括标题、图片、跳转链接、排序等。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- common_status(通用状态):返回字段status(0=禁用, 1=启用)") - @GetMapping("/{id}") - public Result getBanner(@ApiParam("轮播图ID") @PathVariable Long id) { - return Result.success(bannerService.getBanner(id)); - } - -- @ApiOperation("创建Banner") -+ @ApiOperation(value = "创建Banner", -+ notes = "创建新的首页轮播图,包括标题、封面图、跳转链接、排序等。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:创建后默认为启用状态,小程序端将按排序展示。") - @OperationLog(value = "创建Banner", module = "Banner管理") - @PostMapping - public Result createBanner(@ApiParam("轮播图创建请求") @Valid @RequestBody BannerRequest request, -@@ -49,7 +58,9 @@ public class AdminBannerController { - return Result.success(bannerService.createBanner(request, adminId)); - } - -- @ApiOperation("更新Banner") -+ @ApiOperation(value = "更新Banner", -+ notes = "更新指定Banner的标题、封面图、跳转链接、排序、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "更新Banner", module = "Banner管理") - @PutMapping("/{id}") - public Result updateBanner(@ApiParam("轮播图ID") @PathVariable Long id, -@@ -57,7 +68,10 @@ public class AdminBannerController { - return Result.success(bannerService.updateBanner(id, request)); - } - -- @ApiOperation("删除Banner") -+ @ApiOperation(value = "删除Banner", -+ notes = "删除指定的Banner记录(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序首页将不再展示该Banner。") - @OperationLog(value = "删除Banner", module = "Banner管理") - @DeleteMapping("/{id}") - public Result deleteBanner(@ApiParam("轮播图ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminContactController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminContactController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminContactController.java -index 6080439..786b6ad 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminContactController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminContactController.java -@@ -22,7 +22,10 @@ public class AdminContactController { - - private final ContactService contactService; - -- @ApiOperation("联系方式列表") -+ @ApiOperation(value = "联系方式列表", notes = "分页查询联系方式列表,支持按关键词和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- contact_channel_type(联系渠道类型):返回字段channelType(PHONE=电话, WECHAT=微信, EMAIL=邮箱等)\n" -+ + "- common_status(通用状态):请求参数status和返回字段status") - @GetMapping - public Result> listContacts( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -33,20 +36,27 @@ public class AdminContactController { - return Result.success(result); - } - -- @ApiOperation("联系方式详情") -+ @ApiOperation(value = "联系方式详情", notes = "获取指定联系方式的详细信息。" -+ + "\n\n**关联字典**:\n" -+ + "- contact_channel_type(联系渠道类型):返回字段channelType\n" -+ + "- common_status(通用状态):返回字段status") - @GetMapping("/{id}") - public Result getContact(@ApiParam("联系方式ID") @PathVariable Long id) { - return Result.success(contactService.getContact(id)); - } - -- @ApiOperation("创建联系方式") -+ @ApiOperation(value = "创建联系方式", notes = "新增一条联系方式记录。" -+ + "\n\n**关联字典**:\n" -+ + "- contact_channel_type(联系渠道类型):请求字段channelType") - @OperationLog(value = "创建联系方式", module = "联系我们管理") - @PostMapping - public Result createContact(@ApiParam("联系方式创建请求") @Valid @RequestBody ContactRequest request) { - return Result.success(contactService.createContact(request)); - } - -- @ApiOperation("更新联系方式") -+ @ApiOperation(value = "更新联系方式", notes = "更新指定联系方式记录。" -+ + "\n\n**关联字典**:\n" -+ + "- contact_channel_type(联系渠道类型):请求字段channelType") - @OperationLog(value = "更新联系方式", module = "联系我们管理") - @PutMapping("/{id}") - public Result updateContact(@ApiParam("联系方式ID") @PathVariable Long id, -@@ -54,7 +64,10 @@ public class AdminContactController { - return Result.success(contactService.updateContact(id, request)); - } - -- @ApiOperation("删除联系方式") -+ @ApiOperation(value = "删除联系方式", -+ notes = "删除指定的联系方式记录(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序端将不再展示该联系方式。") - @OperationLog(value = "删除联系方式", module = "联系我们管理") - @DeleteMapping("/{id}") - public Result deleteContact(@ApiParam("联系方式ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminCustomerController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminCustomerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminCustomerController.java -index 23ad20d..b5b5983 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminCustomerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminCustomerController.java -@@ -19,7 +19,14 @@ public class AdminCustomerController { - - private final UserService userService; - -- @ApiOperation("客户列表") -+ @ApiOperation(value = "客户列表", notes = "分页查询小程序注册的C端用户(客户)列表。" -+ + "支持按昵称/手机号/真实姓名关键词搜索,按状态筛选。" -+ + "status取值:ACTIVE=正常 BANNED=已封禁。" -+ + "需要管理员认证。" -+ + "\n\n**关联字典**:\n" -+ + "- user_status(用户状态):请求参数status和返回字段status(ACTIVE=正常, BANNED=已封禁)\n" -+ + "- gender(性别):返回字段gender(0=女, 1=男)\n" -+ + "- id_card_type(证件类型):返回字段idCardType") - @GetMapping - public Result> listCustomers( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -30,14 +37,21 @@ public class AdminCustomerController { - return Result.success(result); - } - -- @ApiOperation("客户详情") -+ @ApiOperation(value = "客户详情", notes = "获取指定客户的详细信息。" -+ + "\n\n**关联字典**:\n" -+ + "- user_status(用户状态):返回字段status\n" -+ + "- gender(性别):返回字段gender\n" -+ + "- id_card_type(证件类型):返回字段idCardType") - @GetMapping("/{userId}") - public Result getCustomer(@ApiParam("用户ID") @PathVariable Long userId) { - CustomerVO customer = userService.getCustomerDetail(userId); - return Result.success(customer); - } - -- @ApiOperation("封禁客户") -+ @ApiOperation(value = "封禁客户", notes = "封禁指定的C端用户,状态变为BANNED。" -+ + "封禁后该用户无法登录小程序,已有的Token将失效。" -+ + "封禁操作不会删除用户数据,可通过[解封客户]接口恢复。" -+ + "需要管理员认证。") - @OperationLog(value = "封禁客户", module = "客户管理") - @PostMapping("/{userId}/ban") - public Result banCustomer(@ApiParam("用户ID") @PathVariable Long userId) { -@@ -45,7 +59,9 @@ public class AdminCustomerController { - return Result.success(); - } - -- @ApiOperation("解封客户") -+ @ApiOperation(value = "解封客户", notes = "解封已封禁的C端用户,状态恢复为ACTIVE。" -+ + "解封后用户可正常登录小程序。" -+ + "需要管理员认证。") - @OperationLog(value = "解封客户", module = "客户管理") - @PostMapping("/{userId}/unban") - public Result unbanCustomer(@ApiParam("用户ID") @PathVariable Long userId) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminDesignerController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminDesignerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminDesignerController.java -index 5dfa05d..c76c659 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminDesignerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminDesignerController.java -@@ -30,14 +30,18 @@ public class AdminDesignerController { - private final DesignerProfileService designerProfileService; - private final DesignerDashboardService designerDashboardService; - -- @ApiOperation("获取我的个人资料(已废弃,请使用 /admin/profile/me)") -+ @ApiOperation(value = "获取我的个人资料(已废弃,请使用 /admin/profile/me)", notes = "已废弃接口。" -+ + "\n\n**关联字典**:\n" -+ + "- designer_cert_level(认证等级):返回字段certLevel(none/bronze/silver/gold/diamond)") - @GetMapping("/profile") - public Result getMyProfile(HttpServletRequest request) { - Long adminId = getAdminId(request); - return Result.success(designerProfileService.getMyProfile(adminId)); - } - -- @ApiOperation("更新我的个人资料(已废弃,请使用 PUT /admin/profile/me)") -+ @ApiOperation(value = "更新我的个人资料(已废弃,请使用 PUT /admin/profile/me)", -+ notes = "已废弃接口,请迁移至 PUT /admin/profile/me。\n\n" -+ + "**权限**:需要管理员登录。") - @PutMapping("/profile") - public Result updateMyProfile(HttpServletRequest request, - @Valid @RequestBody UpdateDesignerProfileRequest body) { -@@ -45,14 +49,18 @@ public class AdminDesignerController { - return Result.success(designerProfileService.updateMyProfile(adminId, body)); - } - -- @ApiOperation("工作台概览(已废弃,请使用 /admin/profile/dashboard)") -+ @ApiOperation(value = "工作台概览(已废弃,请使用 /admin/profile/dashboard)", -+ notes = "已废弃接口,请迁移至 GET /admin/profile/dashboard。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/dashboard") - public Result getDashboard(HttpServletRequest request) { - Long adminId = getAdminId(request); - return Result.success(designerDashboardService.getDashboard(adminId, "today")); - } - -- @ApiOperation("我的订单列表(已废弃,请使用 /admin/profile/orders)") -+ @ApiOperation(value = "我的订单列表(已废弃,请使用 /admin/profile/orders)", notes = "已废弃接口。" -+ + "\n\n**关联字典**:\n" -+ + "- order_status(订单状态):请求参数status和返回字段status") - @GetMapping("/orders") - public Result>> getMyOrders( - HttpServletRequest request, -@@ -64,7 +72,9 @@ public class AdminDesignerController { - return Result.success(designerDashboardService.getMyOrders(adminId, page, pageSize, status, keyword)); - } - -- @ApiOperation("我的产品列表(已废弃,请使用 /admin/profile/products)") -+ @ApiOperation(value = "我的产品列表(已废弃,请使用 /admin/profile/products)", notes = "已废弃接口。" -+ + "\n\n**关联字典**:\n" -+ + "- product_status(产品状态):请求参数status和返回字段status") - @GetMapping("/products") - public Result>> getMyProducts( - HttpServletRequest request, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminExploreCategoryController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminExploreCategoryController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminExploreCategoryController.java -index ebe2d88..f6fe95a 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminExploreCategoryController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminExploreCategoryController.java -@@ -24,7 +24,9 @@ public class AdminExploreCategoryController { - - private final ExploreCategoryService exploreCategoryService; - -- @ApiOperation("探索分类列表") -+ @ApiOperation(value = "探索分类列表", notes = "分页查询探索分类列表,支持按关键词和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):请求参数status和返回字段status(0=禁用, 1=启用)") - @GetMapping - public Result> listCategories( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -35,13 +37,20 @@ public class AdminExploreCategoryController { - return Result.success(result); - } - -- @ApiOperation("探索分类详情") -+ @ApiOperation(value = "探索分类详情", -+ notes = "获取指定探索分类的详细信息,包括标题、封面图、描述、关联的景区资源列表等。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- common_status(通用状态):返回字段status(0=禁用, 1=启用)") - @GetMapping("/{id}") - public Result getCategory(@ApiParam("分类ID") @PathVariable Long id) { - return Result.success(exploreCategoryService.getCategory(id)); - } - -- @ApiOperation("创建探索分类") -+ @ApiOperation(value = "创建探索分类", -+ notes = "创建新的探索分类,用于小程序探索页面的分类展示。\n" -+ + "可关联多个景区资源,设置封面图和描述文字。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "创建探索分类", module = "探索管理") - @PostMapping - public Result createCategory(@ApiParam("分类创建请求") @Valid @RequestBody ExploreCategoryRequest request, -@@ -51,7 +60,9 @@ public class AdminExploreCategoryController { - return Result.success(); - } - -- @ApiOperation("更新探索分类") -+ @ApiOperation(value = "更新探索分类", -+ notes = "更新指定探索分类的标题、封面图、描述、关联资源、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "更新探索分类", module = "探索管理") - @PutMapping("/{id}") - public Result updateCategory(@ApiParam("分类ID") @PathVariable Long id, -@@ -60,7 +71,10 @@ public class AdminExploreCategoryController { - return Result.success(); - } - -- @ApiOperation("删除探索分类") -+ @ApiOperation(value = "删除探索分类", -+ notes = "删除指定的探索分类(软删除),同时清除关联的资源绑定关系。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序探索页面将不再展示该分类。") - @OperationLog(value = "删除探索分类", module = "探索管理") - @DeleteMapping("/{id}") - public Result deleteCategory(@ApiParam("分类ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminFaqController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFaqController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFaqController.java -index 61a2dbb..11e1fdd 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFaqController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFaqController.java -@@ -26,20 +26,28 @@ public class AdminFaqController { - - // ==================== 分类 ==================== - -- @ApiOperation("分类列表") -+ @ApiOperation(value = "分类列表", -+ notes = "获取所有FAQ分类的完整列表(不分页)。\n" -+ + "每个分类包含名称、排序号、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/categories") - public Result> listCategories() { - return Result.success(faqService.listCategories()); - } - -- @ApiOperation("创建分类") -+ @ApiOperation(value = "创建分类", -+ notes = "创建新的FAQ分类,用于对常见问题进行归类。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:分类名称不能重复。") - @OperationLog(value = "创建FAQ分类", module = "常见问题管理") - @PostMapping("/categories") - public Result createCategory(@Valid @RequestBody FaqCategoryRequest request) { - return Result.success(faqService.createCategory(request)); - } - -- @ApiOperation("更新分类") -+ @ApiOperation(value = "更新分类", -+ notes = "更新指定FAQ分类的名称、排序号、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "更新FAQ分类", module = "常见问题管理") - @PutMapping("/categories/{id}") - public Result updateCategory(@ApiParam("分类ID") @PathVariable Long id, -@@ -47,7 +55,10 @@ public class AdminFaqController { - return Result.success(faqService.updateCategory(id, request)); - } - -- @ApiOperation("删除分类") -+ @ApiOperation(value = "删除分类", -+ notes = "删除指定的FAQ分类(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除分类不会删除其下的条目,但条目将变为无分类状态。") - @OperationLog(value = "删除FAQ分类", module = "常见问题管理") - @DeleteMapping("/categories/{id}") - public Result deleteCategory(@ApiParam("分类ID") @PathVariable Long id) { -@@ -57,21 +68,29 @@ public class AdminFaqController { - - // ==================== 条目 ==================== - -- @ApiOperation("条目列表") -+ @ApiOperation(value = "条目列表", -+ notes = "查询FAQ条目列表,支持按分类ID筛选。\n" -+ + "返回问题标题、回答内容(富文本)、排序号等。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/items") - public Result> listItems( - @ApiParam("分类ID(可选)") @RequestParam(required = false) Long categoryId) { - return Result.success(faqService.listItems(categoryId)); - } - -- @ApiOperation("创建条目") -+ @ApiOperation(value = "创建条目", -+ notes = "创建一条常见问题,包含问题标题和回答(支持富文本)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:需指定所属分类ID,排序号越小越靠前。") - @OperationLog(value = "创建FAQ条目", module = "常见问题管理") - @PostMapping("/items") - public Result createItem(@Valid @RequestBody FaqItemRequest request) { - return Result.success(faqService.createItem(request)); - } - -- @ApiOperation("更新条目") -+ @ApiOperation(value = "更新条目", -+ notes = "更新指定FAQ条目的问题标题、回答内容、排序号等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "更新FAQ条目", module = "常见问题管理") - @PutMapping("/items/{id}") - public Result updateItem(@ApiParam("条目ID") @PathVariable Long id, -@@ -79,7 +98,10 @@ public class AdminFaqController { - return Result.success(faqService.updateItem(id, request)); - } - -- @ApiOperation("删除条目") -+ @ApiOperation(value = "删除条目", -+ notes = "删除指定的FAQ条目(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序FAQ页面将不再展示该条目。") - @OperationLog(value = "删除FAQ条目", module = "常见问题管理") - @DeleteMapping("/items/{id}") - public Result deleteItem(@ApiParam("条目ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminFrontendConfigController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFrontendConfigController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFrontendConfigController.java -index e81218e..5f5117b 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFrontendConfigController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFrontendConfigController.java -@@ -24,7 +24,9 @@ public class AdminFrontendConfigController { - - private final FrontendConfigService frontendConfigService; - -- @ApiOperation("配置列表") -+ @ApiOperation(value = "配置列表", notes = "分页查询前端配置列表,支持按关键词、分组和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):请求参数status和返回字段status(0=禁用, 1=启用)") - @GetMapping - public Result> listConfigs( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -35,7 +37,10 @@ public class AdminFrontendConfigController { - return Result.success(frontendConfigService.listConfigs(page, pageSize, keyword, configGroup, status)); - } - -- @ApiOperation("配置列表(不分页)") -+ @ApiOperation(value = "配置列表(不分页)", -+ notes = "获取所有前端配置项的完整列表(不分页),支持按分组和状态筛选。\n" -+ + "适用于需要一次性加载全部配置的场景。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/all") - public Result> listAllConfigs( - @ApiParam("配置分组") @RequestParam(required = false) String configGroup, -@@ -43,25 +48,37 @@ public class AdminFrontendConfigController { - return Result.success(frontendConfigService.listAllConfigs(configGroup, status)); - } - -- @ApiOperation("配置详情") -+ @ApiOperation(value = "配置详情", -+ notes = "根据配置ID获取指定前端配置项的详细信息,包括key、value、分组、描述等。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/{id}") - public Result getConfig(@ApiParam("配置ID") @PathVariable Long id) { - return Result.success(frontendConfigService.getConfig(id)); - } - -- @ApiOperation("按key查询配置") -+ @ApiOperation(value = "按key查询配置", -+ notes = "根据配置键(configKey)获取指定的前端配置项。\n" -+ + "configKey为全局唯一标识,如 app_name、primary_color 等。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/by-key/{key}") - public Result getConfigByKey(@ApiParam("配置键") @PathVariable String key) { - return Result.success(frontendConfigService.getConfigByKey(key)); - } - -- @ApiOperation("获取所有分组") -+ @ApiOperation(value = "获取所有分组", -+ notes = "获取前端配置中所有已使用的分组名称列表。\n" -+ + "用于配置管理页面的分组筛选下拉框。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/groups") - public Result> listGroups() { - return Result.success(frontendConfigService.listGroups()); - } - -- @ApiOperation("创建配置") -+ @ApiOperation(value = "创建配置", -+ notes = "创建新的前端配置项,用于控制前端页面的展示和行为。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:configKey 必须全局唯一,不能与已有配置重复。" -+ + "可通过 sensitive 字段标记是否为敏感配置(敏感配置不会通过公开接口暴露给小程序)。") - @OperationLog(value = "创建前端配置", module = "前端配置管理") - @PostMapping - public Result createConfig( -@@ -71,7 +88,10 @@ public class AdminFrontendConfigController { - return Result.success(frontendConfigService.createConfig(request, adminId)); - } - -- @ApiOperation("更新配置") -+ @ApiOperation(value = "更新配置", -+ notes = "更新指定前端配置项的值、分组、描述、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:修改后前端会实时使用新值(如有缓存需等待刷新)。") - @OperationLog(value = "更新前端配置", module = "前端配置管理") - @PutMapping("/{id}") - public Result updateConfig( -@@ -80,7 +100,10 @@ public class AdminFrontendConfigController { - return Result.success(frontendConfigService.updateConfig(id, request)); - } - -- @ApiOperation("删除配置") -+ @ApiOperation(value = "删除配置", -+ notes = "删除指定的前端配置项(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后前端将无法获取该配置,可能影响页面展示,请确认无引用后再删除。") - @OperationLog(value = "删除前端配置", module = "前端配置管理") - @DeleteMapping("/{id}") - public Result deleteConfig(@ApiParam("配置ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminProfileController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminProfileController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminProfileController.java -index e174243..6558bc2 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminProfileController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminProfileController.java -@@ -29,7 +29,12 @@ public class AdminProfileController { - private final FinanceDashboardService financeDashboardService; - private final MaterialDashboardService materialDashboardService; - -- @ApiOperation("获取我的个人资料") -+ @ApiOperation(value = "获取我的个人资料", -+ notes = "获取当前登录管理员的个人资料,根据角色返回不同的资料内容。\n" -+ + "定制师角色会返回认证等级、个人简介、擅长领域等附加信息。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- designer_cert_level(认证等级):返回字段certLevel(none/bronze/silver/gold/diamond)") - @GetMapping("/me") - public Result getMyProfile(HttpServletRequest request) { - Long adminId = getAdminId(request); -@@ -37,7 +42,10 @@ public class AdminProfileController { - return Result.success(profileService.getProfile(adminId, role)); - } - -- @ApiOperation("更新我的个人资料") -+ @ApiOperation(value = "更新我的个人资料", -+ notes = "更新当前登录管理员的个人资料,支持修改昵称、头像、个人简介等。\n" -+ + "定制师角色可额外更新擅长领域、服务区域等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @PutMapping("/me") - public Result updateMyProfile(HttpServletRequest request, - @Valid @RequestBody UpdateDesignerProfileRequest body) { -@@ -46,9 +54,19 @@ public class AdminProfileController { - return Result.success(profileService.updateProfile(adminId, role, body)); - } - -- @ApiOperation("工作台仪表盘(角色分发,支持时间范围)") -+ @ApiOperation(value = "工作台仪表盘(角色分发,支持时间范围)", notes = "根据当前管理员角色返回不同的仪表盘数据。" -+ + "CUSTOMIZER(定制师):待处理订单数、产品数、评价统计等。" -+ + "SUPER_ADMIN/ADMIN:全局概览(订单、收入、用户增长等)。" -+ + "ROOM_MANAGER(客房管理):房间分配概览。" -+ + "VEHICLE_MANAGER(车辆管理):车辆调度概览。" -+ + "FINANCE(财务):收支统计。" -+ + "MATERIAL_ADMIN(素材管理):素材库概览。" -+ + "period取值:today=今日 week=本周 month=本月。" -+ + "需要管理员认证。" -+ + "\n\n**关联字典**:\n" -+ + "- order_status(订单状态):仪表盘中订单统计按状态分组展示") - @GetMapping("/dashboard") -- public Result getDashboard( -+ public Result getDashboard( - HttpServletRequest request, - @ApiParam("时间范围: today/week/month") @RequestParam(defaultValue = "today") String period) { - Long adminId = getAdminId(request); -@@ -72,7 +90,9 @@ public class AdminProfileController { - } - } - -- @ApiOperation("我的评价列表") -+ @ApiOperation(value = "我的评价列表", notes = "查询当前定制师收到的评价列表,支持按评价等级筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- rating_level(评价等级):GOOD=好评, MEDIUM=中评, BAD=差评(筛选条件+列表展示)\n") - @GetMapping("/reviews") - public Result>> getReviews( - HttpServletRequest request, -@@ -83,7 +103,9 @@ public class AdminProfileController { - return Result.success(designerDashboardService.getMyReviews(adminId, page, pageSize, ratingLevel)); - } - -- @ApiOperation("订单列表") -+ @ApiOperation(value = "订单列表", notes = "查询当前定制师的订单列表,支持按状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- order_status(订单状态):请求参数status和返回字段status") - @GetMapping("/orders") - public Result>> getOrders( - HttpServletRequest request, -@@ -95,7 +117,9 @@ public class AdminProfileController { - return Result.success(designerDashboardService.getMyOrders(adminId, page, pageSize, status, keyword)); - } - -- @ApiOperation("产品列表") -+ @ApiOperation(value = "产品列表", notes = "查询当前定制师的产品列表,支持按状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- product_status(产品状态):请求参数status和返回字段status") - @GetMapping("/products") - public Result>> getProducts( - HttpServletRequest request, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminTopicController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminTopicController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminTopicController.java -index 7d2e9bc..e6766e3 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminTopicController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminTopicController.java -@@ -23,7 +23,9 @@ public class AdminTopicController { - - private final TopicService topicService; - -- @ApiOperation("专题列表") -+ @ApiOperation(value = "专题列表", notes = "分页查询探索专题列表,支持按关键词和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):请求参数status和返回字段status(0=禁用, 1=启用)") - @GetMapping - public Result> listTopics( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -34,13 +36,20 @@ public class AdminTopicController { - return Result.success(result); - } - -- @ApiOperation("专题详情") -+ @ApiOperation(value = "专题详情", -+ notes = "获取指定探索专题的详细信息,包括标题、封面图、描述、关联资源等。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- common_status(通用状态):返回字段status(0=禁用, 1=启用)") - @GetMapping("/{id}") - public Result getTopic(@ApiParam("专题ID") @PathVariable Long id) { - return Result.success(topicService.getTopic(id)); - } - -- @ApiOperation("创建专题") -+ @ApiOperation(value = "创建专题", -+ notes = "创建新的探索专题,用于小程序探索页面展示主题推荐内容。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:创建时需设置标题、封面图等基本信息。") - @OperationLog(value = "创建专题", module = "探索专题管理") - @PostMapping - public Result createTopic(@ApiParam("专题创建请求") @Valid @RequestBody TopicRequest request, -@@ -49,7 +58,9 @@ public class AdminTopicController { - return Result.success(topicService.createTopic(request, adminId)); - } - -- @ApiOperation("更新专题") -+ @ApiOperation(value = "更新专题", -+ notes = "更新指定探索专题的标题、封面图、描述、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "更新专题", module = "探索专题管理") - @PutMapping("/{id}") - public Result updateTopic(@ApiParam("专题ID") @PathVariable Long id, -@@ -57,7 +68,10 @@ public class AdminTopicController { - return Result.success(topicService.updateTopic(id, request)); - } - -- @ApiOperation("删除专题") -+ @ApiOperation(value = "删除专题", -+ notes = "删除指定的探索专题(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序探索页面将不再展示该专题。") - @OperationLog(value = "删除专题", module = "探索专题管理") - @DeleteMapping("/{id}") - public Result deleteTopic(@ApiParam("专题ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminUserController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminUserController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminUserController.java -index 2b3f74a..0344258 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminUserController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminUserController.java -@@ -26,7 +26,12 @@ public class AdminUserController { - - private final AdminUserService adminUserService; - -- @ApiOperation("创建管理员") -+ @ApiOperation(value = "创建管理员", notes = "创建新的后台管理员账号。" -+ + "默认密码为Admin@123456,管理员首次登录后建议修改密码。" -+ + "可通过roleIds分配多个角色,也兼容旧的单角色roleId参数。" -+ + "需要SUPER_ADMIN或ADMIN角色。" -+ + "\n\n**关联字典**:\n" -+ + "- admin_status(管理员状态):ACTIVE=启用, LOCKED=锁定, DISABLED=禁用\n") - @OperationLog(value = "创建管理员", module = "管理员管理") - @PostMapping - public Result createAdmin(@ApiParam("创建管理员请求") @Valid @RequestBody CreateAdminRequest request) { -@@ -34,7 +39,9 @@ public class AdminUserController { - return Result.success(admin); - } - -- @ApiOperation("更新管理员") -+ @ApiOperation(value = "更新管理员", notes = "更新管理员信息,包括用户名、状态、角色分配等。" -+ + "\n\n**关联字典**:\n" -+ + "- admin_status(管理员状态):ACTIVE=启用, LOCKED=锁定, DISABLED=禁用\n") - @OperationLog(value = "更新管理员", module = "管理员管理") - @PutMapping("/{adminId}") - public Result updateAdmin(@ApiParam("管理员ID") @PathVariable Long adminId, -@@ -43,7 +50,10 @@ public class AdminUserController { - return Result.success(admin); - } - -- @ApiOperation("删除管理员") -+ @ApiOperation(value = "删除管理员", notes = "删除指定管理员账号(软删除)。" -+ + "不能删除自己的账号,不能删除SUPER_ADMIN角色的账号(除非操作者也是SUPER_ADMIN)。" -+ + "删除后该管理员的登录状态自动失效。" -+ + "需要SUPER_ADMIN或ADMIN角色。") - @OperationLog(value = "删除管理员", module = "管理员管理") - @DeleteMapping("/{adminId}") - public Result deleteAdmin(@ApiParam("管理员ID") @PathVariable Long adminId, -@@ -54,7 +64,9 @@ public class AdminUserController { - return Result.success(); - } - -- @ApiOperation("解锁管理员") -+ @ApiOperation(value = "解锁管理员", notes = "解锁因登录失败次数过多而被锁定的管理员账号。" -+ + "管理员连续5次登录失败后账号自动锁定30分钟,此接口可立即解锁。" -+ + "需要SUPER_ADMIN或ADMIN角色。") - @OperationLog(value = "解锁管理员", module = "管理员管理") - @PostMapping("/{adminId}/unlock") - public Result unlockAdmin(@ApiParam("管理员ID") @PathVariable Long adminId, -@@ -65,7 +77,10 @@ public class AdminUserController { - return Result.success(); - } - -- @ApiOperation("重置密码") -+ @ApiOperation(value = "重置密码", notes = "将指定管理员的密码重置为默认密码(Admin@123456)。" -+ + "用于管理员忘记密码时由上级管理员操作重置。" -+ + "重置后管理员可用默认密码登录,建议立即修改。" -+ + "需要SUPER_ADMIN或ADMIN角色。") - @OperationLog(value = "重置密码", module = "管理员管理") - @PostMapping("/{adminId}/reset-password") - public Result resetPassword(@ApiParam("管理员ID") @PathVariable Long adminId, -@@ -76,7 +91,10 @@ public class AdminUserController { - return Result.success(); - } - -- @ApiOperation("修改企业微信绑定(支持换绑)") -+ @ApiOperation(value = "修改企业微信绑定(支持换绑)", notes = "为管理员绑定或更换企业微信账号。" -+ + "绑定后管理员可通过企业微信扫码登录,并可接收审批通知。" -+ + "如果目标企微ID已被其他管理员绑定,需设置forceRebind=true强制换绑。" -+ + "需要管理员认证。") - @OperationLog(value = "修改企业微信绑定", module = "管理员管理") - @PutMapping("/{adminId}/wechat-binding") - public Result> updateWechatBinding( -@@ -92,14 +110,21 @@ public class AdminUserController { - return Result.success(result); - } - -- @ApiOperation("获取管理员详情") -+ @ApiOperation(value = "获取管理员详情", notes = "获取指定管理员的完整信息。" -+ + "\n\n**关联字典**:\n" -+ + "- admin_status(管理员状态):ACTIVE=启用, LOCKED=锁定, DISABLED=禁用\n") - @GetMapping("/{adminId}") - public Result getAdmin(@ApiParam("管理员ID") @PathVariable Long adminId) { - AdminUser admin = adminUserService.getAdminById(adminId); - return Result.success(admin); - } - -- @ApiOperation("管理员列表") -+ @ApiOperation(value = "管理员列表", notes = "分页查询管理员列表,支持按角色、状态、企微绑定状态筛选。" -+ + "status取值:ACTIVE=正常 LOCKED=已锁定 DISABLED=已禁用。" -+ + "wechatBound:true=已绑定企业微信 false=未绑定。" -+ + "需要管理员认证。" -+ + "\n\n**关联字典**:\n" -+ + "- admin_status(管理员状态):ACTIVE=启用, LOCKED=锁定, DISABLED=禁用(筛选条件+列表展示)\n") - @GetMapping - public Result> listAdmins( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AuthController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AuthController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AuthController.java -index bf6beb1..84bf6c9 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AuthController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AuthController.java -@@ -30,7 +30,10 @@ public class AuthController { - @Value("${auth.2fa-confirm-enabled:false}") - private boolean twoFaConfirmEnabled; - -- @ApiOperation("管理员登录") -+ @ApiOperation(value = "管理员登录", notes = "管理员通过用户名+密码登录后台管理系统。" -+ + "首次在新设备登录时需要进行企业微信扫码二次验证(2FA),返回needTwoFa=true。" -+ + "登录失败5次后账号将被锁定30分钟。" -+ + "无需认证即可调用。") - @PostMapping("/login") - public Result login(@ApiParam("管理员登录请求") @Valid @RequestBody AdminLoginRequest request, - HttpServletRequest httpRequest) { -@@ -41,7 +44,10 @@ public class AuthController { - return Result.success(response); - } - -- @ApiOperation("2FA验证") -+ @ApiOperation(value = "2FA验证", notes = "新设备登录时的企业微信二次验证。" -+ + "管理员登录返回needTwoFa=true后,前端调用此接口提交验证码完成登录。" -+ + "验证通过后设备将被标记为可信设备,后续登录不再需要2FA。" -+ + "无需认证即可调用。") - @PostMapping("/wechat/verify-2fa") - public Result verifyTwoFa(@ApiParam("管理员ID") @RequestParam Long adminId, - @ApiParam("2FA验证请求") @Valid @RequestBody TwoFaVerifyRequest request, -@@ -53,7 +59,10 @@ public class AuthController { - return Result.success(response); - } - -- @ApiOperation("修改密码") -+ @ApiOperation(value = "修改密码", notes = "管理员修改自己的登录密码。" -+ + "需验证旧密码正确后才能设置新密码,新密码须满足复杂度要求(8-128位,含大小写字母和数字)。" -+ + "修改成功后当前Token仍然有效,无需重新登录。" -+ + "需要管理员认证(Token中的adminId)。") - @OperationLog(value = "修改密码", module = "认证管理") - @PutMapping("/password") - public Result changePassword(HttpServletRequest request, -@@ -63,7 +72,9 @@ public class AuthController { - return Result.success(); - } - -- @ApiOperation("管理员登出") -+ @ApiOperation(value = "管理员登出", notes = "清除管理员的登录状态并使当前Token失效。" -+ + "前端应在登出后清除本地存储的Token和用户信息。" -+ + "需要管理员认证。") - @PostMapping("/logout") - public Result logout(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -71,14 +82,20 @@ public class AuthController { - return Result.success(); - } - -- @ApiOperation("生成2FA扫码会话") -+ @ApiOperation(value = "生成2FA扫码会话", notes = "生成企业微信扫码二维码的会话信息,用于新设备二次验证。" -+ + "返回包含qrcodeUrl(二维码链接)和state(会话标识)。" -+ + "前端展示二维码后通过轮询 /2fa/check 接口检查扫码状态。" -+ + "无需认证即可调用(登录流程中使用)。") - @GetMapping("/2fa/qrcode") - public Result> generate2FaQrcode(@ApiParam("管理员ID") @RequestParam Long adminId) { - Map data = adminAuthService.generate2FaQrSession(adminId); - return Result.success(data); - } - -- @ApiOperation("2FA企微扫码回调") -+ @ApiOperation(value = "2FA企微扫码回调", notes = "企业微信OAuth回调地址,用户扫码授权后微信服务器回调此接口。" -+ + "此接口由微信服务器调用,非前端直接调用。" -+ + "回调成功后将state对应的会话标记为已扫码,前端轮询 /2fa/check 即可获取结果。" -+ + "返回HTML页面(成功/失败提示),不返回JSON。") - @GetMapping(value = "/2fa/callback", produces = MediaType.TEXT_HTML_VALUE) - @ResponseBody - public String handle2FaCallback(@ApiParam("授权码") @RequestParam String code, @ApiParam("会话状态") @RequestParam String state) { -@@ -120,14 +137,19 @@ public class AuthController { - - // ==================== WeChat QR Direct Login ==================== - -- @ApiOperation("生成企业微信扫码登录会话") -+ @ApiOperation(value = "生成企业微信扫码登录会话", notes = "生成企业微信扫码直接登录的会话信息(非2FA验证,而是扫码替代密码登录)。" -+ + "返回包含qrcodeUrl和state。前端展示二维码后通过轮询 /wechat-qr/status 检查登录状态。" -+ + "无需认证即可调用。") - @GetMapping("/wechat-qr") - public Result> generateWechatLoginQr() { - Map data = adminAuthService.generateWechatLoginQrSession(); - return Result.success(data); - } - -- @ApiOperation("企业微信扫码登录回调") -+ @ApiOperation(value = "企业微信扫码登录回调", notes = "企业微信OAuth回调地址,扫码登录授权后微信服务器回调此接口。" -+ + "此接口由微信服务器调用,非前端直接调用。" -+ + "回调后标记会话为已扫码,前端通过轮询 /wechat-qr/status 获取登录结果。" -+ + "返回HTML页面,不返回JSON。") - @GetMapping(value = "/wechat-qr/callback", produces = MediaType.TEXT_HTML_VALUE) - @ResponseBody - public String handleWechatLoginCallback(@ApiParam("授权码") @RequestParam String code, @ApiParam("会话状态") @RequestParam String state) { -@@ -167,7 +189,10 @@ public class AuthController { - } - } - -- @ApiOperation("查询企业微信扫码登录状态") -+ @ApiOperation(value = "查询企业微信扫码登录状态", notes = "前端轮询此接口检查扫码登录是否完成。" -+ + "返回status字段:PENDING=等待扫码,SCANNED=已扫码登录成功(附带token和用户信息)。" -+ + "建议轮询间隔2秒,超过5分钟未扫码会话自动失效。" -+ + "无需认证即可调用。") - @GetMapping("/wechat-qr/status") - public Result> checkWechatLoginStatus(@ApiParam("会话状态") @RequestParam String state, - HttpServletRequest httpRequest) { -@@ -178,7 +203,11 @@ public class AuthController { - return Result.success(data); - } - -- @ApiOperation("手动确认扫码(内网穿透环境workaround,默认关闭)") -+ @ApiOperation(value = "手动确认扫码(内网穿透环境workaround,默认关闭)", -+ notes = "在内网穿透环境下,企微回调可能无法正常到达,此接口作为手动替代方案。\n" -+ + "需在Nacos配置中开启 auth.2fa-confirm-enabled=true 才可使用。\n\n" -+ + "**权限**:无需认证(登录流程中使用)。\n" -+ + "**注意**:生产环境应保持关闭,仅限开发/测试时使用。") - @PostMapping("/2fa/confirm") - public Result confirm2FaScan(@ApiParam("会话状态") @RequestParam String state, - @ApiParam("管理员ID") @RequestParam String adminId, -@@ -195,7 +224,10 @@ public class AuthController { - return Result.success(); - } - -- @ApiOperation("查询2FA扫码状态") -+ @ApiOperation(value = "查询2FA扫码状态", notes = "前端轮询此接口检查2FA扫码验证是否完成。" -+ + "返回status字段:PENDING=等待扫码,SCANNED=已完成验证(附带token和用户信息)。" -+ + "建议轮询间隔2秒,超过5分钟未扫码会话自动失效。" -+ + "无需认证即可调用(登录流程中使用)。") - @GetMapping("/2fa/check") - public Result> check2FaStatus(@ApiParam("会话状态") @RequestParam String state, - HttpServletRequest httpRequest) { -@@ -206,7 +238,10 @@ public class AuthController { - return Result.success(data); - } - -- @ApiOperation("切换当前角色") -+ @ApiOperation(value = "切换当前角色", notes = "多角色管理员切换当前活跃角色。" -+ + "切换后返回新的Token和角色对应的菜单权限,前端需更新本地Token并刷新菜单。" -+ + "只能切换到该管理员已分配的角色,否则报错。" -+ + "需要管理员认证。") - @OperationLog(value = "切换角色", module = "认证管理") - @PostMapping("/switch-role") - public Result switchRole(HttpServletRequest request, -@@ -216,7 +251,10 @@ public class AuthController { - return Result.success(response); - } - -- @ApiOperation("更新头像") -+ @ApiOperation(value = "更新头像", notes = "管理员更新自己的头像。" -+ + "需先通过文件服务上传图片获取OSS URL和fileId,再调用此接口绑定。" -+ + "旧头像的文件引用会自动解绑。" -+ + "需要管理员认证。") - @OperationLog(value = "更新头像", module = "认证管理") - @PutMapping("/avatar") - public Result updateAvatar(HttpServletRequest request, -@@ -226,7 +264,9 @@ public class AuthController { - return Result.success(); - } - -- @ApiOperation("获取当前管理员信息") -+ @ApiOperation(value = "获取当前管理员信息", notes = "获取当前登录管理员的完整信息,包括用户名、头像、角色列表、当前角色、菜单权限等。" -+ + "前端页面初始化时调用此接口获取用户信息和权限数据。" -+ + "需要管理员认证。") - @GetMapping("/info") - public Result getAdminInfo(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/FavoriteController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/FavoriteController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/FavoriteController.java -index 0b374f0..79a06b4 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/FavoriteController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/FavoriteController.java -@@ -22,7 +22,12 @@ public class FavoriteController { - - private final FavoriteService favoriteService; - -- @ApiOperation("添加收藏") -+ @ApiOperation(value = "添加收藏", notes = "将指定资源添加到当前用户的收藏列表。" -+ + "同一用户对同一资源不可重复收藏,重复收藏会报错。" -+ + "targetType取值:SCENIC_SPOT/ACTIVITY/HOTEL/PRODUCT/EXPLORE等。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品, EXPLORE=探索(请求参数targetType)\n") - @PostMapping - public Result addFavorite(HttpServletRequest request, - @ApiParam("收藏请求") @Valid @RequestBody FavoriteRequest favoriteRequest) { -@@ -31,7 +36,11 @@ public class FavoriteController { - return Result.success(favorite); - } - -- @ApiOperation("收藏列表") -+ @ApiOperation(value = "收藏列表", notes = "分页查询当前用户的所有收藏记录,按收藏时间倒序排列。" -+ + "返回收藏记录的基础信息(不包含资源详情),需前端根据targetType和targetId再查详情。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):返回字段targetType,前端据此判断跳转到哪种资源详情页\n") - @GetMapping - public Result> listFavorites(HttpServletRequest request, - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -41,7 +50,9 @@ public class FavoriteController { - return Result.success(result); - } - -- @ApiOperation("删除收藏") -+ @ApiOperation(value = "删除收藏", notes = "根据收藏记录ID取消收藏。" -+ + "只能删除自己的收藏记录,删除他人的收藏会报权限错误。" -+ + "需要小程序用户认证。") - @DeleteMapping("/{favoriteId}") - public Result deleteFavorite(HttpServletRequest request, - @ApiParam("收藏ID") @PathVariable Long favoriteId) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/FootprintController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/FootprintController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/FootprintController.java -index 2616fdc..a24102e 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/FootprintController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/FootprintController.java -@@ -22,7 +22,13 @@ public class FootprintController { - - private final FootprintService footprintService; - -- @ApiOperation("添加足迹") -+ @ApiOperation(value = "添加足迹", notes = "记录用户浏览资源的足迹。" -+ + "同一用户对同一资源多次浏览只保留最新一条记录(更新时间)。" -+ + "resourceType取值:SCENIC_SPOT/ACTIVITY/HOTEL/PRODUCT等。" -+ + "通常由前端在进入资源详情页时自动调用。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- footprint_resource_type(足迹资源类型):SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品(请求参数resourceType)\n") - @PostMapping - public Result addFootprint(HttpServletRequest request, - @ApiParam("足迹请求") @Valid @RequestBody FootprintRequest footprintRequest) { -@@ -31,7 +37,10 @@ public class FootprintController { - return Result.success(footprint); - } - -- @ApiOperation("足迹列表") -+ @ApiOperation(value = "足迹列表", notes = "分页查询当前用户的浏览足迹,按浏览时间倒序排列。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- footprint_resource_type(足迹资源类型):返回字段resourceType,前端据此判断跳转到哪种资源详情页\n") - @GetMapping - public Result> listFootprints(HttpServletRequest request, - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -41,7 +50,9 @@ public class FootprintController { - return Result.success(result); - } - -- @ApiOperation("删除足迹") -+ @ApiOperation(value = "删除足迹", notes = "根据足迹记录ID删除单条浏览足迹。" -+ + "只能删除自己的足迹记录。" -+ + "需要小程序用户认证。") - @DeleteMapping("/{footprintId}") - public Result deleteFootprint(HttpServletRequest request, - @ApiParam("足迹ID") @PathVariable Long footprintId) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalApprovalController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalApprovalController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalApprovalController.java -index 37a5069..bdd7f6d 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalApprovalController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalApprovalController.java -@@ -22,7 +22,7 @@ import java.util.*; - * Called by other services via Feign (not exposed via gateway). - */ - @Slf4j --@Api(tags = "【内部接口】审批(Feign调用)") -+@Api(tags = "【内部接口】审批(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/wechat") - @RequiredArgsConstructor -@@ -129,7 +129,11 @@ public class InternalApprovalController { - @Value("${approval.product.control-ids.reason:}") - private String controlIdProductReason; - -- @ApiOperation("Submit approval to enterprise WeChat OA") -+ @ApiOperation(value = "提交企业微信OA审批", notes = "内部接口,由其他服务通过Feign调用提交企微审批申请。" -+ + "根据templateId自动路由到对应的审批模板(资源上下架/产品上下架/退款申请/退款申诉)。" -+ + "需提供adminId(管理员提交)或wechatUserId(代理提交)。" -+ + "返回企微审批单号spNo,用于后续查询审批状态。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/submit-approval") - public Result submitApproval(@RequestBody ApprovalSubmitDTO dto) { - if (dto.getTemplateId() == null || dto.getTemplateId().isEmpty()) { -@@ -183,7 +187,10 @@ public class InternalApprovalController { - return Result.success(result); - } - -- @ApiOperation("Revoke a pending approval in enterprise WeChat OA") -+ @ApiOperation(value = "撤销企业微信OA审批", notes = "内部接口,撤销一个待审批的企微OA审批申请。" -+ + "仅PENDING状态的审批可以撤销,已审批的无法撤销。" -+ + "撤销失败不会抛异常(降级处理),业务侧需自行处理状态。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/revoke-approval/{spNo}") - public Result revokeApproval(@PathVariable String spNo) { - if (spNo == null || spNo.isEmpty()) { -@@ -200,7 +207,12 @@ public class InternalApprovalController { - return Result.success(); - } - -- @ApiOperation("Get approval status from enterprise WeChat OA") -+ @ApiOperation(value = "查询企业微信OA审批状态", notes = "内部接口,根据审批单号查询企微审批的详细状态。" -+ + "返回审批状态(spStatus:1=审批中 2=已通过 3=已驳回 4=已撤销)、申请人、表单数据等。" -+ + "用于审批轮询兜底方案(ApprovalPollingService)。" -+ + "不经过Gateway,仅服务间调用。" -+ + "\n\n**关联字典**:\n" -+ + "- approval_sp_status(审批状态):返回字段spStatus(1=审批中, 2=已通过, 3=已驳回, 4=已撤销)") - @GetMapping("/approval-status/{spNo}") - @SuppressWarnings("unchecked") - public Result> getApprovalStatus(@PathVariable String spNo) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalBadgeController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBadgeController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBadgeController.java -index c2204f9..df482d7 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBadgeController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBadgeController.java -@@ -13,7 +13,7 @@ import java.util.Map; - * 徽章内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/badge") - @RequiredArgsConstructor -@@ -21,7 +21,10 @@ public class InternalBadgeController { - - private final BadgeService badgeService; - -- @ApiOperation("获取用户徽章数据") -+ @ApiOperation(value = "获取用户徽章数据", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取指定用户的各类未读数和待处理徽章数据(如未读消息数、待付款订单数等)。\n" -+ + "用于小程序个人中心页面的红点/数字徽章展示。") - @GetMapping - public Result> getUserBadgeData(@RequestParam Long userId) { - return Result.success(badgeService.getUserBadgeData(userId)); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalBannerController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBannerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBannerController.java -index 4df5705..b339c1f 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBannerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBannerController.java -@@ -16,7 +16,7 @@ import java.util.List; - * Banner内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/banner") - @RequiredArgsConstructor -@@ -24,7 +24,9 @@ public class InternalBannerController { - - private final BannerService bannerService; - -- @ApiOperation("获取当前有效Banner列表") -+ @ApiOperation(value = "获取当前有效Banner列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取所有状态为启用的Banner列表,按排序号排列,用于小程序首页轮播展示。") - @GetMapping("/active") - public Result> listActiveBanners() { - return Result.success(bannerService.listActiveBanners()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalContactController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalContactController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalContactController.java -index d38d4a3..dc412e7 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalContactController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalContactController.java -@@ -16,7 +16,7 @@ import java.util.List; - * 联系我们内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/contact") - @RequiredArgsConstructor -@@ -24,7 +24,10 @@ public class InternalContactController { - - private final ContactService contactService; - -- @ApiOperation("获取当前有效联系方式列表") -+ @ApiOperation(value = "获取当前有效联系方式列表", notes = "内部接口,获取所有状态为上线的联系方式。" -+ + "不经过Gateway,仅服务间调用。" -+ + "\n\n**关联字典**:\n" -+ + "- contact_channel_type(联系渠道类型):返回字段channelType(ABOUT=关于我们, ONLINE_CS=在线客服, PHONE=电话咨询)\n") - @GetMapping("/active") - public Result> listActiveContacts() { - return Result.success(contactService.listActiveContacts()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalDesignerController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalDesignerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalDesignerController.java -index 969a9d2..f96ec05 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalDesignerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalDesignerController.java -@@ -14,7 +14,7 @@ import java.util.List; - * C端定制师内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/designer") - @RequiredArgsConstructor -@@ -22,20 +22,28 @@ public class InternalDesignerController { - - private final DesignerService designerService; - -- @ApiOperation("定制师列表") -+ @ApiOperation(value = "定制师列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "分页获取已上线的定制师列表,用于小程序定制师展示页面。\n" -+ + "返回定制师头像、昵称、认证等级、擅长领域等信息。") - @GetMapping - public Result> listDesigners(@RequestParam(defaultValue = "1") int page, - @RequestParam(defaultValue = "10") int limit) { - return Result.success(designerService.listDesigners(page, limit)); - } - -- @ApiOperation("推荐定制师") -+ @ApiOperation(value = "推荐定制师", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取一位推荐定制师,用于小程序首页推荐位展示。\n" -+ + "推荐逻辑由后端按权重排序选取。") - @GetMapping("/featured") - public Result getFeaturedDesigner() { - return Result.success(designerService.getFeaturedDesigner()); - } - -- @ApiOperation("定制师详情") -+ @ApiOperation(value = "定制师详情", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取指定定制师的详细信息,包括个人简介、擅长领域、服务案例等。") - @GetMapping("/{id}") - public Result getDesignerDetail(@PathVariable Long id) { - return Result.success(designerService.getDesignerDetail(id)); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalExploreCategoryController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalExploreCategoryController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalExploreCategoryController.java -index 1e7bf8d..02ea651 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalExploreCategoryController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalExploreCategoryController.java -@@ -26,7 +26,7 @@ import java.util.stream.Collectors; - * 探索分类内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "探索分类小程序接口") -+@Api(tags = "探索分类小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/explore") - @RequiredArgsConstructor -@@ -38,7 +38,10 @@ public class InternalExploreCategoryController { - private final FavoriteService favoriteService; - private final UserLikeService userLikeService; - -- @ApiOperation("获取上线探索分类列表") -+ @ApiOperation(value = "获取上线探索分类列表", notes = "内部接口,获取已上线的探索分类列表,支持排序。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):仅返回status=1(启用)的分类\n" -+ + "- explore_sort_type(排序方式):请求参数sortType(comprehensive=综合, newest=最新, hottest=最热)") - @GetMapping("/active") - public Result> listActive( - @ApiParam("排序方式:comprehensive=综合 newest=最新 hottest=最热") @RequestParam(defaultValue = "comprehensive") String sortType, -@@ -47,7 +50,10 @@ public class InternalExploreCategoryController { - return Result.success(exploreCategoryService.listActive(sortType, page, pageSize)); - } - -- @ApiOperation("获取探索分类详情(自动增加浏览量)") -+ @ApiOperation(value = "获取探索分类详情(自动增加浏览量)", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取指定分类的详细信息,同时自动增加浏览量计数。\n" -+ + "如果传入 X-User-Id 请求头,还会返回当前用户的点赞和收藏状态。") - @GetMapping("/{id}") - public Result getActiveDetail( - @ApiParam("分类ID") @PathVariable Long id, -@@ -65,14 +71,19 @@ public class InternalExploreCategoryController { - return Result.success(exploreCategoryService.getActiveDetail(id, isLiked, isFavorited)); - } - -- @ApiOperation("增加浏览量") -+ @ApiOperation(value = "增加浏览量", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "手动增加指定探索分类的浏览量计数(+1)。") - @PostMapping("/{id}/view") - public Result incrementViewCount(@ApiParam("分类ID") @PathVariable Long id) { - exploreCategoryService.incrementViewCount(id); - return Result.success(); - } - -- @ApiOperation("切换收藏状态") -+ @ApiOperation(value = "切换收藏状态", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "切换用户对指定探索分类的收藏状态:已收藏则取消,未收藏则添加。\n" -+ + "返回 true=已收藏,false=已取消收藏。同时更新分类的收藏计数。") - @PostMapping("/{id}/favorite") - public Result toggleFavorite( - @ApiParam("分类ID") @PathVariable Long id, -@@ -101,7 +112,9 @@ public class InternalExploreCategoryController { - } - } - -- @ApiOperation("检查是否已收藏") -+ @ApiOperation(value = "检查是否已收藏", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "检查用户是否已收藏指定的探索分类,返回 true/false。") - @GetMapping("/{id}/favorite/check") - public Result checkFavorite( - @ApiParam("分类ID") @PathVariable Long id, -@@ -109,7 +122,10 @@ public class InternalExploreCategoryController { - return Result.success(favoriteService.checkFavorite(userId, TARGET_TYPE_EXPLORE, id)); - } - -- @ApiOperation("切换点赞状态") -+ @ApiOperation(value = "切换点赞状态", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "切换用户对指定探索分类的点赞状态:已点赞则取消,未点赞则添加。\n" -+ + "返回 true=已点赞,false=已取消。同时更新分类的点赞计数。") - @PostMapping("/{id}/like") - public Result toggleLike( - @ApiParam("分类ID") @PathVariable Long id, -@@ -119,7 +135,9 @@ public class InternalExploreCategoryController { - return Result.success(liked); - } - -- @ApiOperation("检查是否已点赞") -+ @ApiOperation(value = "检查是否已点赞", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "检查用户是否已点赞指定的探索分类,返回 true/false。") - @GetMapping("/{id}/like/check") - public Result checkLike( - @ApiParam("分类ID") @PathVariable Long id, -@@ -127,7 +145,10 @@ public class InternalExploreCategoryController { - return Result.success(userLikeService.checkLike(userId, TARGET_TYPE_EXPLORE, id)); - } - -- @ApiOperation("获取同分类的景区资源列表") -+ @ApiOperation(value = "获取同分类的景区资源列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "根据景区ID查找与其同一探索分类下的其他景区资源,用于'相关推荐'展示。\n" -+ + "返回资源ID、名称、描述、封面图等基本信息。") - @GetMapping("/related-scenic") - public Result>> getRelatedScenic( - @ApiParam("景区ID") @RequestParam Long scenicId, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalFaqController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFaqController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFaqController.java -index 90d24df..e00222c 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFaqController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFaqController.java -@@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RestController; - - import java.util.List; - --@Api(tags = "【内部接口】常见问题(Feign调用)") -+@Api(tags = "【内部接口】常见问题(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/faq") - @RequiredArgsConstructor -@@ -20,7 +20,9 @@ public class InternalFaqController { - - private final FaqService faqService; - -- @ApiOperation("获取所有启用的FAQ(含分类和条目)") -+ @ApiOperation(value = "获取所有启用的FAQ(含分类和条目)", -+ notes = "内部服务间调用接口,由其他微服务通过 Feign 调用。\n" -+ + "获取所有状态为启用的FAQ分类及其下属条目,按排序号排列。") - @GetMapping("/all") - public Result> getAllActiveFaq() { - return Result.success(faqService.getAllActiveFaq()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalFrontendConfigController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFrontendConfigController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFrontendConfigController.java -index 1f32c3b..4976f91 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFrontendConfigController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFrontendConfigController.java -@@ -14,7 +14,7 @@ import java.util.List; - * 前端配置内部接口(仅供其他服务通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "【内部接口】前端配置(Feign调用)") -+@Api(tags = "【内部接口】前端配置(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/frontend-config") - @RequiredArgsConstructor -@@ -22,32 +22,42 @@ public class InternalFrontendConfigController { - - private final FrontendConfigService frontendConfigService; - -- @ApiOperation("获取所有启用的前端配置") -+ @ApiOperation(value = "获取所有启用的前端配置", -+ notes = "内部服务间调用接口,由其他微服务通过 Feign 调用。\n" -+ + "获取所有状态为启用的前端配置项列表(含敏感配置)。") - @GetMapping("/all") - public Result> listAllActiveConfigs() { - return Result.success(frontendConfigService.listAllActiveConfigs()); - } - -- @ApiOperation("按分组获取启用的配置") -+ @ApiOperation(value = "按分组获取启用的配置", -+ notes = "内部服务间调用接口,由其他微服务通过 Feign 调用。\n" -+ + "按配置分组名获取该分组下所有已启用的配置项。") - @GetMapping("/group/{group}") - public Result> listActiveConfigsByGroup(@PathVariable String group) { - return Result.success(frontendConfigService.listActiveConfigsByGroup(group)); - } - -- @ApiOperation("按key获取单个配置") -+ @ApiOperation(value = "按key获取单个配置", -+ notes = "内部服务间调用接口,由其他微服务通过 Feign 调用。\n" -+ + "根据 configKey 获取单个已启用的配置项,不存在则返回错误。") - @GetMapping("/key/{key}") - public Result getActiveConfigByKey(@PathVariable String key) { - FrontendConfigVO vo = frontendConfigService.getActiveConfigByKey(key); - return vo != null ? Result.success(vo) : Result.error("配置项不存在"); - } - -- @ApiOperation("获取所有非敏感的前端配置(供小程序使用)") -+ @ApiOperation(value = "获取所有非敏感的前端配置(供小程序使用)", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取所有已启用且非敏感(sensitive=false)的配置项,安全地暴露给小程序C端。") - @GetMapping("/public") - public Result> listPublicConfigs() { - return Result.success(frontendConfigService.listPublicConfigs()); - } - -- @ApiOperation("按分组获取非敏感配置(供小程序使用)") -+ @ApiOperation(value = "按分组获取非敏感配置(供小程序使用)", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "按分组获取非敏感配置,过滤掉标记为敏感的配置项。") - @GetMapping("/public/group/{group}") - public Result> listPublicConfigsByGroup(@PathVariable String group) { - return Result.success(frontendConfigService.listPublicConfigsByGroup(group)); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalLikeController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLikeController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLikeController.java -index aba407f..a14b558 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLikeController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLikeController.java -@@ -14,7 +14,7 @@ import java.util.*; - * 通用点赞内部接口(供 hl-mp-service BFF 通过 Feign 调用) - * 支持任意资源类型:REVIEW, EXPLORE, GUIDE 等 - */ --@Api(tags = "【内部接口】通用点赞(Feign调用)") -+@Api(tags = "【内部接口】通用点赞(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/like") - @RequiredArgsConstructor -@@ -22,7 +22,9 @@ public class InternalLikeController { - - private final UserLikeService userLikeService; - -- @ApiOperation("切换点赞状态(通用)") -+ @ApiOperation(value = "切换点赞状态(通用)", notes = "内部接口,切换用户对指定资源的点赞状态。" -+ + "\n\n**关联字典**:\n" -+ + "- like_target_type(点赞目标类型):请求参数targetType(REVIEW=评价, EXPLORE=探索, GUIDE=攻略)") - @PostMapping("/toggle") - public Result> toggleLike( - @ApiParam("目标类型") @RequestParam String targetType, -@@ -36,7 +38,9 @@ public class InternalLikeController { - return Result.success(data); - } - -- @ApiOperation("检查是否已点赞(通用)") -+ @ApiOperation(value = "检查是否已点赞(通用)", notes = "内部接口,检查用户是否已点赞指定资源。" -+ + "\n\n**关联字典**:\n" -+ + "- like_target_type(点赞目标类型):请求参数targetType(REVIEW=评价, EXPLORE=探索, GUIDE=攻略)") - @GetMapping("/check") - public Result checkLike( - @ApiParam("目标类型") @RequestParam String targetType, -@@ -45,7 +49,9 @@ public class InternalLikeController { - return Result.success(userLikeService.checkLike(userId, targetType, targetId)); - } - -- @ApiOperation("批量检查是否已点赞(接受字符串ID,避免JS大数精度丢失)") -+ @ApiOperation(value = "批量检查是否已点赞(接受字符串ID,避免JS大数精度丢失)", notes = "内部接口,批量检查用户是否已点赞指定资源列表。" -+ + "\n\n**关联字典**:\n" -+ + "- like_target_type(点赞目标类型):请求参数targetType(REVIEW=评价, EXPLORE=探索, GUIDE=攻略)") - @PostMapping("/batch-check") - public Result> batchCheckLiked( - @ApiParam("目标类型") @RequestParam String targetType, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalLoginLogController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLoginLogController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLoginLogController.java -index 124fb4f..179904b 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLoginLogController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLoginLogController.java -@@ -24,7 +24,7 @@ import java.util.stream.Collectors; - * Internal endpoint for monitor-service to query login logs. - * NOT exposed via gateway. - */ --@Api(tags = "【内部接口】登录日志(Feign调用)") -+@Api(tags = "【内部接口】登录日志(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal") - @RequiredArgsConstructor -@@ -35,7 +35,14 @@ public class InternalLoginLogController { - - private static final DateTimeFormatter FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - -- @ApiOperation("Query login logs") -+ @ApiOperation(value = "查询登录日志", notes = "内部接口,供hl-monitor-service通过Feign查询管理员登录日志。" -+ + "支持按管理员ID、登录状态、时间范围筛选。" -+ + "status取值:SUCCESS=登录成功 FAILED=登录失败。" -+ + "时间格式:yyyy-MM-dd HH:mm:ss。" -+ + "不经过Gateway,仅服务间调用。" -+ + "\n\n**关联字典**:\n" -+ + "- login_status(登录状态):请求参数status和返回字段status(SUCCESS=成功, FAILED=失败)\n" -+ + "- login_method(登录方式):返回字段loginMethod(PASSWORD=密码, WECHAT_QR=企微扫码, TWO_FA=二次验证)") - @GetMapping("/login-logs") - public Result> queryLoginLogs( - @RequestParam(defaultValue = "1") int page, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpCommonController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpCommonController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpCommonController.java -index a8f1de8..8e53118 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpCommonController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpCommonController.java -@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/common") - @RequiredArgsConstructor -@@ -19,19 +19,26 @@ public class InternalMpCommonController { - - private final CommonService commonService; - -- @ApiOperation("应用配置") -+ @ApiOperation(value = "应用配置", -+ notes = "内部服务间调用接口,由 hl-mp-service 调用。\n" -+ + "获取小程序应用的基础配置信息,如版本号、客服电话等。") - @GetMapping("/config") - public Result> getConfig() { - return Result.success(commonService.getConfig()); - } - -- @ApiOperation("FAQ列表") -+ @ApiOperation(value = "FAQ列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 调用。\n" -+ + "获取所有启用的FAQ分类及其条目,用于小程序帮助中心页面展示。") - @GetMapping("/faq") - public Result>> listFaq() { - return Result.success(commonService.listFaq()); - } - -- @ApiOperation("提交反馈") -+ @ApiOperation(value = "提交反馈", -+ notes = "内部服务间调用接口,由 hl-mp-service 调用。\n" -+ + "提交用户反馈意见,包括反馈内容、联系方式等。\n" -+ + "需传入 userId 参数标识提交反馈的用户。") - @PostMapping("/feedback") - public Result submitFeedback(@RequestParam Long userId, - @RequestBody UserFeedback feedback) { -@@ -39,13 +46,18 @@ public class InternalMpCommonController { - return Result.success(null); - } - -- @ApiOperation("获取协议文本") -+ @ApiOperation(value = "获取协议文本", -+ notes = "内部服务间调用接口,由 hl-mp-service 调用。\n" -+ + "根据协议类型(如 user_agreement、privacy_policy)获取协议的富文本内容。\n" -+ + "用于小程序协议详情页面展示。") - @GetMapping("/agreement/{type}") - public Result> getAgreement(@PathVariable String type) { - return Result.success(commonService.getAgreement(type)); - } - -- @ApiOperation("获取所有已上线协议列表") -+ @ApiOperation(value = "获取所有已上线协议列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 调用。\n" -+ + "获取所有状态为启用的协议列表,用于小程序注册/登录时展示需要同意的协议链接。") - @GetMapping("/agreement/list") - public Result>> listActiveAgreements() { - return Result.success(commonService.listActiveAgreements()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpDictController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpDictController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpDictController.java -index e634ded..6028ac3 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpDictController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpDictController.java -@@ -19,7 +19,7 @@ import java.util.stream.Collectors; - * C端字典内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/dict") - @RequiredArgsConstructor -@@ -27,7 +27,9 @@ public class InternalMpDictController { - - private final SysDictService sysDictService; - -- @ApiOperation("获取所有字典数据(C端小程序)") -+ @ApiOperation(value = "获取所有字典数据(C端小程序)", notes = "内部接口,供hl-mp-service通过Feign获取小程序可用的字典数据。" -+ + "返回格式:[{dictType, dictName, dataList}],与管理端字典数据格式一致。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/all") - public Result>> getAllDict() { - List dictList = sysDictService.getAllDictForMiniApp(); -@@ -44,7 +46,8 @@ public class InternalMpDictController { - return Result.success(result); - } - -- @ApiOperation("按字典类型获取字典数据列表") -+ @ApiOperation(value = "按字典类型获取字典数据列表", notes = "内部接口,根据字典类型编码(如order_status)获取该类型下的所有字典数据项。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/type/{dictType}") - public Result> getDictDataByType( - @ApiParam("字典类型编码") @PathVariable String dictType) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpMessageController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpMessageController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpMessageController.java -index 4921435..f32737c 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpMessageController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpMessageController.java -@@ -14,7 +14,7 @@ import java.util.HashMap; - import java.util.List; - import java.util.Map; - --@Api(tags = "小程序消息接口") -+@Api(tags = "小程序消息接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/message") - @RequiredArgsConstructor -@@ -22,19 +22,32 @@ public class InternalMpMessageController { - - private final UserMessageService userMessageService; - -- @ApiOperation("消息分类列表(含未读数和最新消息预览)") -+ @ApiOperation(value = "消息分类列表(含未读数和最新消息预览)", notes = "获取用户的消息分类汇总信息。" -+ + "每个分类返回:分类名称、未读消息数、最新一条消息的标题和时间。" -+ + "用于消息中心首页展示各分类入口。" -+ + "内部接口,由hl-mp-service通过Feign调用。" -+ + "\n\n**关联字典**:\n" -+ + "- message_category(消息分类):返回字段code(ORDER=订单消息, TRIP=行程消息, SYSTEM=系统消息, PROMO=营销消息)") - @GetMapping("/categories") - public Result> getCategories(@RequestParam("userId") Long userId) { - return Result.success(userMessageService.getCategorySummaries(userId)); - } - -- @ApiOperation("消息摘要(兼容旧接口)") -+ @ApiOperation(value = "消息摘要(兼容旧接口)", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "功能同 /categories 接口,保留用于向后兼容旧版本小程序。") - @GetMapping("/summary") - public Result> getSummary(@RequestParam("userId") Long userId) { - return Result.success(userMessageService.getCategorySummaries(userId)); - } - -- @ApiOperation("分类内消息列表(进入后自动标记已读)") -+ @ApiOperation(value = "分类内消息列表(进入后自动标记已读)", notes = "分页查询指定分类下的消息列表,按时间倒序排列。" -+ + "进入该分类后自动将该分类的所有消息标记为已读。" -+ + "categoryCode参数支持旧参数名category(向后兼容)。" -+ + "内部接口,由hl-mp-service通过Feign调用。" -+ + "\n\n**关联字典**:\n" -+ + "- message_category(消息分类):请求参数categoryCode(ORDER=订单消息, TRIP=行程消息, SYSTEM=系统消息, PROMO=营销消息)\n" -+ + "- message_biz_type(关联业务类型):返回字段bizType(ORDER=订单, REFUND=退款, CONTRACT=合同)") - @GetMapping("/list") - public Result> listMessages( - @RequestParam("userId") Long userId, -@@ -47,7 +60,9 @@ public class InternalMpMessageController { - return Result.success(userMessageService.listMessages(userId, code, page, pageSize)); - } - -- @ApiOperation("获取总未读数") -+ @ApiOperation(value = "获取总未读数", notes = "获取用户所有分类的未读消息总数。" -+ + "返回{count: N}格式,用于小程序Tab栏消息角标显示。" -+ + "内部接口,由hl-mp-service通过Feign调用。") - @GetMapping("/unread-count") - public Result> getUnreadCount(@RequestParam("userId") Long userId) { - Map result = new HashMap<>(); -@@ -55,7 +70,10 @@ public class InternalMpMessageController { - return Result.success(result); - } - -- @ApiOperation("全部标记已读") -+ @ApiOperation(value = "全部标记已读", notes = "将消息标记为已读。" -+ + "如果传入categoryCode,则只标记该分类下的消息为已读。" -+ + "如果不传categoryCode,则标记所有消息为已读。" -+ + "内部接口,由hl-mp-service通过Feign调用。") - @PutMapping("/read-all") - public Result markAllRead( - @RequestParam("userId") Long userId, -@@ -70,7 +88,9 @@ public class InternalMpMessageController { - return Result.success(null); - } - -- @ApiOperation("标记已读") -+ @ApiOperation(value = "标记已读", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "将单条消息标记为已读(兼容旧接口,实际已被分类级别标记替代)。") - @PutMapping("/{id}/read") - public Result markRead( - @RequestParam("userId") Long userId, -@@ -79,7 +99,9 @@ public class InternalMpMessageController { - return Result.success(null); - } - -- @ApiOperation("删除消息") -+ @ApiOperation(value = "删除消息", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "删除指定的用户消息记录,删除后不可恢复。") - @DeleteMapping("/{id}") - public Result deleteMessage( - @RequestParam("userId") Long userId, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpUserController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpUserController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpUserController.java -index 69c0674..67190a9 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpUserController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpUserController.java -@@ -22,7 +22,7 @@ import java.util.Map; - * C端用户内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/user") - @RequiredArgsConstructor -@@ -37,26 +37,37 @@ public class InternalMpUserController { - - // ==================== Auth ==================== - -- @ApiOperation("发送短信验证码") -+ @ApiOperation(value = "发送短信验证码", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "向指定手机号发送6位数字短信验证码,有效期5分钟,60秒内不可重复发送。") - @PostMapping("/sms/send") - public Result sendSmsCode(@Valid @RequestBody SendSmsRequest request) { - smsService.sendVerificationCode(request.getPhone()); - return Result.success(); - } - -- @ApiOperation("短信登录") -+ @ApiOperation(value = "短信登录", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "小程序用户通过手机号+短信验证码登录,首次登录自动注册。\n" -+ + "返回JWT Token和用户基本信息。") - @PostMapping("/login/sms") - public Result loginBySms(@Valid @RequestBody SmsLoginRequest request) { - return Result.success(userService.loginBySms(request)); - } - -- @ApiOperation("微信登录") -+ @ApiOperation(value = "微信登录", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "小程序用户通过微信授权码(wx.login获取的code)登录,首次登录自动注册。\n" -+ + "返回JWT Token和用户基本信息,含 needProfile 字段标识是否需要补全资料。") - @PostMapping("/login") - public Result login(@Valid @RequestBody LoginRequest request) { - return Result.success(userService.login(request)); - } - -- @ApiOperation("获取用户信息") -+ @ApiOperation(value = "获取用户信息", notes = "内部接口,获取用户个人资料,含真实手机号。" -+ + "\n\n**关联字典**:\n" -+ + "- gender(性别):返回字段gender\n" -+ + "- id_card_type(证件类型):返回字段idCardType") - @GetMapping("/profile") - public Result getProfile(@RequestParam Long userId) { - UserVO vo = userService.getProfile(userId); -@@ -65,21 +76,31 @@ public class InternalMpUserController { - return Result.success(vo); - } - -- @ApiOperation("更新用户信息") -+ @ApiOperation(value = "更新用户信息", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "更新用户个人资料,包括昵称、头像、性别、实名信息等。\n" -+ + "首次补全资料时 realName/idCardType/idCardNo 为必填。\n\n" -+ + "**关联字典**:\n" -+ + "- gender(性别):请求字段gender\n" -+ + "- id_card_type(证件类型):请求字段idCardType") - @PutMapping("/profile") - public Result updateProfile(@RequestParam Long userId, - @Valid @RequestBody UpdateProfileRequest request) { - return Result.success(userService.updateProfile(userId, request)); - } - -- @ApiOperation("用户登出") -+ @ApiOperation(value = "用户登出", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "清除指定用户的登录状态,使Token失效。") - @PostMapping("/logout") - public Result logout(@RequestParam Long userId) { - userService.logout(userId); - return Result.success(); - } - -- @ApiOperation("注销账号") -+ @ApiOperation(value = "注销账号", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "永久注销用户账号(软删除),注销后该手机号可重新注册。") - @DeleteMapping("/account") - public Result deleteAccount(@RequestParam Long userId) { - userService.deleteAccount(userId); -@@ -88,14 +109,18 @@ public class InternalMpUserController { - - // ==================== Favorite ==================== - -- @ApiOperation("添加收藏") -+ @ApiOperation(value = "添加收藏", notes = "内部接口,为用户添加收藏。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):请求参数targetType(SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品, EXPLORE=探索)") - @PostMapping("/favorite") - public Result addFavorite(@RequestParam Long userId, - @Valid @RequestBody FavoriteRequest request) { - return Result.success(favoriteService.addFavorite(userId, request)); - } - -- @ApiOperation("收藏列表") -+ @ApiOperation(value = "收藏列表", notes = "内部接口,获取用户收藏列表。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):请求参数targetType和返回字段targetType(SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品, EXPLORE=探索)") - @GetMapping("/favorite") - public Result> listFavorites(@RequestParam Long userId, - @RequestParam(required = false) String targetType, -@@ -104,7 +129,9 @@ public class InternalMpUserController { - return Result.success(favoriteService.listFavorites(userId, targetType, page, pageSize)); - } - -- @ApiOperation("检查是否已收藏") -+ @ApiOperation(value = "检查是否已收藏", notes = "内部接口,检查用户是否已收藏指定资源。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):请求参数targetType") - @GetMapping("/favorite/check") - public Result checkFavorite(@RequestParam Long userId, - @RequestParam String targetType, -@@ -112,7 +139,9 @@ public class InternalMpUserController { - return Result.success(favoriteService.checkFavorite(userId, targetType, targetId)); - } - -- @ApiOperation("批量删除收藏") -+ @ApiOperation(value = "批量删除收藏", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "根据收藏记录ID列表批量删除用户的收藏记录。") - @DeleteMapping("/favorite/batch") - public Result batchDeleteFavorites(@RequestParam Long userId, - @RequestBody List ids) { -@@ -120,7 +149,9 @@ public class InternalMpUserController { - return Result.success(); - } - -- @ApiOperation("按目标取消收藏") -+ @ApiOperation(value = "按目标取消收藏", notes = "内部接口,按目标类型和ID取消收藏。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):请求参数targetType") - @DeleteMapping("/favorite/by-target") - public Result deleteFavoriteByTarget(@RequestParam Long userId, - @RequestParam String targetType, -@@ -129,7 +160,9 @@ public class InternalMpUserController { - return Result.success(); - } - -- @ApiOperation("取消收藏") -+ @ApiOperation(value = "取消收藏", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "根据收藏记录ID删除单条收藏记录。") - @DeleteMapping("/favorite/{id}") - public Result deleteFavorite(@RequestParam Long userId, @PathVariable Long id) { - favoriteService.deleteFavorite(userId, id); -@@ -138,14 +171,18 @@ public class InternalMpUserController { - - // ==================== Footprint ==================== - -- @ApiOperation("记录足迹") -+ @ApiOperation(value = "记录足迹", notes = "内部接口,记录用户浏览足迹。" -+ + "\n\n**关联字典**:\n" -+ + "- footprint_resource_type(足迹资源类型):请求参数resourceType(SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品)") - @PostMapping("/footprint") - public Result addFootprint(@RequestParam Long userId, - @Valid @RequestBody FootprintRequest request) { - return Result.success(footprintService.addFootprint(userId, request)); - } - -- @ApiOperation("足迹列表") -+ @ApiOperation(value = "足迹列表", notes = "内部接口,获取用户足迹列表。" -+ + "\n\n**关联字典**:\n" -+ + "- footprint_resource_type(足迹资源类型):请求参数resourceType和返回字段resourceType(SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品)") - @GetMapping("/footprint") - public Result> listFootprints(@RequestParam Long userId, - @RequestParam(required = false) String resourceType, -@@ -154,7 +191,9 @@ public class InternalMpUserController { - return Result.success(footprintService.listFootprints(userId, resourceType, page, pageSize)); - } - -- @ApiOperation("批量删除足迹") -+ @ApiOperation(value = "批量删除足迹", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "根据足迹记录ID列表批量删除用户的浏览足迹。") - @DeleteMapping("/footprint/batch") - public Result batchDeleteFootprints(@RequestParam Long userId, - @RequestBody List ids) { -@@ -162,7 +201,9 @@ public class InternalMpUserController { - return Result.success(); - } - -- @ApiOperation("删除足迹") -+ @ApiOperation(value = "删除足迹", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "根据足迹记录ID删除单条浏览足迹。") - @DeleteMapping("/footprint/{id}") - public Result deleteFootprint(@RequestParam Long userId, @PathVariable Long id) { - footprintService.deleteFootprint(userId, id); -@@ -171,26 +212,45 @@ public class InternalMpUserController { - -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalOrderUserController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalOrderUserController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalOrderUserController.java -index df5bc72..581cc22 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalOrderUserController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalOrderUserController.java -@@ -17,7 +17,7 @@ import java.util.Map; - /** - * Internal API for order service - */ --@Api(tags = "【内部接口】订单用户(Feign调用)") -+@Api(tags = "【内部接口】订单用户(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/order/user") - @RequiredArgsConstructor -@@ -25,7 +25,10 @@ public class InternalOrderUserController { - - private final UserService userService; - -- @ApiOperation("获取用户基本信息(供订单服务查询使用)") -+ @ApiOperation(value = "获取用户基本信息(供订单服务查询使用)", -+ notes = "内部服务间调用接口,由 hl-order-service 通过 Feign 调用。\n" -+ + "根据 userId 获取用户基本信息(userId、realName、phone),用于订单详情展示。\n" -+ + "**注意**:返回的手机号为真实手机号(未脱敏)。") - @GetMapping("/info") - public Result> getUserInfo(@RequestParam Long userId) { - User user = userService.getById(userId); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalTopicController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalTopicController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalTopicController.java -index fba4363..e432e26 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalTopicController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalTopicController.java -@@ -16,7 +16,7 @@ import java.util.List; - * 探索专题内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/topic") - @RequiredArgsConstructor -@@ -24,7 +24,9 @@ public class InternalTopicController { - - private final TopicService topicService; - -- @ApiOperation("获取当前有效专题列表") -+ @ApiOperation(value = "获取当前有效专题列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取所有状态为启用的探索专题列表,按排序号排列,用于小程序探索页面展示。") - @GetMapping("/active") - public Result> listActiveTopics() { - return Result.success(topicService.listActiveTopics()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalUserController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalUserController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalUserController.java -index 6e38f29..d41fb78 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalUserController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalUserController.java -@@ -29,7 +29,7 @@ import java.util.*; - import java.util.stream.Collectors; - - @Slf4j --@Api(tags = "【内部接口】用户信息(Feign调用)") -+@Api(tags = "【内部接口】用户信息(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/user") - @RequiredArgsConstructor -@@ -44,7 +44,8 @@ public class InternalUserController { - private final WechatMiniAppClient wechatMiniAppClient; - private final UserService userService; - -- @ApiOperation("Get admin basic info by ID") -+ @ApiOperation(value = "根据ID获取管理员基本信息", notes = "内部接口,供其他服务通过Feign查询管理员基础信息(ID、用户名、头像、企微姓名)。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/admin/info/{adminId}") - public Result getAdminInfo(@PathVariable Long adminId) { - AdminUser admin = adminUserMapper.selectById(adminId); -@@ -55,7 +56,9 @@ public class InternalUserController { - return Result.success(toBasicDTO(admin, wechatNameMap)); - } - -- @ApiOperation("Batch get admin basic info") -+ @ApiOperation(value = "批量获取管理员基本信息", notes = "内部接口,批量查询多个管理员的基础信息。" -+ + "传入adminId列表,返回对应的管理员信息列表。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/admin/batch-info") - public Result> batchGetAdminInfo(@RequestBody List adminIds) { - if (adminIds == null || adminIds.isEmpty()) { -@@ -69,7 +72,9 @@ public class InternalUserController { - return Result.success(result); - } - -- @ApiOperation("Get all departments") -+ @ApiOperation(value = "获取所有部门列表", notes = "内部接口,获取企业微信同步的所有部门数据。" -+ + "用于通知规则配置等场景中的部门选择。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/departments") - public Result> getDepartments() { - List depts = wechatDepartmentMapper.selectList(null); -@@ -85,7 +90,10 @@ public class InternalUserController { - return Result.success(result); - } - -- @ApiOperation("Get admin IDs belonging to a department") -+ @ApiOperation(value = "获取部门下的管理员ID列表", notes = "内部接口,查询指定部门下所有活跃管理员的ID。" -+ + "通过企微用户的部门归属关联到管理员账号。" -+ + "用于通知规则引擎按部门发送通知。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/admin/dept-members/{deptId}") - public Result> getDeptAdminIds(@PathVariable Long deptId) { - // Find wechat users in this department using FIND_IN_SET for exact match -@@ -113,7 +121,9 @@ public class InternalUserController { - return Result.success(adminIds); - } - -- @ApiOperation("Get admins by role key") -+ @ApiOperation(value = "根据角色标识获取管理员列表", notes = "内部接口,根据角色标识(如CUSTOMIZER、FINANCE等)查询该角色下所有活跃管理员。" -+ + "用于通知规则引擎按角色发送通知。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/admin/by-role-key") - public Result> getAdminsByRoleKey(@RequestParam String roleKey) { - if (roleKey == null || roleKey.isBlank()) { -@@ -148,7 +158,10 @@ public class InternalUserController { - return Result.success(result); - } - -- @ApiOperation("Find C-end user ID by phone number") -+ @ApiOperation(value = "根据手机号查找C端用户ID", notes = "内部接口,根据手机号查找活跃的小程序用户。" -+ + "用于订单绑定流程中通过联系人手机号匹配用户。" -+ + "找不到时返回null(不报错)。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/find-by-phone") - public Result findUserByPhone(@RequestParam String phone) { - if (phone == null || phone.isBlank()) { -@@ -162,7 +175,9 @@ public class InternalUserController { - return Result.success(user != null ? user.getUserId() : null); - } - -- @ApiOperation("Generate mini program URL Link for sharing") -+ @ApiOperation(value = "生成小程序URL Link", notes = "内部接口,生成小程序短链接用于分享。" -+ + "通过微信API生成URL Link,可在浏览器/短信中打开小程序指定页面。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/wechat/miniapp/generate-url-link") - public Result> generateUrlLink( - @RequestParam String path, @RequestParam String query) { -@@ -170,7 +185,10 @@ public class InternalUserController { - return Result.success(result); - } - -- @ApiOperation("Send WeChat message to users") -+ @ApiOperation(value = "发送企业微信消息", notes = "内部接口,向指定的企微用户发送文本消息。" -+ + "toUserIds为企微用户ID列表,支持一次发送给多人。" -+ + "用于审批通知、订单提醒等场景。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/wechat/send-message") - public Result sendWechatMessage(@RequestBody WechatMessageDTO dto) { - if (dto.getToUserIds() == null || dto.getToUserIds().isEmpty()) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalWechatController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWechatController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWechatController.java -index e0d5a6d..d192b76 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWechatController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWechatController.java -@@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.*; - * No JWT auth required (excluded from TokenInterceptor via /internal/** pattern). - */ - @Slf4j --@Api(tags = "【内部接口】企微同步(Feign调用)") -+@Api(tags = "【内部接口】企微同步(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/wechat") - @RequiredArgsConstructor -@@ -27,9 +27,11 @@ public class InternalWechatController { - private final WechatSyncService wechatSyncService; - private final ExternalContactNotifyService externalContactNotifyService; - -- @ApiOperation("Sync single user from callback") -+ @ApiOperation(value = "同步单个企微用户(回调触发)", notes = "内部接口,由hl-callback-service在收到企微通讯录变更回调时调用。" -+ + "将单个用户的信息同步到本地wechat_user表。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/user/sync") -- public Result syncUser(@RequestBody WechatUserSyncDTO dto) { -+ public Result syncUser(@RequestBody WechatUserSyncDTO dto) { - log.info("Internal: sync user userid={}", dto.getUserid()); - try { - wechatSyncService.syncSingleUserFromDto(dto); -@@ -40,9 +42,11 @@ public class InternalWechatController { - } - } - -- @ApiOperation("Delete single user from callback") -+ @ApiOperation(value = "删除单个企微用户(回调触发)", notes = "内部接口,由hl-callback-service在收到企微成员离职回调时调用。" -+ + "从本地wechat_user表中删除该用户记录。" -+ + "不经过Gateway,仅服务间调用。") - @DeleteMapping("/user/{userid}") -- public Result deleteUser(@PathVariable("userid") String userid) { -+ public Result deleteUser(@PathVariable("userid") String userid) { - log.info("Internal: delete user userid={}", userid); - try { - wechatSyncService.deleteSingleUser(userid); -@@ -53,9 +57,11 @@ public class InternalWechatController { - } - } - -- @ApiOperation("Sync single department from callback") -+ @ApiOperation(value = "同步单个企微部门(回调触发)", notes = "内部接口,由hl-callback-service在收到企微部门变更回调时调用。" -+ + "将单个部门的信息同步到本地wechat_department表。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/department/sync") -- public Result syncDepartment(@RequestBody WechatDeptSyncDTO dto) { -+ public Result syncDepartment(@RequestBody WechatDeptSyncDTO dto) { - log.info("Internal: sync department deptId={}", dto.getId()); - try { - wechatSyncService.syncSingleDepartmentFromDto(dto); -@@ -66,18 +72,22 @@ public class InternalWechatController { - } - } - -- @ApiOperation("Receive external contact change event") -+ @ApiOperation(value = "接收外部联系人变更事件", notes = "内部接口,由hl-callback-service在收到企微外部联系人变更回调时调用。" -+ + "处理客户添加/删除等事件,异步执行通知逻辑。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/external-contact/event") -- public Result handleExternalContactEvent(@RequestBody ExternalContactEventDTO dto) { -+ public Result handleExternalContactEvent(@RequestBody ExternalContactEventDTO dto) { - log.info("Internal: external contact event changeType={}, userId={}, externalUserId={}", - dto.getChangeType(), dto.getUserId(), dto.getExternalUserId()); - externalContactNotifyService.processEventAsync(dto); - return Result.success(); - } - -- @ApiOperation("Delete single department from callback") -+ @ApiOperation(value = "删除单个企微部门(回调触发)", notes = "内部接口,由hl-callback-service在收到企微部门删除回调时调用。" -+ + "从本地wechat_department表中删除该部门记录。" -+ + "不经过Gateway,仅服务间调用。") - @DeleteMapping("/department/{deptId}") -- public Result deleteDepartment(@PathVariable("deptId") Long deptId) { -+ public Result deleteDepartment(@PathVariable("deptId") Long deptId) { - log.info("Internal: delete department deptId={}", deptId); - try { - wechatSyncService.deleteSingleDepartment(deptId); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalWishController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWishController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWishController.java -index 44641ef..e3cf403 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWishController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWishController.java -@@ -15,7 +15,7 @@ import java.util.Map; - * 祈愿内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/wish") - @RequiredArgsConstructor -@@ -23,13 +23,17 @@ public class InternalWishController { - - private final WishService wishService; - -- @ApiOperation("获取用户祈愿列表") -+ @ApiOperation(value = "获取用户祈愿列表", notes = "内部接口,获取用户的祈愿列表。" -+ + "\n\n**关联字典**:\n" -+ + "- wish_type(心愿类型):返回字段wishType(1=想去的地方, 2=想做的事, 3=其他)") - @GetMapping - public Result> listWishes(@RequestParam Long userId) { - return Result.success(wishService.listWishes(userId)); - } - -- @ApiOperation("创建祈愿") -+ @ApiOperation(value = "创建祈愿", notes = "内部接口,创建用户祈愿。" -+ + "\n\n**关联字典**:\n" -+ + "- wish_type(心愿类型):请求参数wishType(1=想去的地方, 2=想做的事, 3=其他)") - @PostMapping - public Result createWish(@RequestParam Long userId, - @RequestBody Map request) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/OfficialAccountCallbackController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/OfficialAccountCallbackController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/OfficialAccountCallbackController.java -index 5acc247..753577c 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/OfficialAccountCallbackController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/OfficialAccountCallbackController.java -@@ -24,7 +24,7 @@ import java.util.Map; - @RestController - @RequestMapping("/oa/callback") - @RequiredArgsConstructor --@Api(tags = "【回调接口】公众号回调") -+@Api(tags = "【回调接口】公众号回调", hidden = true) - public class OfficialAccountCallbackController { - - private final WechatOfficialAccountClient oaClient; -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/PublicDictController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/PublicDictController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/PublicDictController.java -index 6d1ec31..38f0ad6 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/PublicDictController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/PublicDictController.java -@@ -24,7 +24,12 @@ public class PublicDictController { - - private final SysDictService sysDictService; - -- @ApiOperation("获取所有字典数据") -+ @ApiOperation(value = "获取所有字典数据(公开接口)", notes = "获取系统全部字典类型及其字典数据,供小程序C端使用。" -+ + "无需认证即可调用。返回格式与管理端 /admin/dict/all 一致。" -+ + "\n\n**字典层级说明**:\n" -+ + "- 每个元素包含 dictType(编码)、dictName(名称)、dataList(字典数据列表)\n" -+ + "- 前端通过 dictType 匹配业务字段,用 dataList 中的 dictValue/dictLabel 做翻译展示\n" -+ + "- 常用字典:order_status、product_status、id_card_type、gender、traveler_type、favorite_resource_type、footprint_resource_type\n") - @GetMapping("/all") - public Result> getAllDict() { - return Result.success(sysDictService.getAllDictForPublic()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/SysDictController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/SysDictController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/SysDictController.java -index 5be6ee7..260eadd 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/SysDictController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/SysDictController.java -@@ -26,7 +26,14 @@ public class SysDictController { - - // ======================== All Dict ======================== - -- @ApiOperation("获取所有字典数据") -+ @ApiOperation(value = "获取所有字典数据", notes = "获取系统全部字典类型及其字典数据,按字典类型分组返回。" -+ + "用于后台管理系统初始化时一次性加载所有下拉选项。" -+ + "返回结果包含dictType编码、dictName名称、dataList数据列表。" -+ + "需要管理员认证。" -+ + "\n\n**字典层级说明**:\n" -+ + "- 字典类型(SysDictType):一级分类,如 admin_status、order_status、id_card_type 等\n" -+ + "- 字典数据(SysDictData):二级选项,归属于某个字典类型,如 admin_status 下的 ACTIVE/LOCKED/DISABLED\n" -+ + "- 前端通过 dictType 编码查找对应的 dataList,用 dictValue 匹配实际数据进行翻译展示\n") - @GetMapping("/all") - public Result> getAllDict() { - return Result.success(sysDictService.getAllDictForPublic()); -@@ -34,14 +41,21 @@ public class SysDictController { - - // ======================== Dict Type ======================== - -- @ApiOperation("创建字典类型") -+ @ApiOperation(value = "创建字典类型", notes = "新建一个字典类型(如:订单状态、证件类型等)。" -+ + "字典类型编码(dictType)全局唯一,创建后不可修改。" -+ + "需要管理员认证,建议仅SUPER_ADMIN/ADMIN角色操作。" -+ + "\n\n**已有字典类型示例**:\n" -+ + "- admin_status(管理员状态)、common_status(通用状态)、login_status(登录状态)\n" -+ + "- order_status(订单状态)、product_status(产品状态)、rating_level(评价等级)\n" -+ + "- id_card_type(证件类型)、gender(性别)、traveler_type(出行人类型)\n" -+ + "- contact_channel_type(联系方式渠道类型)、favorite_resource_type(收藏资源类型)、footprint_resource_type(足迹资源类型)\n") - @OperationLog(value = "创建字典类型", module = "字典管理") - @PostMapping("/type") - public Result createDictType(@ApiParam("创建字典类型请求") @Valid @RequestBody CreateDictTypeRequest request) { - return Result.success(sysDictService.createDictType(request)); - } - -- @ApiOperation("更新字典类型") -+ @ApiOperation(value = "更新字典类型", notes = "更新字典类型的名称、分类、备注等信息。字典类型编码(dictType)不可修改。") - @OperationLog(value = "更新字典类型", module = "字典管理") - @PutMapping("/type/{id}") - public Result updateDictType(@ApiParam("字典类型ID") @PathVariable Long id, -@@ -49,7 +63,9 @@ public class SysDictController { - return Result.success(sysDictService.updateDictType(id, request)); - } - -- @ApiOperation("删除字典类型") -+ @ApiOperation(value = "删除字典类型", notes = "删除字典类型及其下所有字典数据(软删除)。" -+ + "如果该字典类型已被业务引用,删除后不影响已有数据,但新的表单将无法选择该字典值。" -+ + "需要管理员认证。") - @OperationLog(value = "删除字典类型", module = "字典管理") - @DeleteMapping("/type/{id}") - public Result deleteDictType(@ApiParam("字典类型ID") @PathVariable Long id) { -@@ -57,7 +73,8 @@ public class SysDictController { - return Result.success(); - } - -- @ApiOperation("分页查询字典类型") -+ @ApiOperation(value = "分页查询字典类型", notes = "分页查询字典类型列表,支持按分类(category)筛选。" -+ + "字典类型是字典数据的上级分组,管理字典类型即管理有哪些可供前端使用的下拉选项组。") - @GetMapping("/type") - public Result> listDictTypes( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -66,7 +83,7 @@ public class SysDictController { - return Result.success(sysDictService.listDictTypes(page, pageSize, category)); - } - -- @ApiOperation("根据ID获取字典类型详情") -+ @ApiOperation(value = "根据ID获取字典类型详情", notes = "获取单个字典类型的详细信息,包括编码、名称、分类、状态等。") - @GetMapping("/type/{dictTypeId}") - public Result getDictTypeById(@ApiParam("字典类型ID") @PathVariable Long dictTypeId) { - return Result.success(sysDictService.getDictTypeById(dictTypeId)); -@@ -74,14 +91,16 @@ public class SysDictController { - - // ======================== Dict Data ======================== - -- @ApiOperation("创建字典数据") -+ @ApiOperation(value = "创建字典数据", notes = "在指定字典类型下新增一条字典数据项。" -+ + "dictValue为前端匹配的值(如ACTIVE),dictLabel为前端展示的标签(如'启用')。" -+ + "支持树形字典数据(通过parentId设置父级)。") - @OperationLog(value = "创建字典数据", module = "字典管理") - @PostMapping("/data") - public Result createDictData(@ApiParam("创建字典数据请求") @Valid @RequestBody CreateDictDataRequest request) { - return Result.success(sysDictService.createDictData(request)); - } - -- @ApiOperation("更新字典数据") -+ @ApiOperation(value = "更新字典数据", notes = "更新字典数据项的标签、样式类型、排序号等。dictValue建议不修改以免影响已有业务数据。") - @OperationLog(value = "更新字典数据", module = "字典管理") - @PutMapping("/data/{id}") - public Result updateDictData(@ApiParam("字典数据ID") @PathVariable Long id, -@@ -89,7 +108,7 @@ public class SysDictController { - return Result.success(sysDictService.updateDictData(id, request)); - } - -- @ApiOperation("删除字典数据") -+ @ApiOperation(value = "删除字典数据", notes = "删除指定字典数据项(软删除)。删除后不影响已引用该字典值的业务数据。") - @OperationLog(value = "删除字典数据", module = "字典管理") - @DeleteMapping("/data/{id}") - public Result deleteDictData(@ApiParam("字典数据ID") @PathVariable Long id) { -@@ -97,19 +116,23 @@ public class SysDictController { - return Result.success(); - } - -- @ApiOperation("根据ID获取字典数据详情") -+ @ApiOperation(value = "根据ID获取字典数据详情", notes = "获取单个字典数据项的详细信息,包括dictValue、dictLabel、cssClass等。") - @GetMapping("/data/detail/{dictDataId}") - public Result getDictDataById(@ApiParam("字典数据ID") @PathVariable Long dictDataId) { - return Result.success(sysDictService.getDictDataById(dictDataId)); - } - -- @ApiOperation("按类型查询字典数据(树形结构)") -+ @ApiOperation(value = "按类型查询字典数据(树形结构)", notes = "根据字典类型ID查询其下所有字典数据,以树形结构返回(支持父子级字典数据)。" -+ + "用于多级联动下拉框场景(如省市区)。" -+ + "需要管理员认证。") - @GetMapping("/data/tree/{dictTypeId}") - public Result> getDictDataTree(@ApiParam("字典类型ID") @PathVariable Long dictTypeId) { - return Result.success(sysDictService.getDictDataTree(dictTypeId)); - } - -- @ApiOperation("按类型查询字典数据") -+ @ApiOperation(value = "按类型查询字典数据", notes = "根据字典类型编码(如order_status)查询其下所有字典数据(平铺列表)。" -+ + "用于单层下拉框场景。" -+ + "需要管理员认证。") - @GetMapping("/data/{dictType}") - public Result> getDictDataByType(@ApiParam("字典类型编码") @PathVariable String dictType) { - return Result.success(sysDictService.getDictDataByType(dictType)); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/SysJobController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/SysJobController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/SysJobController.java -index 22b99cb..d58905e 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/SysJobController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/SysJobController.java -@@ -5,9 +5,9 @@ import com.hulalv.common.result.PageResult; - import com.hulalv.common.result.Result; - import com.hulalv.user.dto.CreateJobRequest; - import com.hulalv.user.dto.UpdateJobRequest; --import com.hulalv.user.entity.SysJob; --import com.hulalv.user.entity.SysJobLog; - import com.hulalv.user.service.SysJobService; -+import com.hulalv.user.vo.SysJobLogVO; -+import com.hulalv.user.vo.SysJobVO; - import io.swagger.annotations.Api; - import io.swagger.annotations.ApiOperation; - import io.swagger.annotations.ApiParam; -@@ -24,22 +24,39 @@ public class SysJobController { - - private final SysJobService sysJobService; - -- @ApiOperation("创建定时任务") -+ @ApiOperation(value = "创建定时任务", notes = "创建新的定时任务。" -+ + "invokeTarget格式为'Bean名称.方法名'(如wechatSyncService.syncAll),方法必须是无参公开方法。" -+ + "cronExpression为标准6位Cron表达式(秒 分 时 日 月 周)。" -+ + "创建后任务默认为暂停状态(PAUSED),需手动调用[恢复任务]接口启用。" -+ + "\n\n**关联字典**:\n" -+ + "- job_group(任务分组):DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步\n" -+ + "- job_misfire_policy(执行策略):DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发\n" -+ + "- job_status(任务状态):ACTIVE=启用, PAUSED=已暂停\n\n" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "创建定时任务", module = "定时任务") - @PostMapping -- public Result createJob(@ApiParam("创建定时任务请求") @Valid @RequestBody CreateJobRequest request) { -+ public Result createJob(@ApiParam("创建定时任务请求") @Valid @RequestBody CreateJobRequest request) { - return Result.success(sysJobService.createJob(request)); - } - -- @ApiOperation("更新定时任务") -+ @ApiOperation(value = "更新定时任务", -+ notes = "更新指定定时任务的名称、Cron表达式、调用目标等信息。\n" -+ + "修改Cron表达式后任务将按新的计划执行。\n\n" -+ + "**关联字典**:\n" -+ + "- job_group(任务分组):DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步\n" -+ + "- job_misfire_policy(执行策略):DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发\n\n" -+ + "**权限**:需要SUPER_ADMIN角色。") - @OperationLog(value = "更新定时任务", module = "定时任务") - @PutMapping("/{jobId}") -- public Result updateJob(@ApiParam("定时任务ID") @PathVariable Long jobId, -+ public Result updateJob(@ApiParam("定时任务ID") @PathVariable Long jobId, - @ApiParam("更新定时任务请求") @Valid @RequestBody UpdateJobRequest request) { - return Result.success(sysJobService.updateJob(jobId, request)); - } - -- @ApiOperation("删除定时任务") -+ @ApiOperation(value = "删除定时任务", -+ notes = "删除指定的定时任务(软删除),同时从调度器中移除该任务。\n\n" -+ + "**权限**:需要SUPER_ADMIN角色。\n" -+ + "**注意**:删除后任务将不再执行,但历史执行日志仍可查看。") - @OperationLog(value = "删除定时任务", module = "定时任务") - @DeleteMapping("/{jobId}") - public Result deleteJob(@ApiParam("定时任务ID") @PathVariable Long jobId) { -@@ -47,15 +64,22 @@ public class SysJobController { - return Result.success(); - } - -- @ApiOperation("分页查询定时任务") -+ @ApiOperation(value = "分页查询定时任务", notes = "分页查询定时任务列表。" -+ + "\n\n**关联字典**:\n" -+ + "- job_group(任务分组):DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步\n" -+ + "- job_misfire_policy(执行策略):DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发\n" -+ + "- job_status(任务状态):ACTIVE=启用, PAUSED=已暂停") - @GetMapping -- public Result> listJobs( -+ public Result> listJobs( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, - @ApiParam("每页条数") @RequestParam(defaultValue = "20") int pageSize) { - return Result.success(sysJobService.listJobs(page, pageSize)); - } - -- @ApiOperation("暂停任务") -+ @ApiOperation(value = "暂停任务", notes = "暂停指定的定时任务,任务状态变为PAUSED。" -+ + "暂停后任务不再按Cron计划执行,但可通过[恢复任务]接口重新启用。" -+ + "\n\n**关联字典**:job_status(任务状态):ACTIVE=启用, PAUSED=已暂停\n\n" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "暂停任务", module = "定时任务") - @PostMapping("/{jobId}/pause") - public Result pauseJob(@ApiParam("定时任务ID") @PathVariable Long jobId) { -@@ -63,7 +87,10 @@ public class SysJobController { - return Result.success(); - } - -- @ApiOperation("恢复任务") -+ @ApiOperation(value = "恢复任务", notes = "恢复已暂停的定时任务,任务状态变为ACTIVE。" -+ + "恢复后任务按Cron计划继续执行。" -+ + "\n\n**关联字典**:job_status(任务状态):ACTIVE=启用, PAUSED=已暂停\n\n" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "恢复任务", module = "定时任务") - @PostMapping("/{jobId}/resume") - public Result resumeJob(@ApiParam("定时任务ID") @PathVariable Long jobId) { -@@ -71,7 +98,10 @@ public class SysJobController { - return Result.success(); - } - -- @ApiOperation("立即执行一次") -+ @ApiOperation(value = "立即执行一次", notes = "立即触发一次定时任务的执行,不影响原有的Cron计划。" -+ + "无论任务当前状态是ACTIVE还是PAUSED,都可以手动触发。" -+ + "执行结果可在任务日志中查看。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "立即执行任务", module = "定时任务") - @PostMapping("/{jobId}/trigger") - public Result triggerJob(@ApiParam("定时任务ID") @PathVariable Long jobId) { -@@ -79,9 +109,12 @@ public class SysJobController { - return Result.success(); - } - -- @ApiOperation("查询任务日志") -+ @ApiOperation(value = "查询任务日志", notes = "分页查询指定定时任务的执行日志,按执行时间倒序排列。" -+ + "日志包含执行状态(成功/失败)、执行耗时、异常信息等。" -+ + "\n\n**关联字典**:job_log_status(日志状态):SUCCESS=成功, FAIL=失败\n\n" -+ + "需要管理员认证。") - @GetMapping("/{jobId}/logs") -- public Result> listJobLogs( -+ public Result> listJobLogs( - @ApiParam("定时任务ID") @PathVariable Long jobId, - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, - @ApiParam("每页条数") @RequestParam(defaultValue = "20") int pageSize) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/SysMenuController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/SysMenuController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/SysMenuController.java -index 46e8615..44e4293 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/SysMenuController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/SysMenuController.java -@@ -24,14 +24,27 @@ public class SysMenuController { - - private final SysMenuService sysMenuService; - -- @ApiOperation("创建菜单") -+ @ApiOperation(value = "创建菜单", notes = "创建新的菜单/目录/按钮。" -+ + "menuType取值:DIRECTORY=目录(含子菜单) MENU=页面菜单 BUTTON=操作按钮。" -+ + "目录和菜单需设置path路由路径,菜单还需设置component组件路径。" -+ + "按钮类型需设置permissionCode权限标识(如system:user:add)。" -+ + "需要SUPER_ADMIN角色。" -+ + "\n\n**关联字典**:\n" -+ + "- menu_type(菜单类型):请求/返回字段menuType(DIRECTORY=目录, MENU=菜单, BUTTON=按钮)\n" -+ + "- common_status(通用状态):返回字段status") - @OperationLog(value = "创建菜单", module = "菜单管理") - @PostMapping - public Result createMenu(@ApiParam("创建菜单请求") @Valid @RequestBody CreateMenuRequest request) { - return Result.success(sysMenuService.createMenu(request)); - } - -- @ApiOperation("更新菜单") -+ @ApiOperation(value = "更新菜单", -+ notes = "更新指定菜单的名称、路径、组件、图标、排序、状态等信息。\n\n" -+ + "**权限**:需要SUPER_ADMIN角色。\n" -+ + "**注意**:修改后需清除 Redis 菜单缓存才能生效。\n\n" -+ + "**关联字典**:\n" -+ + "- menu_type(菜单类型):请求字段menuType(DIRECTORY=目录, MENU=菜单, BUTTON=按钮)\n" -+ + "- common_status(通用状态):请求字段status") - @OperationLog(value = "更新菜单", module = "菜单管理") - @PutMapping("/{menuId}") - public Result updateMenu(@ApiParam("菜单ID") @PathVariable Long menuId, -@@ -39,7 +52,11 @@ public class SysMenuController { - return Result.success(sysMenuService.updateMenu(menuId, request)); - } - -- @ApiOperation("删除菜单") -+ @ApiOperation(value = "删除菜单", -+ notes = "删除指定的菜单/目录/按钮(软删除)。\n\n" -+ + "**权限**:需要SUPER_ADMIN角色。\n" -+ + "**注意**:如果该菜单有子菜单,需先删除子菜单才能删除父菜单。" -+ + "删除后需清除 Redis 菜单缓存才能生效。") - @OperationLog(value = "删除菜单", module = "菜单管理") - @DeleteMapping("/{menuId}") - public Result deleteMenu(@ApiParam("菜单ID") @PathVariable Long menuId) { -@@ -47,25 +64,42 @@ public class SysMenuController { - return Result.success(); - } - -- @ApiOperation("获取菜单详情") -+ @ApiOperation(value = "获取菜单详情", -+ notes = "获取指定菜单的详细信息,包括名称、路径、组件、图标、排序、权限标识等。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- menu_type(菜单类型):返回字段menuType(DIRECTORY=目录, MENU=菜单, BUTTON=按钮)\n" -+ + "- common_status(通用状态):返回字段status") - @GetMapping("/{menuId}") - public Result getMenu(@ApiParam("菜单ID") @PathVariable Long menuId) { - return Result.success(sysMenuService.getMenuById(menuId)); - } - -- @ApiOperation("获取完整菜单树") -+ @ApiOperation(value = "获取完整菜单树", notes = "获取系统所有菜单的完整树形结构。" -+ + "用于角色权限配置页面展示完整的菜单树供勾选。" -+ + "仅SUPER_ADMIN可查看完整菜单树。" -+ + "需要管理员认证。" -+ + "\n\n**关联字典**:\n" -+ + "- menu_type(菜单类型):返回字段menuType\n" -+ + "- common_status(通用状态):返回字段status") - @GetMapping("/tree") - public Result> getMenuTree() { - return Result.success(sysMenuService.getMenuTree()); - } - -- @ApiOperation("获取角色菜单树") -+ @ApiOperation(value = "获取角色菜单树", -+ notes = "获取指定角色已分配的菜单树形结构。\n" -+ + "用于角色权限配置页面,展示该角色已拥有的菜单权限。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/tree/role/{roleId}") - public Result> getMenuTreeByRoleId(@ApiParam("角色ID") @PathVariable Long roleId) { - return Result.success(sysMenuService.getMenuTreeByRoleId(roleId)); - } - -- @ApiOperation("获取当前管理员菜单") -+ @ApiOperation(value = "获取当前管理员菜单", notes = "获取当前登录管理员的菜单树(基于其当前角色的权限)。" -+ + "SUPER_ADMIN角色返回完整菜单树,其他角色返回已授权的菜单子集。" -+ + "前端登录后调用此接口动态生成路由和侧边栏菜单。" -+ + "需要管理员认证。") - @GetMapping("/my") - public Result> getMyMenus(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/SysRoleController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/SysRoleController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/SysRoleController.java -index 1e4979d..52f6507 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/SysRoleController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/SysRoleController.java -@@ -25,14 +25,19 @@ public class SysRoleController { - - private final SysRoleService sysRoleService; - -- @ApiOperation("创建角色") -+ @ApiOperation(value = "创建角色", notes = "创建新的系统角色。" -+ + "角色标识(roleKey)全局唯一,创建后不可修改,用于代码中的权限判断。" -+ + "创建后需通过[分配菜单权限]接口为角色授权菜单。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "创建角色", module = "角色管理") - @PostMapping - public Result createRole(@ApiParam("创建角色请求") @Valid @RequestBody CreateRoleRequest request) { - return Result.success(sysRoleService.createRole(request)); - } - -- @ApiOperation("更新角色") -+ @ApiOperation(value = "更新角色", notes = "更新角色名称、状态等信息。角色标识(roleKey)不可修改。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):ACTIVE=启用, DISABLED=禁用\n") - @OperationLog(value = "更新角色", module = "角色管理") - @PutMapping("/{roleId}") - public Result updateRole(@ApiParam("角色ID") @PathVariable Long roleId, -@@ -40,7 +45,10 @@ public class SysRoleController { - return Result.success(sysRoleService.updateRole(roleId, request)); - } - -- @ApiOperation("删除角色") -+ @ApiOperation(value = "删除角色", notes = "删除指定角色(软删除)。" -+ + "如果该角色下还有关联的管理员,将无法删除,需先解除绑定关系。" -+ + "内置角色(SUPER_ADMIN等)不可删除。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "删除角色", module = "角色管理") - @DeleteMapping("/{roleId}") - public Result deleteRole(@ApiParam("角色ID") @PathVariable Long roleId) { -@@ -48,13 +56,17 @@ public class SysRoleController { - return Result.success(); - } - -- @ApiOperation("获取角色详情(含菜单ID)") -+ @ApiOperation(value = "获取角色详情(含菜单ID)", notes = "获取角色基本信息及其已分配的菜单ID列表。" -+ + "返回role对象和menuIds数组,用于角色编辑页面回显已勾选的菜单。" -+ + "需要管理员认证。") - @GetMapping("/{roleId}") - public Result> getRoleDetail(@ApiParam("角色ID") @PathVariable Long roleId) { - return Result.success(sysRoleService.getRoleDetail(roleId)); - } - -- @ApiOperation("分页查询角色") -+ @ApiOperation(value = "分页查询角色", notes = "分页查询系统角色列表,支持按状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):ACTIVE=启用, DISABLED=禁用(筛选条件+列表展示)\n") - @GetMapping - public Result> listRoles( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -63,13 +75,19 @@ public class SysRoleController { - return Result.success(sysRoleService.listRoles(page, pageSize, status)); - } - -- @ApiOperation("获取所有角色(下拉)") -+ @ApiOperation(value = "获取所有角色(下拉)", notes = "获取所有状态正常的角色列表,用于下拉选择框。" -+ + "不分页,返回全部角色。创建管理员、筛选管理员列表时使用。" -+ + "需要管理员认证。") - @GetMapping("/all") - public Result> getAllRoles() { - return Result.success(sysRoleService.getAllRoles()); - } - -- @ApiOperation("分配菜单权限") -+ @ApiOperation(value = "分配菜单权限", notes = "为指定角色分配菜单权限(全量覆盖模式)。" -+ + "传入的menuIds将完全替换该角色原有的菜单权限。" -+ + "分配后该角色的所有在线管理员下次请求 /admin/menu/my 时会获取到新的菜单树。" -+ + "注意:需同步清除Redis中的菜单缓存,否则前端拿到的是旧菜单。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "分配菜单权限", module = "角色管理") - @PutMapping("/{roleId}/menus") - public Result assignMenus(@ApiParam("角色ID") @PathVariable Long roleId, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/TravelerController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/TravelerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/TravelerController.java -index 5f71654..ac3f257 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/TravelerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/TravelerController.java -@@ -22,7 +22,15 @@ public class TravelerController { - - private final TravelerService travelerService; - -- @ApiOperation("新增出行人") -+ @ApiOperation(value = "新增出行人", notes = "为当前用户添加一位出行人信息,用于下单时选择。" -+ + "出行人类型(成人/儿童/婴儿)根据出生日期自动判断,无需手动传入。" -+ + "如果传入身份证号,后端自动校验格式并解析性别。" -+ + "每个用户最多可添加20位出行人。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- gender(性别):请求/返回字段gender(0=女, 1=男)\n" -+ + "- id_card_type(证件类型):请求/返回字段idCardType(ID_CARD=身份证, PASSPORT=护照等)\n" -+ + "- traveler_type(出行人类型):返回字段travelerType(ADULT=成人, CHILD=儿童, INFANT=婴儿,自动计算)") - @PostMapping - public Result addTraveler(HttpServletRequest request, - @ApiParam("出行人信息") @Valid @RequestBody TravelerRequest travelerRequest) { -@@ -31,7 +39,14 @@ public class TravelerController { - return Result.success(traveler); - } - -- @ApiOperation("出行人列表") -+ @ApiOperation(value = "出行人列表", notes = "获取当前用户的所有出行人列表。" -+ + "如果用户已完成实名认证(realName不为空),列表首项会自动注入一个'本人'虚拟出行人(travelerId=0)。" -+ + "默认出行人排在前面,其余按创建时间排序。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- gender(性别):返回字段gender\n" -+ + "- id_card_type(证件类型):返回字段idCardType\n" -+ + "- traveler_type(出行人类型):返回字段travelerType") - @GetMapping - public Result> listTravelers(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -@@ -39,7 +54,11 @@ public class TravelerController { - return Result.success(travelers); - } - -- @ApiOperation("出行人详情") -+ @ApiOperation(value = "出行人详情", notes = "获取指定出行人的详细信息。" -+ + "\n\n**关联字典**:\n" -+ + "- gender(性别):返回字段gender\n" -+ + "- id_card_type(证件类型):返回字段idCardType\n" -+ + "- traveler_type(出行人类型):返回字段travelerType") - @GetMapping("/{travelerId}") - public Result getTraveler(HttpServletRequest request, - @ApiParam("出行人ID") @PathVariable Long travelerId) { -@@ -48,7 +67,11 @@ public class TravelerController { - return Result.success(traveler); - } - -- @ApiOperation("更新出行人") -+ @ApiOperation(value = "更新出行人", notes = "更新指定出行人的信息。" -+ + "\n\n**关联字典**:\n" -+ + "- gender(性别):请求/返回字段gender\n" -+ + "- id_card_type(证件类型):请求/返回字段idCardType\n" -+ + "- traveler_type(出行人类型):返回字段travelerType(自动计算)") - @PutMapping("/{travelerId}") - public Result updateTraveler(HttpServletRequest request, - @ApiParam("出行人ID") @PathVariable Long travelerId, -@@ -58,7 +81,10 @@ public class TravelerController { - return Result.success(traveler); - } - -- @ApiOperation("删除出行人") -+ @ApiOperation(value = "删除出行人", -+ notes = "删除指定的出行人记录(软删除)。\n\n" -+ + "**权限**:需要小程序用户认证。\n" -+ + "**注意**:如果该出行人已关联到未完成的订单,删除不影响订单中的出行人快照数据。") - @DeleteMapping("/{travelerId}") - public Result deleteTraveler(HttpServletRequest request, - @ApiParam("出行人ID") @PathVariable Long travelerId) { -@@ -67,7 +93,10 @@ public class TravelerController { - return Result.success(); - } - -- @ApiOperation("设为默认出行人") -+ @ApiOperation(value = "设为默认出行人", notes = "将指定出行人设为默认。" -+ + "每个用户只能有一个默认出行人,设置新的默认会自动取消原来的默认。" -+ + "默认出行人在下单时会被自动选中。" -+ + "需要小程序用户认证。") - @PutMapping("/{travelerId}/default") - public Result setDefault(HttpServletRequest request, - @ApiParam("出行人ID") @PathVariable Long travelerId) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/UserController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/UserController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/UserController.java -index f5d5dc0..24ecd04 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/UserController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/UserController.java -@@ -29,28 +29,42 @@ public class UserController { - private final SmsService smsService; - private final FavoriteService favoriteService; - -- @ApiOperation("发送短信验证码") -+ @ApiOperation(value = "发送短信验证码", notes = "向指定手机号发送6位数字短信验证码,用于小程序手机号登录。" -+ + "同一手机号60秒内不可重复发送,每日最多发送10次。" -+ + "验证码有效期5分钟。" -+ + "无需认证即可调用。") - @PostMapping("/sms/send") - public Result sendSmsCode(@ApiParam("发送短信验证码请求") @Valid @RequestBody SendSmsRequest request) { - smsService.sendVerificationCode(request.getPhone()); - return Result.success(); - } - -- @ApiOperation("手机号验证码登录") -+ @ApiOperation(value = "手机号验证码登录", notes = "小程序用户通过手机号+短信验证码登录。" -+ + "首次登录自动注册账号,返回JWT Token。" -+ + "登录成功后若needProfile=true,表示需要补充个人信息(实名认证),前端应跳转到信息补充页。" -+ + "无需认证即可调用。") - @PostMapping("/login/sms") - public Result loginBySms(@ApiParam("短信验证码登录请求") @Valid @RequestBody SmsLoginRequest request) { - LoginResponse response = userService.loginBySms(request); - return Result.success(response); - } - -- @ApiOperation("微信登录") -+ @ApiOperation(value = "微信登录", notes = "小程序用户通过微信授权码(wx.login获取的code)登录。" -+ + "可选传入phoneCode用于获取手机号绑定,avatar和nickname用于设置头像昵称。" -+ + "首次登录自动注册,返回JWT Token。needProfile=true表示需补充实名信息。" -+ + "无需认证即可调用。") - @PostMapping("/login") - public Result login(@ApiParam("微信登录请求") @Valid @RequestBody LoginRequest request) { - LoginResponse response = userService.login(request); - return Result.success(response); - } - -- @ApiOperation("获取用户信息") -+ @ApiOperation(value = "获取用户信息", notes = "获取当前登录用户的个人资料,包括昵称、头像、手机号(脱敏)、实名信息等。" -+ + "手机号返回脱敏格式(如138****0000),证件号同样脱敏处理。" -+ + "需要小程序用户认证(Token中的userId)。" -+ + "\n\n**关联字典**:\n" -+ + "- id_card_type(证件类型):ID_CARD=身份证, PASSPORT=护照\n" -+ + "- gender(性别):0=女, 1=男\n") - @GetMapping("/profile") - public Result getProfile(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -@@ -58,7 +72,14 @@ public class UserController { - return Result.success(user); - } - -- @ApiOperation("更新用户信息") -+ @ApiOperation(value = "更新用户信息", notes = "更新当前用户的个人资料。" -+ + "首次登录补充信息时realName/idCardType/idCardNo为必填(使用ProfileCompletion验证组)。" -+ + "如果传入身份证号,后端自动解析性别和出生日期。" -+ + "更新手机号后会自动绑定匹配的待绑定订单。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- id_card_type(证件类型):ID_CARD=身份证, PASSPORT=护照(请求参数idCardType)\n" -+ + "- gender(性别):0=女, 1=男\n") - @PutMapping("/profile") - public Result updateProfile(HttpServletRequest request, - @ApiParam("更新用户信息请求") @Valid @RequestBody UpdateProfileRequest updateRequest) { -@@ -67,7 +88,8 @@ public class UserController { - return Result.success(user); - } - -- @ApiOperation("用户登出") -+ @ApiOperation(value = "用户登出", notes = "清除当前用户的登录状态并使Token失效。" -+ + "需要小程序用户认证。") - @PostMapping("/logout") - public Result logout(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -@@ -75,7 +97,10 @@ public class UserController { - return Result.success(); - } - -- @ApiOperation("注销账号") -+ @ApiOperation(value = "注销账号", notes = "永久注销当前用户账号(软删除)。" -+ + "注销后该账号的openid和手机号将被释放,可用于重新注册。" -+ + "注销操作不可撤销,请谨慎调用。" -+ + "需要小程序用户认证。") - @DeleteMapping("/account") - public Result deleteAccount(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -@@ -83,7 +108,12 @@ public class UserController { - return Result.success(); - } - -- @ApiOperation("检查是否已收藏") -+ @ApiOperation(value = "检查是否已收藏", notes = "检查当前用户是否已收藏指定类型的资源。" -+ + "返回true=已收藏,false=未收藏。" -+ + "targetType取值:SCENIC_SPOT/ACTIVITY/HOTEL/PRODUCT/EXPLORE等。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品, EXPLORE=探索(请求参数targetType)\n") - @GetMapping("/favorite/check") - public Result checkFavorite(HttpServletRequest request, - @ApiParam("目标类型") @RequestParam String targetType, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/WechatSyncController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/WechatSyncController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/WechatSyncController.java -index 2b68e9c..03cca6a 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/WechatSyncController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/WechatSyncController.java -@@ -23,7 +23,10 @@ public class WechatSyncController { - - private final WechatSyncService wechatSyncService; - -- @ApiOperation("手动同步部门") -+ @ApiOperation(value = "手动同步部门", notes = "从企业微信拉取最新的部门列表并同步到本地数据库。" -+ + "通常在企业微信后台调整组织架构后手动触发。" -+ + "也可通过定时任务自动执行。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "手动同步部门", module = "企业微信同步") - @PostMapping("/sync/departments") - public Result syncDepartments() { -@@ -31,7 +34,10 @@ public class WechatSyncController { - return Result.success(); - } - -- @ApiOperation("手动同步用户") -+ @ApiOperation(value = "手动同步用户", notes = "从企业微信拉取所有部门的成员列表并同步到本地数据库。" -+ + "包括姓名、手机号、职位、部门归属等信息。" -+ + "需先同步部门再同步用户,或直接使用[同步全部]接口。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "手动同步用户", module = "企业微信同步") - @PostMapping("/sync/users") - public Result syncUsers() { -@@ -39,7 +45,10 @@ public class WechatSyncController { - return Result.success(); - } - -- @ApiOperation("手动同步全部(部门+用户)") -+ @ApiOperation(value = "手动同步全部(部门+用户)", notes = "一键同步企业微信的部门和用户数据,先同步部门再同步用户。" -+ + "推荐使用此接口而非单独同步,确保部门和用户数据一致性。" -+ + "同步过程为异步执行,接口立即返回成功。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "手动同步全部", module = "企业微信同步") - @PostMapping("/sync/all") - public Result syncAll() { -@@ -47,7 +56,13 @@ public class WechatSyncController { - return Result.success(); - } - -- @ApiOperation("查询企业微信用户(分页+搜索)") -+ @ApiOperation(value = "查询企业微信用户(分页+搜索)", notes = "分页查询已同步的企业微信用户列表。" -+ + "支持按姓名/手机号/职位关键词搜索,按部门ID和状态筛选。" -+ + "status取值:1=已激活 2=已禁用 4=未关注。" -+ + "用于管理员绑定企微账号时选择企微用户。" -+ + "需要管理员认证。" -+ + "\n\n**关联字典**:\n" -+ + "- wechat_user_status(企微用户状态):请求参数status和返回字段status(1=已激活, 2=已禁用, 4=未关注)") - @GetMapping("/users") - public Result> listWechatUsers( - @ApiParam("页码") @RequestParam(defaultValue = "1") Integer page, -@@ -58,21 +73,29 @@ public class WechatSyncController { - return Result.success(wechatSyncService.listWechatUsers(page, pageSize, keyword, deptId, status)); - } - -- @ApiOperation("部门列表(部门管理页面)") -+ @ApiOperation(value = "部门列表(部门管理页面)", -+ notes = "获取已同步的所有企业微信部门列表(平铺结构),用于部门管理页面展示。\n" -+ + "包含部门ID、名称、上级部门ID、排序等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/departments") - public Result> listAllDepartments() { - List departments = wechatSyncService.listAllDepartments(); - return Result.success(departments); - } - -- @ApiOperation("部门树(下拉筛选)") -+ @ApiOperation(value = "部门树(下拉筛选)", notes = "以树形结构返回企业微信部门数据。" -+ + "用于部门筛选下拉框,每个节点包含id/label/children。" -+ + "需要管理员认证。") - @GetMapping("/departments/tree") - public Result>> listDepartmentsTree() { - List> tree = wechatSyncService.listDepartmentsTree(); - return Result.success(tree); - } - -- @ApiOperation("同步状态(最后同步时间)") -+ @ApiOperation(value = "同步状态(最后同步时间)", -+ notes = "获取企业微信数据的最后同步时间和状态。\n" -+ + "返回部门和用户各自的最后同步时间,用于管理页面展示同步状态。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/sync/status") - public Result> getSyncStatus() { - Map status = wechatSyncService.getSyncStatus(); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/controller/AdminNotificationController.java` (M) - -接口变更 diff: -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/controller/AdminNotificationController.java b/hl-user-service/src/main/java/com/hulalv/user/notification/controller/AdminNotificationController.java -index d2b7b8d..aa20c4b 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/controller/AdminNotificationController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/controller/AdminNotificationController.java -@@ -45,7 +45,10 @@ public class AdminNotificationController { - - // ==================== 事件配置 ==================== - -- @ApiOperation("获取通知配置列表(按分类分组)") -+ @ApiOperation(value = "获取通知配置列表(按分类分组)", notes = "获取所有通知事件配置,按消息分类(categoryCode)分组返回。" -+ + "每个事件配置包含各通知渠道的开关状态(smsEnabled/inappEnabled/weworkEnabled等)。" -+ + "\n\n**关联字典**:\n" -+ + "- notification_channel(通知渠道):sms=短信, inapp=站内信, wework=企业微信, miniapp_subscribe=小程序订阅消息, official_account=公众号模板消息\n") - @GetMapping("/config") - public Result>> listConfigs() { - Map> grouped = configService.listGroupedByCategory(); -@@ -66,7 +69,9 @@ public class AdminNotificationController { - return Result.success(result); - } - -- @ApiOperation("切换通道开关") -+ @ApiOperation(value = "切换通道开关", notes = "切换指定通知事件的某个渠道开关。" -+ + "channel取值:sms/inapp/wework/miniapp_subscribe/official_account。" -+ + "注意:只允许开启渠道,不建议关闭已有渠道。") - @PutMapping("/config/{id}/toggle") - public Result toggleChannel(@PathVariable Long id, - @Valid @RequestBody ChannelToggleRequest request) { -@@ -74,7 +79,10 @@ public class AdminNotificationController { - return Result.success(); - } - -- @ApiOperation("编辑事件配置详情") -+ @ApiOperation(value = "编辑事件配置详情", -+ notes = "更新指定通知事件配置的详细信息,包括模板内容、接收人规则等。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:修改模板内容后会立即影响后续的通知发送。") - @PutMapping("/config/{id}") - public Result updateConfig(@PathVariable Long id, - @Valid @RequestBody EventConfigUpdateRequest request) { -@@ -84,7 +92,11 @@ public class AdminNotificationController { - return Result.success(); - } - -- @ApiOperation("测试发送") -+ @ApiOperation(value = "测试发送", -+ notes = "使用测试数据触发一次通知发送,验证通知配置是否正确。\n" -+ + "会使用预设的测试参数(订单号、产品名等)填充模板。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:需指定 testUserId 或 testAdminId 作为接收人,发送结果可在发送日志中查看。") - @PostMapping("/config/{id}/test") - public Result testSend(@PathVariable Long id, - @Valid @RequestBody TestSendRequest request) { -@@ -125,7 +137,10 @@ public class AdminNotificationController { - - // ==================== 消息分类 ==================== - -- @ApiOperation("获取消息分类列表") -+ @ApiOperation(value = "获取消息分类列表", -+ notes = "获取所有通知消息分类,包括分类编码、名称、图标、描述等。\n" -+ + "消息分类用于将通知事件归组管理(如订单消息、系统消息等)。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/categories") - public Result> listCategories() { - List categories = categoryService.listAll(); -@@ -135,7 +150,10 @@ public class AdminNotificationController { - return Result.success(voList); - } - -- @ApiOperation("创建消息分类") -+ @ApiOperation(value = "创建消息分类", -+ notes = "创建新的通知消息分类,用于归组管理通知事件。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:分类编码(code)必须唯一,创建后不可修改。") - @PostMapping("/categories") - public Result createCategory(@Valid @RequestBody CategoryRequest request) { - MessageCategory category = new MessageCategory(); -@@ -148,7 +166,10 @@ public class AdminNotificationController { - return Result.success(); - } - -- @ApiOperation("更新消息分类") -+ @ApiOperation(value = "更新消息分类", -+ notes = "更新指定消息分类的名称、图标、描述、排序等信息。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:分类编码(code)不可修改。") - @PutMapping("/categories/{id}") - public Result updateCategory(@PathVariable Long id, - @Valid @RequestBody CategoryRequest request) { -@@ -161,7 +182,10 @@ public class AdminNotificationController { - return Result.success(); - } - -- @ApiOperation("删除消息分类") -+ @ApiOperation(value = "删除消息分类", -+ notes = "删除指定的消息分类。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:如果该分类下有关联的通知事件配置,需先移除关联后才能删除。") - @DeleteMapping("/categories/{id}") - public Result deleteCategory(@PathVariable Long id) { - categoryService.delete(id); -@@ -170,13 +194,18 @@ public class AdminNotificationController { - - // ==================== 发送日志 ==================== - -- @ApiOperation("查询发送日志") -+ @ApiOperation(value = "查询发送日志", notes = "分页查询通知发送日志,支持按事件编码、渠道、状态等筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- notification_channel(通知渠道):返回字段channel\n" -+ + "- notification_send_status(发送状态):返回字段status(SUCCESS=成功, FAILED=失败, SKIPPED=跳过)\n") - @GetMapping("/logs") - public Result> queryLogs(LogQueryRequest request) { - return Result.success(sendLogService.queryLogs(request)); - } - -- @ApiOperation("获取发送统计") -+ @ApiOperation(value = "获取发送统计", -+ notes = "获取通知发送的统计数据,包括总发送数、成功数、失败数、各渠道发送量等。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/logs/stats") - public Result getLogStats() { - return Result.success(sendLogService.getStats()); -@@ -184,7 +213,11 @@ public class AdminNotificationController { - - // ==================== 自定义推送 ==================== - -- @ApiOperation("自定义推送") -+ @ApiOperation(value = "自定义推送", -+ notes = "向指定用户发送自定义通知消息,支持选择推送渠道和目标用户。\n" -+ + "用于运营人员手动推送活动通知、系统公告等。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:推送记录会记入发送日志。") - @PostMapping("/custom-push") - public Result customPush(@Valid @RequestBody CustomPushRequest request, - HttpServletRequest httpRequest) { -@@ -193,7 +226,10 @@ public class AdminNotificationController { - return Result.success(result); - } - -- @ApiOperation("搜索用户(自定义推送选择目标)") -+ @ApiOperation(value = "搜索用户(自定义推送选择目标)", -+ notes = "按关键词搜索C端用户,用于自定义推送时选择推送目标。\n" -+ + "支持按真实姓名或手机号模糊搜索,最多返回20条结果。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/custom-push/users") - public Result> searchUsersForPush(@RequestParam(required = false) String keyword) { - LambdaQueryWrapper wrapper = new LambdaQueryWrapper() -``` - -## DTO/VO 字段变更 - -### `hl-user-service/src/main/java/com/hulalv/user/vo/SysJobLogVO.java` (A) - -> **新增** -```java -package com.hulalv.user.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import java.time.LocalDateTime; - -@Data -@ApiModel("定时任务执行日志") -public class SysJobLogVO { - @ApiModelProperty("日志ID") - private Long jobLogId; - - @ApiModelProperty("任务ID") - private Long jobId; - - @ApiModelProperty("任务名称") - private String jobName; - - @ApiModelProperty("调用目标") - private String invokeTarget; - - @ApiModelProperty(value = "执行状态", notes = "字典类型:job_log_status。可选值:SUCCESS=成功, FAIL=失败") - private String status; - - @ApiModelProperty("执行结果/异常信息") - private String message; - - @ApiModelProperty("开始时间") - private LocalDateTime startTime; - - @ApiModelProperty("结束时间") - private LocalDateTime endTime; - - @ApiModelProperty("创建时间") - private LocalDateTime createdAt; -} -``` - -### `hl-user-service/src/main/java/com/hulalv/user/vo/SysJobVO.java` (A) - -> **新增** -```java -package com.hulalv.user.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import java.time.LocalDateTime; - -@Data -@ApiModel("定时任务信息") -public class SysJobVO { - @ApiModelProperty("任务ID") - private Long jobId; - - @ApiModelProperty("任务名称") - private String jobName; - - @ApiModelProperty(value = "任务分组", notes = "字典类型:job_group。可选值:DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步") - private String jobGroup; - - @ApiModelProperty("调用目标(Bean名称.方法名)") - private String invokeTarget; - - @ApiModelProperty("Cron表达式") - private String cronExpression; - - @ApiModelProperty(value = "计划执行策略", notes = "字典类型:job_misfire_policy。可选值:DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发") - private String misfirePolicy; - - @ApiModelProperty("是否允许并发执行") - private Boolean concurrent; - - @ApiModelProperty(value = "任务状态", notes = "字典类型:job_status。可选值:ACTIVE=启用, PAUSED=已暂停") - private String status; - - @ApiModelProperty("备注") - private String remark; - - @ApiModelProperty("创建时间") - private LocalDateTime createdAt; - - @ApiModelProperty("更新时间") - private LocalDateTime updatedAt; -} -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/vo/ChatMessageVO.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/vo/ChatMessageVO.java b/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/vo/ChatMessageVO.java -index cc334e0..001c095 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/vo/ChatMessageVO.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/vo/ChatMessageVO.java -@@ -1,15 +1,33 @@ - package com.hulalv.callback.msgaudit.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("聊天消息VO") - public class ChatMessageVO { -+ @ApiModelProperty("消息ID") - private String msgId; -+ -+ @ApiModelProperty("发送人ID") - private String fromUser; -+ -+ @ApiModelProperty("发送人姓名") - private String fromUserName; -+ -+ @ApiModelProperty("发送人头像") - private String fromUserAvatar; -+ -+ @ApiModelProperty("群聊ID") - private String roomId; -+ -+ @ApiModelProperty("消息时间戳") - private Long msgTime; -+ -+ @ApiModelProperty("消息类型") - private String msgType; -+ -+ @ApiModelProperty("消息内容") - private String content; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/AdminBasicDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/AdminBasicDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/AdminBasicDTO.java -index 4384bbc..d7ae755 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/AdminBasicDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/AdminBasicDTO.java -@@ -1,14 +1,26 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - import java.io.Serializable; - - @Data -+@ApiModel("管理员基本信息") - public class AdminBasicDTO implements Serializable { -+ @ApiModelProperty("管理员ID") - private Long adminId; -+ -+ @ApiModelProperty("用户名") - private String username; -+ -+ @ApiModelProperty("头像URL") - private String avatarUrl; -+ -+ @ApiModelProperty("企微用户ID") - private String wechatUserid; -+ -+ @ApiModelProperty("企微用户名称") - private String wechatName; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/DepartmentDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/DepartmentDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/DepartmentDTO.java -index 54e49c6..d957404 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/DepartmentDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/DepartmentDTO.java -@@ -1,12 +1,20 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - import java.io.Serializable; - - @Data -+@ApiModel("部门信息") - public class DepartmentDTO implements Serializable { -+ @ApiModelProperty("部门ID") - private Long deptId; -+ -+ @ApiModelProperty("部门名称") - private String deptName; -+ -+ @ApiModelProperty("上级部门ID") - private Long parentId; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/ExternalContactEventDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/ExternalContactEventDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/ExternalContactEventDTO.java -index b460471..b5d3084 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/ExternalContactEventDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/ExternalContactEventDTO.java -@@ -1,13 +1,18 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("外部联系人事件") - public class ExternalContactEventDTO { -- /** add_external_contact / del_follow_user / del_external_contact / edit_external_contact */ -+ @ApiModelProperty("变更类型: add_external_contact/del_follow_user/del_external_contact/edit_external_contact") - private String changeType; -- /** Employee enterprise WeChat userid */ -+ -+ @ApiModelProperty("员工企微用户ID") - private String userId; -- /** External contact ID */ -+ -+ @ApiModelProperty("外部联系人ID") - private String externalUserId; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/FileBindRefsDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/FileBindRefsDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/FileBindRefsDTO.java -index dc20c8c..dda68cc 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/FileBindRefsDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/FileBindRefsDTO.java -@@ -1,5 +1,7 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -9,8 +11,14 @@ import java.util.List; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("文件绑定引用请求") - public class FileBindRefsDTO { -+ @ApiModelProperty("业务类型") - private String bizType; -+ -+ @ApiModelProperty("业务ID") - private Long bizId; -+ -+ @ApiModelProperty("文件ID列表") - private List fileIds; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/FileUnbindRefsDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/FileUnbindRefsDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/FileUnbindRefsDTO.java -index 5cc541a..9a26827 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/FileUnbindRefsDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/FileUnbindRefsDTO.java -@@ -1,5 +1,7 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -7,7 +9,11 @@ import lombok.NoArgsConstructor; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("文件解绑引用请求") - public class FileUnbindRefsDTO { -+ @ApiModelProperty("业务类型") - private String bizType; -+ -+ @ApiModelProperty("业务ID") - private Long bizId; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/OrderPayInfoDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/OrderPayInfoDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/OrderPayInfoDTO.java -index 2b8b700..1661e45 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/OrderPayInfoDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/OrderPayInfoDTO.java -@@ -1,5 +1,7 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - import java.math.BigDecimal; - -@@ -7,19 +9,41 @@ import java.math.BigDecimal; - * Order payment info DTO (order-service -> payment-service) - */ - @Data -+@ApiModel("订单支付信息") - public class OrderPayInfoDTO { -+ @ApiModelProperty("订单ID") - private Long orderId; -+ -+ @ApiModelProperty("订单编号") - private String orderNo; -+ -+ @ApiModelProperty("用户ID") - private Long userId; -+ -+ @ApiModelProperty("商户号") - private String mchId; -+ -+ @ApiModelProperty("总价") - private BigDecimal totalPrice; -+ -+ @ApiModelProperty("优惠金额") - private BigDecimal discountAmount; -+ -+ @ApiModelProperty("定金金额") - private BigDecimal depositAmount; -+ -+ @ApiModelProperty("已支付金额") - private BigDecimal paidAmount; -- /** 支付模式: FULL=全款 DEPOSIT=定金+尾款 */ -+ -+ @ApiModelProperty("支付模式: FULL=全款, DEPOSIT=定金+尾款") - private String paymentMode; -+ -+ @ApiModelProperty("订单状态") - private String status; -+ -+ @ApiModelProperty("产品名称") - private String productName; -- /** 是否预定产品: true=预定(定金可不填出行人) false=非预定(支付前必须填出行人) */ -+ -+ @ApiModelProperty("是否预定产品: true=预定(定金可不填出行人), false=非预定(支付前必须填出行人)") - private Boolean isBooking; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/PaymentResultDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/PaymentResultDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/PaymentResultDTO.java -index f39ebfa..7becb52 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/PaymentResultDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/PaymentResultDTO.java -@@ -1,5 +1,7 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - import java.math.BigDecimal; - -@@ -7,9 +9,17 @@ import java.math.BigDecimal; - * Payment result notification DTO (payment-service -> order-service) - */ - @Data -+@ApiModel("支付结果通知") - public class PaymentResultDTO { -+ @ApiModelProperty("订单ID") - private Long orderId; -- private String payType; // FULL / DEPOSIT / BALANCE -+ -+ @ApiModelProperty("支付类型: FULL=全款, DEPOSIT=定金, BALANCE=尾款") -+ private String payType; -+ -+ @ApiModelProperty("支付金额") - private BigDecimal paidAmount; -+ -+ @ApiModelProperty("微信支付交易号") - private String transactionIdWx; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/RefundResultDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/RefundResultDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/RefundResultDTO.java -index 27b0f25..7483c4e 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/RefundResultDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/RefundResultDTO.java -@@ -1,5 +1,7 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - import java.math.BigDecimal; - -@@ -7,8 +9,14 @@ import java.math.BigDecimal; - * Refund result notification DTO (payment-service -> order-service) - */ - @Data -+@ApiModel("退款结果通知") - public class RefundResultDTO { -+ @ApiModelProperty("订单ID") - private Long orderId; -+ -+ @ApiModelProperty("退款金额") - private BigDecimal refundAmount; -+ -+ @ApiModelProperty("微信退款单号") - private String refundIdWx; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/ResourceDetailDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/ResourceDetailDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/ResourceDetailDTO.java -index 1311d05..3cc83c0 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/ResourceDetailDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/ResourceDetailDTO.java -@@ -1,5 +1,7 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Builder; - import lombok.Data; -@@ -16,47 +18,48 @@ import java.util.List; - @Builder - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("资源详情") - public class ResourceDetailDTO { - -- /** 资源ID */ -+ @ApiModelProperty("资源ID") - private String resourceId; - -- /** 资源类型: SCENIC_SPOT/HOTEL/RESTAURANT/ACTIVITY */ -+ @ApiModelProperty("资源类型: SCENIC_SPOT/HOTEL/RESTAURANT/ACTIVITY") - private String resourceType; - -- /** 资源名称 */ -+ @ApiModelProperty("资源名称") - private String name; - -- /** 副标题 */ -+ @ApiModelProperty("副标题") - private String subtitle; - -- /** 简介/描述 */ -+ @ApiModelProperty("简介/描述") - private String description; - -- /** 封面图URL */ -+ @ApiModelProperty("封面图URL") - private String cover; - -- /** 图片URL列表(轮播图) */ -+ @ApiModelProperty("图片URL列表(轮播图)") - private List images; - -- /** 地址 */ -+ @ApiModelProperty("地址") - private String address; - -- /** 经度 */ -+ @ApiModelProperty("经度") - private BigDecimal longitude; - -- /** 纬度 */ -+ @ApiModelProperty("纬度") - private BigDecimal latitude; - -- /** 标签列表 */ -+ @ApiModelProperty("标签列表") - private List tags; - -- /** 图文详情(featureIntro JSON) */ -+ @ApiModelProperty("图文详情(featureIntro JSON)") - private String featureIntro; - -- /** 评分 */ -+ @ApiModelProperty("评分") - private BigDecimal rating; - -- /** 所在城市 */ -+ @ApiModelProperty("所在城市") - private String city; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/TravelerValidationDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/TravelerValidationDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/TravelerValidationDTO.java -index 3defc94..f46a8e4 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/TravelerValidationDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/TravelerValidationDTO.java -@@ -1,5 +1,7 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Builder; - import lombok.Data; -@@ -14,34 +16,23 @@ import java.util.List; - @Builder - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("出行人验证结果") - public class TravelerValidationDTO { -- /** -- * 订单ID -- */ -+ @ApiModelProperty("订单ID") - private Long orderId; - -- /** -- * 需要的出行人数量 -- */ -+ @ApiModelProperty("需要的出行人数量") - private Integer requiredCount; - -- /** -- * 实际填写的出行人数量 -- */ -+ @ApiModelProperty("实际填写的出行人数量") - private Integer actualCount; - -- /** -- * 是否完整(数量足够且信息完整) -- */ -+ @ApiModelProperty("是否完整(数量足够且信息完整)") - private Boolean isComplete; - -- /** -- * 信息不完整的出行人ID列表 -- */ -+ @ApiModelProperty("信息不完整的出行人ID列表") - private List incompleteTravelerIds; - -- /** -- * 验证消息 -- */ -+ @ApiModelProperty("验证消息") - private String message; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/WechatDeptSyncDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/WechatDeptSyncDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/WechatDeptSyncDTO.java -index 6eb1bab..13bb274 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/WechatDeptSyncDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/WechatDeptSyncDTO.java -@@ -1,11 +1,21 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("企微部门同步信息") - public class WechatDeptSyncDTO { -+ @ApiModelProperty("部门ID") - private Long id; -+ -+ @ApiModelProperty("部门名称") - private String name; -+ -+ @ApiModelProperty("上级部门ID") - private Long parentId; -+ -+ @ApiModelProperty("排序值") - private Integer order; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/WechatMessageDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/WechatMessageDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/WechatMessageDTO.java -index 1fae45a..617a3b3 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/WechatMessageDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/WechatMessageDTO.java -@@ -1,12 +1,18 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - import java.io.Serializable; - import java.util.List; - - @Data -+@ApiModel("企微消息推送") - public class WechatMessageDTO implements Serializable { -+ @ApiModelProperty("接收用户ID列表") - private List toUserIds; -+ -+ @ApiModelProperty("消息内容") - private String content; - } -``` - -### `hl-common/src/main/java/com/hulalv/common/dto/WechatUserSyncDTO.java` (M) - -```diff -diff --git a/hl-common/src/main/java/com/hulalv/common/dto/WechatUserSyncDTO.java b/hl-common/src/main/java/com/hulalv/common/dto/WechatUserSyncDTO.java -index f047acc..97a07fc 100644 ---- a/hl-common/src/main/java/com/hulalv/common/dto/WechatUserSyncDTO.java -+++ b/hl-common/src/main/java/com/hulalv/common/dto/WechatUserSyncDTO.java -@@ -1,16 +1,36 @@ - package com.hulalv.common.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("企微用户同步信息") - public class WechatUserSyncDTO { -+ @ApiModelProperty("企微用户ID") - private String userid; -+ -+ @ApiModelProperty("用户名称") - private String name; -+ -+ @ApiModelProperty("所属部门ID(逗号分隔)") - private String department; -+ -+ @ApiModelProperty("职位") - private String position; -+ -+ @ApiModelProperty("手机号") - private String mobile; -+ -+ @ApiModelProperty("性别: 1=男, 2=女, 0=未定义") - private Integer gender; -+ -+ @ApiModelProperty("邮箱") - private String email; -+ -+ @ApiModelProperty("头像URL") - private String avatar; -+ -+ @ApiModelProperty("状态: 1=已激活, 2=已禁用, 4=未激活, 5=退出企业") - private Integer status; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCancelRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCancelRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCancelRequest.java -index 7adbe0a..93a06f8 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCancelRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCancelRequest.java -@@ -1,9 +1,13 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("分片上传取消请求") - public class ChunkUploadCancelRequest { - -+ @ApiModelProperty("上传ID") - private String uploadId; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCompleteRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCompleteRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCompleteRequest.java -index 712c15c..d876fcc 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCompleteRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCompleteRequest.java -@@ -1,9 +1,13 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("分片上传完成请求") - public class ChunkUploadCompleteRequest { - -+ @ApiModelProperty("上传ID") - private String uploadId; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadInitRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadInitRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadInitRequest.java -index 2d94f04..939a630 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadInitRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadInitRequest.java -@@ -1,13 +1,25 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("分片上传初始化请求") - public class ChunkUploadInitRequest { - -+ @ApiModelProperty("文件名") - private String filename; -+ -+ @ApiModelProperty("文件大小(字节)") - private Long fileSize; -+ -+ @ApiModelProperty("文件MIME类型") - private String contentType; -+ -+ @ApiModelProperty("分组标识") - private String groupKey; -+ -+ @ApiModelProperty("文件哈希值") - private String fileHash; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileBatchIdsRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileBatchIdsRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileBatchIdsRequest.java -index 96c2499..449c3b4 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileBatchIdsRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileBatchIdsRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -9,7 +11,9 @@ import java.util.List; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("文件批量ID请求") - public class FileBatchIdsRequest { - -+ @ApiModelProperty("文件ID列表") - private List fileIds; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadConfirmRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadConfirmRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadConfirmRequest.java -index bb85acc..1b1d316 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadConfirmRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadConfirmRequest.java -@@ -1,9 +1,13 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("文件上传确认请求") - public class FileUploadConfirmRequest { - -+ @ApiModelProperty("文件ID") - private String fileId; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadTokenRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadTokenRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadTokenRequest.java -index 4d7a140..ee7cd4e 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadTokenRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadTokenRequest.java -@@ -1,13 +1,25 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("文件上传令牌请求") - public class FileUploadTokenRequest { - -+ @ApiModelProperty("文件名") - private String fileName; -+ -+ @ApiModelProperty("文件大小(字节)") - private Long fileSize; -+ -+ @ApiModelProperty("文件哈希值") - private String fileHash; -+ -+ @ApiModelProperty("分组标识") - private String groupKey; -+ -+ @ApiModelProperty("是否强制使用预签名URL") - private boolean forcePresigned; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadInitVO.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadInitVO.java b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadInitVO.java -index 6cd60b6..9f38bc4 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadInitVO.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadInitVO.java -@@ -1,12 +1,22 @@ - package com.hulalv.material.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("分片上传初始化结果") - public class ChunkUploadInitVO { - -+ @ApiModelProperty("上传ID") - private String uploadId; -+ -+ @ApiModelProperty("分片大小(字节)") - private int chunkSize; -+ -+ @ApiModelProperty("文件ID") - private String fileId; -+ -+ @ApiModelProperty("OSS对象Key") - private String ossKey; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadPartVO.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadPartVO.java b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadPartVO.java -index 1628687..cc0df47 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadPartVO.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadPartVO.java -@@ -1,9 +1,13 @@ - package com.hulalv.material.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("分片上传片段结果") - public class ChunkUploadPartVO { - -+ @ApiModelProperty("分片ETag标识") - private String etag; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileUploadTokenVO.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileUploadTokenVO.java b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileUploadTokenVO.java -index 779f74d..07b2068 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileUploadTokenVO.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileUploadTokenVO.java -@@ -1,28 +1,58 @@ - package com.hulalv.material.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - import java.time.LocalDateTime; - - @Data -+@ApiModel("文件上传令牌结果") - public class FileUploadTokenVO { - -+ @ApiModelProperty("文件ID") - private String fileId; -+ -+ @ApiModelProperty("文件MIME类型") - private String contentType; -+ -+ @ApiModelProperty("上传模式") - private String uploadMode; -+ -+ @ApiModelProperty("预签名上传URL") - private String presignedUrl; -+ -+ @ApiModelProperty("OSS对象Key") - private String ossKey; -+ -+ @ApiModelProperty("过期时间") - private LocalDateTime expireAt; -+ -+ @ApiModelProperty("STS临时凭证") - private StsTokenInfo stsToken; -+ -+ @ApiModelProperty("OSS存储桶名称") - private String bucket; -+ -+ @ApiModelProperty("OSS区域") - private String region; -+ -+ @ApiModelProperty("文件信息(秒传时返回)") - private FileVO file; - - @Data -+ @ApiModel("STS临时凭证信息") - public static class StsTokenInfo { -+ @ApiModelProperty("访问密钥ID") - private String accessKeyId; -+ -+ @ApiModelProperty("访问密钥Secret") - private String accessKeySecret; -+ -+ @ApiModelProperty("安全令牌") - private String securityToken; -+ -+ @ApiModelProperty("过期时间") - private String expiration; - } - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileVO.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileVO.java b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileVO.java -index a5e43b9..90612e6 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileVO.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileVO.java -@@ -1,23 +1,51 @@ - package com.hulalv.material.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - import java.time.LocalDateTime; - - @Data -+@ApiModel("文件信息VO") - public class FileVO { - -+ @ApiModelProperty("文件ID") - private String fileId; -+ -+ @ApiModelProperty("文件名") - private String fileName; -+ -+ @ApiModelProperty("文件类型") - private String fileType; -+ -+ @ApiModelProperty("MIME类型") - private String mimeType; -+ -+ @ApiModelProperty("文件大小(字节)") - private Long fileSize; -+ -+ @ApiModelProperty("文件哈希值") - private String fileHash; -+ -+ @ApiModelProperty("OSS访问URL") - private String ossUrl; -+ -+ @ApiModelProperty("缩略图URL") - private String thumbnailUrl; -+ -+ @ApiModelProperty("预览URL") - private String previewUrl; -+ -+ @ApiModelProperty("分组标识") - private String groupKey; -+ -+ @ApiModelProperty("文件状态") - private String status; -+ -+ @ApiModelProperty("引用次数") - private Integer refCount; -+ -+ @ApiModelProperty("创建时间") - private LocalDateTime createdAt; - } -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/AdminCreateOrderRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminCreateOrderRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminCreateOrderRequest.java -index 8fb0223..48d0a18 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminCreateOrderRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminCreateOrderRequest.java -@@ -35,7 +35,7 @@ public class AdminCreateOrderRequest { - @Min(value = 0) - private int babyCount = 0; - -- @ApiModelProperty(value = "儿童是否需要床位", example = "false") -+ @ApiModelProperty(value = "儿童是否需要床位(影响房间分配和报价计算)", example = "false") - private Boolean childNeedBed = false; - - @ApiModelProperty(value = "团期ID(GROUP产品必填)") -@@ -59,14 +59,14 @@ public class AdminCreateOrderRequest { - @Size(max = 500, message = "备注不能超过500个字符") - private String remark; - -- @ApiModelProperty(value = "用户手机号(可选,用于关联C端用户)", example = "13800138000") -+ @ApiModelProperty(value = "用户手机号(可选,用于关联C端用户)。如匹配到已注册用户则自动绑定订单", example = "13800138000") - @Size(max = 20) - private String userPhone; - - @ApiModelProperty(value = "定制师ID(可选,默认为创建人)", example = "1760000000000010") - private Long customizerId; - -- @ApiModelProperty(value = "支付时限(分钟),不传则使用全局默认值", example = "30") -+ @ApiModelProperty(value = "支付时限(分钟),不传则使用全局默认值。超时未支付订单自动取消", example = "30") - @Min(value = 1, message = "支付时限最少1分钟") - @Max(value = 1440, message = "支付时限最多1440分钟") - private Integer expiryMinutes; -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/AdminRefundReviewRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminRefundReviewRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminRefundReviewRequest.java -index dfdbe7d..3eb5db1 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminRefundReviewRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminRefundReviewRequest.java -@@ -11,11 +11,11 @@ import java.math.BigDecimal; - @Data - @ApiModel("管理员退款审批请求") - public class AdminRefundReviewRequest { -- @ApiModelProperty(value = "审批结果(APPROVE/REJECT)", required = true, example = "APPROVE") -+ @ApiModelProperty(value = "审批结果:APPROVE=通过(自动调起微信退款)、REJECT=拒绝(用户可发起申诉)", required = true, example = "APPROVE") - @NotBlank(message = "审批结果不能为空") - private String action; - -- @ApiModelProperty(value = "实际退款金额(审批通过时可调整)", example = "1500.00") -+ @ApiModelProperty(value = "实际退款金额(审批通过时可调整,不传则使用申请金额)。不能超过订单已付金额", example = "1500.00") - private BigDecimal actualAmount; - - @ApiModelProperty(value = "审批备注", example = "同意全额退款") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/AdminUpdateOrderRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminUpdateOrderRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminUpdateOrderRequest.java -index 2d1c10e..44a424e 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminUpdateOrderRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminUpdateOrderRequest.java -@@ -44,7 +44,7 @@ public class AdminUpdateOrderRequest { - @Min(value = 0, message = "幼童数不能为负") - private Integer babyCount; - -- @ApiModelProperty(value = "商户号", example = "1246532201") -+ @ApiModelProperty(value = "商户号(微信支付商户号,多商户场景使用)", example = "1246532201") - @Size(max = 32, message = "商户号不能超过32个字符") - private String mchId; - -@@ -62,6 +62,6 @@ public class AdminUpdateOrderRequest { - - // Note: discount is now managed via separate discount CRUD endpoints (POST/PUT/DELETE /admin/order/{orderId}/discount) - -- @ApiModelProperty(value = "出行人列表(如提供则替换全部出行人)") -+ @ApiModelProperty(value = "出行人列表(如提供则替换全部出行人,不传则不修改出行人)") - private List travelers; - } -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/CreateWorkOrderRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/CreateWorkOrderRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/CreateWorkOrderRequest.java -index aeb8c8c..b984863 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/CreateWorkOrderRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/CreateWorkOrderRequest.java -@@ -13,11 +13,12 @@ public class CreateWorkOrderRequest { - @NotNull(message = "订单ID不能为空") - private Long orderId; - -- @ApiModelProperty(value = "工单类型: ROOM_CHANGE/ROOM_ADD/CHECKOUT_CHANGE/HOTEL_ISSUE/VEHICLE_CHANGE/SCENIC_ADD/SCENIC_REMOVE/OTHER", required = true) -+ @ApiModelProperty(value = "工单类型: ROOM_CHANGE(换房)/ROOM_ADD(加房)/CHECKOUT_CHANGE(改退房日期)/" + -+ "HOTEL_ISSUE(酒店问题)/VEHICLE_CHANGE(换车)/SCENIC_ADD(加景点)/SCENIC_REMOVE(减景点)/OTHER(其他)", required = true) - @NotBlank(message = "工单类型不能为空") - private String type; - -- @ApiModelProperty(value = "优先级: URGENT/NORMAL", required = true) -+ @ApiModelProperty(value = "优先级: URGENT(紧急,如当天出发需处理)/NORMAL(普通)", required = true) - @NotBlank(message = "优先级不能为空") - private String priority; - -@@ -31,7 +32,7 @@ public class CreateWorkOrderRequest { - @ApiModelProperty("资源详情JSON(酒店/车辆/景点信息)") - private String resourceDetail; - -- @ApiModelProperty("差价(正数=加价, 负数=退费)") -+ @ApiModelProperty("差价(正数=客户需补差价, 负数=需退费给客户)") - private BigDecimal costDifference; - - @ApiModelProperty("指定处理人ID") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/EarlyBirdPlanRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/EarlyBirdPlanRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/EarlyBirdPlanRequest.java -index f2f451c..a678aff 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/EarlyBirdPlanRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/EarlyBirdPlanRequest.java -@@ -24,12 +24,12 @@ public class EarlyBirdPlanRequest { - @NotNull(message = "生效结束日期不能为空") - private LocalDate endDate; - -- @ApiModelProperty(value = "最低人数", required = true, example = "2") -+ @ApiModelProperty(value = "最低出行人数(含成人+儿童),订单人数>=此值才能享受优惠", required = true, example = "2") - @NotNull(message = "最低人数不能为空") - @Min(value = 1, message = "最低人数至少为1") - private Integer minPeople; - -- @ApiModelProperty(value = "优惠金额", required = true, example = "200.00") -+ @ApiModelProperty(value = "优惠金额(从订单总价中扣减的固定金额)", required = true, example = "200.00") - @NotNull(message = "优惠金额不能为空") - @DecimalMin(value = "0.01", message = "优惠金额必须大于0") - private BigDecimal discountAmount; -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/InvoiceApplyRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/InvoiceApplyRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/InvoiceApplyRequest.java -index 125cd6a..9a93336 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/InvoiceApplyRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/InvoiceApplyRequest.java -@@ -13,7 +13,7 @@ public class InvoiceApplyRequest { - @NotNull(message = "orderId is required") - private Long orderId; - -- @ApiModelProperty(value = "抬头类型(personal=个人/company=企业)", example = "personal") -+ @ApiModelProperty(value = "抬头类型:personal=个人(默认)、company=企业(需填写税号)", example = "personal") - private String titleType = "personal"; - - @ApiModelProperty(value = "发票抬头", required = true, example = "张三") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/MpOrderQueryRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/MpOrderQueryRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/MpOrderQueryRequest.java -index 98b28d5..c28453b 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/MpOrderQueryRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/MpOrderQueryRequest.java -@@ -10,7 +10,7 @@ import javax.validation.constraints.Min; - @Data - @ApiModel("C端订单查询请求") - public class MpOrderQueryRequest { -- @ApiModelProperty(value = "订单状态", example = "PAID") -+ @ApiModelProperty(value = "订单状态(不传则查全部)。可选值:PENDING_PAY/DEPOSIT_PAID/PAID/CONFIRMED/PENDING_BALANCE/PENDING_DEPARTURE/TRAVELLING/COMPLETED/AFTER_SALE/REFUNDING/REFUNDED/CANCELLED", example = "PAID") - private String status; - - @ApiModelProperty(value = "页码", example = "1") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/MpUpdateOrderRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/MpUpdateOrderRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/MpUpdateOrderRequest.java -index 9782f64..0b13f71 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/MpUpdateOrderRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/MpUpdateOrderRequest.java -@@ -9,12 +9,12 @@ import java.time.LocalDate; - import java.util.List; - - @Data --@ApiModel("小程序修改订单请求") -+@ApiModel(value = "小程序修改订单请求", description = "用户可修改出发日期和出行人。修改后系统自动重算价格,内部流程已启动的订单会通知定制师") - public class MpUpdateOrderRequest { - -- @ApiModelProperty(value = "出发日期", example = "2026-05-01") -+ @ApiModelProperty(value = "出发日期(修改出发日期会触发价格重算)", example = "2026-05-01") - private LocalDate departureDate; - -- @ApiModelProperty(value = "出行人列表(如提供则替换全部出行人)") -+ @ApiModelProperty(value = "出行人列表(如提供则替换全部出行人,不传则不修改出行人)") - private List travelers; - } -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/RefundApplyRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/RefundApplyRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/RefundApplyRequest.java -index 4d8aa75..7c32a24 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/RefundApplyRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/RefundApplyRequest.java -@@ -11,11 +11,11 @@ import javax.validation.constraints.Size; - @Data - @ApiModel("退款申请请求") - public class RefundApplyRequest { -- @ApiModelProperty(value = "退款类型(字典:refund_type)", required = true, example = "FULL") -+ @ApiModelProperty(value = "退款类型:FULL=全额退款、PARTIAL=部分退款", required = true, example = "FULL") - @NotBlank(message = "退款类型不能为空") - private String refundType; - -- @ApiModelProperty(value = "退款原因ID", example = "1760000000000001") -+ @ApiModelProperty(value = "退款原因ID(从退款原因列表接口获取)", example = "1760000000000001") - private Long reasonId; - - @ApiModelProperty(value = "退款原因", required = true, example = "行程有变,无法出行") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/RefundPolicyRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/RefundPolicyRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/RefundPolicyRequest.java -index cb0873c..a6a18a7 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/RefundPolicyRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/RefundPolicyRequest.java -@@ -42,12 +42,12 @@ public class RefundPolicyRequest { - @Data - @ApiModel("退款规则项") - public static class RuleItem { -- @ApiModelProperty(value = "距出发最少天数", required = true, example = "7") -+ @ApiModelProperty(value = "距出发最少天数(含当天)。例如:minDays=7表示出发前7天及以上适用此规则", required = true, example = "7") - @NotNull(message = "最少天数不能为空") - @Min(value = 0, message = "最少天数不能小于0") - private Integer minDays; - -- @ApiModelProperty(value = "退款比例(百分比)", required = true, example = "80") -+ @ApiModelProperty(value = "退款比例(百分比,0-100)。例如:80表示退已付金额的80%", required = true, example = "80") - @NotNull(message = "退款比例不能为空") - @Min(value = 0, message = "退款比例不能小于0") - @Max(value = 100, message = "退款比例不能超过100") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/UpdateOrderStatusRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/UpdateOrderStatusRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/UpdateOrderStatusRequest.java -index f290109..c40fb91 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/UpdateOrderStatusRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/UpdateOrderStatusRequest.java -@@ -9,7 +9,10 @@ import javax.validation.constraints.NotBlank; - @Data - @ApiModel("更新订单状态请求") - public class UpdateOrderStatusRequest { -- @ApiModelProperty(value = "目标状态(字典:order_status)", required = true, example = "CONFIRMED") -+ @ApiModelProperty(value = "目标状态。可选值:PENDING_PAY(待支付)/DEPOSIT_PAID(已付定金)/PAID(已全额支付)/" + -+ "CONFIRMED(已确认)/PENDING_BALANCE(待付尾款)/PENDING_DEPARTURE(待出行)/" + -+ "TRAVELLING(旅行中)/COMPLETED(已完成)/AFTER_SALE(售后中)/REFUNDING(退款中)/" + -+ "REFUNDED(已退款)/CANCELLED(已取消)", required = true, example = "CONFIRMED") - @NotBlank(message = "状态不能为空") - private String status; - } -``` - -### `hl-order-service/src/main/java/com/hulalv/order/vo/WorkOrderVO.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/vo/WorkOrderVO.java b/hl-order-service/src/main/java/com/hulalv/order/vo/WorkOrderVO.java -index 58106e0..f6bcd64 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/vo/WorkOrderVO.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/vo/WorkOrderVO.java -@@ -82,12 +82,24 @@ public class WorkOrderVO { - private List logs; - - @Data -+ @io.swagger.annotations.ApiModel("工单操作日志VO") - public static class WorkOrderLogVO { -+ @ApiModelProperty("日志ID") - private String logId; -+ -+ @ApiModelProperty("操作动作") - private String action; -+ -+ @ApiModelProperty("操作动作标签") - private String actionLabel; -+ -+ @ApiModelProperty("操作内容") - private String content; -+ -+ @ApiModelProperty("操作人姓名") - private String operatorName; -+ -+ @ApiModelProperty("操作时间") - private LocalDateTime createdAt; - } - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/FamilySaveRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/FamilySaveRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/FamilySaveRequest.java -index 223810b..84591cf 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/FamilySaveRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/FamilySaveRequest.java -@@ -9,7 +9,7 @@ import javax.validation.constraints.NotBlank; - import javax.validation.constraints.Size; - - @Data --@ApiModel("家庭分组保存请求") -+@ApiModel(value = "家庭分组保存请求", description = "仅适用于CUSTOM定制产品,用于将行程按家庭单位分配") - public class FamilySaveRequest { - - @ApiModelProperty(value = "家庭名称", required = true, example = "家庭1") -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/FormulaStepRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/FormulaStepRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/FormulaStepRequest.java -index 4acb045..89b3240 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/FormulaStepRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/FormulaStepRequest.java -@@ -29,7 +29,8 @@ public class FormulaStepRequest { - @ApiModelProperty(value = "执行顺序", example = "1") - private Integer executionOrder; - -- @ApiModelProperty(value = "表达式", required = true, example = "baseCost = adultCount * adultUnitCost + childCount * childUnitCost") -+ @ApiModelProperty(value = "Aviator表达式(支持数学运算、条件判断、内置函数;可引用前置步骤的输出变量和公式变量表中的变量)", -+ required = true, example = "baseCost = adultCount * adultUnitCost + childCount * childUnitCost") - @NotBlank(message = "表达式不能为空") - @Size(max = 2000, message = "表达式不能超过2000个字符") - private String expression; -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchCreateRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchCreateRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchCreateRequest.java -index 70e06ec..2cf6432 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchCreateRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchCreateRequest.java -@@ -8,34 +8,34 @@ import javax.validation.constraints.*; - import java.time.LocalDate; - - @Data --@ApiModel("create group batch request") -+@ApiModel("创建拼团批次请求") - public class GroupBatchCreateRequest { - -- @ApiModelProperty(value = "batch name", required = true, example = "Jul 20 Batch 1") -- @NotBlank(message = "batch name required") -+ @ApiModelProperty(value = "批次名称", required = true, example = "7月20日第1批") -+ @NotBlank(message = "批次名称不能为空") - @Size(max = 128) - private String batchName; - -- @ApiModelProperty(value = "departure date", required = true, example = "2026-07-20") -- @NotNull(message = "departure date required") -+ @ApiModelProperty(value = "出发日期", required = true, example = "2026-07-20") -+ @NotNull(message = "出发日期不能为空") - private LocalDate departureDate; - -- @ApiModelProperty(value = "enrollment deadline", required = true, example = "2026-07-15") -- @NotNull(message = "enrollment deadline required") -+ @ApiModelProperty(value = "报名截止日期,必须早于出发日期", required = true, example = "2026-07-15") -+ @NotNull(message = "报名截止日期不能为空") - private LocalDate enrollmentDeadline; - -- @ApiModelProperty(value = "min participants for group confirmation (0=no limit)", example = "10") -+ @ApiModelProperty(value = "最低成团人数(0=不限制,达到此人数自动变为CONFIRMED状态)", example = "10") - @Min(0) - private int minParticipants = 0; - -- @ApiModelProperty(value = "max participants", required = true, example = "30") -- @Min(value = 1, message = "max participants must be >= 1") -+ @ApiModelProperty(value = "最大参团人数(报名人数达到上限后自动关闭报名)", required = true, example = "30") -+ @Min(value = 1, message = "最大参团人数至少为1") - private int maxParticipants; - -- @ApiModelProperty(value = "remark", example = "summer special batch") -+ @ApiModelProperty(value = "备注说明", example = "暑期特别批次") - @Size(max = 512) - private String remark; - -- @ApiModelProperty(value = "sort order", example = "0") -+ @ApiModelProperty(value = "排序序号(越小越靠前)", example = "0") - private int sortOrder = 0; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchDisbandRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchDisbandRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchDisbandRequest.java -index 369a7ca..ca769e4 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchDisbandRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchDisbandRequest.java -@@ -8,11 +8,11 @@ import javax.validation.constraints.NotBlank; - import javax.validation.constraints.Size; - - @Data --@ApiModel("disband batch request") -+@ApiModel("解散批次请求") - public class GroupBatchDisbandRequest { - -- @ApiModelProperty(value = "disband reason", required = true, example = "insufficient enrollment") -- @NotBlank(message = "disband reason required") -+ @ApiModelProperty(value = "解散原因(如:报名人数不足、行程调整等)", required = true, example = "报名人数不足") -+ @NotBlank(message = "解散原因不能为空") - @Size(max = 512) - private String reason; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchStaffRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchStaffRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchStaffRequest.java -index 8c2f4bb..712181e 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchStaffRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchStaffRequest.java -@@ -9,22 +9,22 @@ import javax.validation.constraints.NotNull; - import javax.validation.constraints.Size; - - @Data --@ApiModel("batch staff assignment request") -+@ApiModel("批次服务人员分配请求") - public class GroupBatchStaffRequest { - -- @ApiModelProperty(value = "staff ID (from resource-service)", required = true, example = "1760000000000001") -- @NotNull(message = "staff ID required") -+ @ApiModelProperty(value = "人员ID(来自资源服务的人员库)", required = true, example = "1760000000000001") -+ @NotNull(message = "人员ID不能为空") - private Long staffId; - -- @ApiModelProperty(value = "role in this batch: LEADER/PHOTOGRAPHER/DRIVER/OTHER", required = true, example = "LEADER") -- @NotBlank(message = "staff role required") -+ @ApiModelProperty(value = "在该批次中的角色:LEADER(领队)/PHOTOGRAPHER(摄影师)/DRIVER(司机)/OTHER(其他)", required = true, example = "LEADER") -+ @NotBlank(message = "人员角色不能为空") - @Size(max = 32) - private String staffRole; - -- @ApiModelProperty(value = "remark", example = "main guide") -+ @ApiModelProperty(value = "备注(如:主导游、备用摄影师等)", example = "主导游") - @Size(max = 256) - private String remark; - -- @ApiModelProperty(value = "sort order", example = "0") -+ @ApiModelProperty(value = "排序序号(越小越靠前)", example = "0") - private int sortOrder = 0; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchUpdateRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchUpdateRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchUpdateRequest.java -index a8e2de6..4532f60 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchUpdateRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchUpdateRequest.java -@@ -9,31 +9,31 @@ import javax.validation.constraints.Size; - import java.time.LocalDate; - - @Data --@ApiModel("update group batch request") -+@ApiModel("更新拼团批次请求") - public class GroupBatchUpdateRequest { - -- @ApiModelProperty(value = "batch name", example = "Jul 20 Batch 1") -+ @ApiModelProperty(value = "批次名称", example = "7月20日第1批") - @Size(max = 128) - private String batchName; - -- @ApiModelProperty(value = "departure date", example = "2026-07-20") -+ @ApiModelProperty(value = "出发日期", example = "2026-07-20") - private LocalDate departureDate; - -- @ApiModelProperty(value = "enrollment deadline", example = "2026-07-15") -+ @ApiModelProperty(value = "报名截止日期", example = "2026-07-15") - private LocalDate enrollmentDeadline; - -- @ApiModelProperty(value = "min participants", example = "10") -+ @ApiModelProperty(value = "最低成团人数(0=不限制)", example = "10") - @Min(0) - private Integer minParticipants; - -- @ApiModelProperty(value = "max participants", example = "30") -+ @ApiModelProperty(value = "最大参团人数(不能低于已报名人数)", example = "30") - @Min(1) - private Integer maxParticipants; - -- @ApiModelProperty(value = "remark") -+ @ApiModelProperty(value = "备注说明") - @Size(max = 512) - private String remark; - -- @ApiModelProperty(value = "sort order") -+ @ApiModelProperty(value = "排序序号") - private Integer sortOrder; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/NodeCreateRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/NodeCreateRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/NodeCreateRequest.java -index a19ae8a..eae3469 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/NodeCreateRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/NodeCreateRequest.java -@@ -37,10 +37,10 @@ public class NodeCreateRequest { - @ApiModelProperty(value = "纬度", example = "26.872108") - private BigDecimal latitude; - -- @ApiModelProperty(value = "关联资源类型:SCENIC_SPOT/HOTEL/RESTAURANT/ACTIVITY/VEHICLE/SERVICE", example = "SCENIC_SPOT") -+ @ApiModelProperty(value = "关联资源类型(关联后可从资源服务获取价格参与成本计算):SCENIC/HOTEL/RESTAURANT/ACTIVITY/VEHICLE/SERVICE", example = "SCENIC") - private String resourceType; - -- @ApiModelProperty(value = "关联资源ID", example = "1893012345678901234") -+ @ApiModelProperty(value = "关联资源ID(来自资源服务,关联后节点名称和图片可自动同步)", example = "1893012345678901234") - private String resourceId; - - @ApiModelProperty(value = "节点描述", example = "漫步古城,感受纳西文化") -@@ -58,6 +58,6 @@ public class NodeCreateRequest { - @ApiModelProperty(value = "数量", example = "1") - private Integer quantity; - -- @ApiModelProperty(value = "所属家庭ID列表(定制产品按家庭分配)") -+ @ApiModelProperty(value = "所属家庭ID列表(仅CUSTOM定制产品使用,实现按家庭分配行程节点)") - private List familyIds; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/PriceCalendarRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/PriceCalendarRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/PriceCalendarRequest.java -index a5188da..dacb69c 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/PriceCalendarRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/PriceCalendarRequest.java -@@ -28,13 +28,13 @@ public class PriceCalendarRequest { - @ApiModelProperty(value = "儿童成本价", example = "1800.00") - private BigDecimal childCostPrice; - -- @ApiModelProperty(value = "是否自动计算成本", example = "true") -+ @ApiModelProperty(value = "是否自动计算成本(true时重新测算会自动更新此日期的价格)", example = "true") - private Boolean costAutoCalc; - -- @ApiModelProperty(value = "库存数量", example = "30") -+ @ApiModelProperty(value = "库存数量(CORE/GROUP按人头扣减,CUSTOM/ROUTE按单扣减)", example = "30") - private Integer stock; - -- @ApiModelProperty(value = "状态:OPEN=开放 CLOSED=关闭", example = "OPEN") -+ @ApiModelProperty(value = "状态:OPEN=开放预订 CLOSED=关闭(不可预订)", example = "OPEN") - private String status; - - @ApiModelProperty(value = "备注", example = "五一黄金周特价") -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/PricingRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/PricingRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/PricingRequest.java -index 28b7e49..a937367 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/PricingRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/PricingRequest.java -@@ -11,10 +11,10 @@ import java.util.List; - @ApiModel("定价配置请求") - public class PricingRequest { - -- @ApiModelProperty(value = "定价模式:AUTO=自动计算 MANUAL=手动定价 CUSTOM=定制定价", example = "AUTO") -+ @ApiModelProperty(value = "定价模式:AUTO=根据行程资源价格自动计算 MANUAL=手动在价格日历设置每日价格 CUSTOM=定制产品整单定价", example = "AUTO") - private String pricingMode; - -- @ApiModelProperty(value = "利润模式:FIXED=固定金额 PERCENT=百分比", example = "FIXED") -+ @ApiModelProperty(value = "利润模式(AUTO模式下生效):FIXED=在成本基础上加固定金额 PERCENT=在成本基础上按百分比加价", example = "FIXED") - private String profitMode; - - @ApiModelProperty(value = "利润金额(FIXED模式下使用)", example = "500.00") -@@ -32,16 +32,16 @@ public class PricingRequest { - @ApiModelProperty(value = "餐费预算", example = "100.00") - private BigDecimal mealBudget; - -- @ApiModelProperty(value = "儿童占床价", example = "1800.00") -+ @ApiModelProperty(value = "儿童加床费(childNeedBed=true时额外加收的费用)", example = "1800.00") - private BigDecimal childWithBed; - -- @ApiModelProperty(value = "儿童不占床价", example = "1200.00") -+ @ApiModelProperty(value = "儿童不占床价(暂未使用,预留字段)", example = "1200.00") - private BigDecimal childNoBed; - -- @ApiModelProperty(value = "婴儿价", example = "300.00") -+ @ApiModelProperty(value = "婴儿固定价格(不随日期变化)", example = "300.00") - private BigDecimal babyPrice; - -- @ApiModelProperty(value = "儿童折扣百分比", example = "70.00") -+ @ApiModelProperty(value = "小童折扣百分比(小童价=儿童价×此百分比/100,如70表示打7折)", example = "70.00") - private BigDecimal childDiscountPercent; - - @ApiModelProperty(value = "车型ID列表") -@@ -56,24 +56,24 @@ public class PricingRequest { - @ApiModelProperty(value = "陪同人员价格", example = "0.00") - private BigDecimal companionPrice; - -- @ApiModelProperty(value = "定制产品总价(CUSTOM模式下使用)", example = "28800.00") -+ @ApiModelProperty(value = "定制产品总价(CUSTOM定价模式下使用,代表整单总价)", example = "28800.00") - private BigDecimal customTotalPrice; - -- @ApiModelProperty(value = "最小成团人数", example = "2") -+ @ApiModelProperty(value = "最小成团人数(CORE/GROUP产品用,影响均摊成本计算)", example = "2") - private Integer minGroupSize; - -- @ApiModelProperty(value = "最大成团人数", example = "16") -+ @ApiModelProperty(value = "最大成团人数(CORE/GROUP产品用)", example = "16") - private Integer maxGroupSize; - -- @ApiModelProperty(value = "支付方式:FULL=全款 DEPOSIT=定金+尾款", example = "FULL") -+ @ApiModelProperty(value = "支付方式:FULL=全款支付 DEPOSIT=定金+尾款分期支付", example = "FULL") - private String paymentType; - -- @ApiModelProperty(value = "定金比例(百分比)", example = "30") -+ @ApiModelProperty(value = "定金比例(百分比,如30代表30%。与depositAmount二选一,优先使用比例)", example = "30") - private Integer depositRatio; - -- @ApiModelProperty(value = "定金金额", example = "1000.00") -+ @ApiModelProperty(value = "定金金额(固定金额,与depositRatio二选一)", example = "1000.00") - private BigDecimal depositAmount; - -- @ApiModelProperty(value = "尾款支付截止天数(出发前N天)", example = "7") -+ @ApiModelProperty(value = "尾款支付截止天数(出发前N天必须支付尾款,超时可能取消订单)", example = "7") - private Integer balanceDueDays; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/ProductStatusRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/ProductStatusRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/ProductStatusRequest.java -index 23e1203..99033be 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/ProductStatusRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/ProductStatusRequest.java -@@ -10,10 +10,11 @@ import javax.validation.constraints.NotBlank; - @ApiModel("产品状态变更请求") - public class ProductStatusRequest { - -- @ApiModelProperty(value = "目标状态:DRAFT/PENDING_REVIEW/REVIEWED/REJECTED/PUBLISHED/UNPUBLISHED/COMPLETED", required = true, example = "PUBLISHED") -+ @ApiModelProperty(value = "目标状态。核心/小蒙马:DRAFT/PENDING_REVIEW/REVIEWED/REJECTED/PUBLISHED/UNPUBLISHED;定制产品:COMPLETED", -+ required = true, example = "PUBLISHED") - @NotBlank(message = "目标状态不能为空") - private String status; - -- @ApiModelProperty(value = "状态变更原因(驳回时必填)", example = "行程信息不完整,请补充") -+ @ApiModelProperty(value = "状态变更原因(驳回时必填;上架/下架审批时可填)", example = "行程信息不完整,请补充") - private String reason; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/QuoteRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/QuoteRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/QuoteRequest.java -index fd39d97..92c28aa 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/QuoteRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/QuoteRequest.java -@@ -21,18 +21,18 @@ public class QuoteRequest { - @Min(value = 1, message = "成人人数最少1人") - private Integer adultCount; - -- @ApiModelProperty(value = "儿童人数(占床)", example = "1") -+ @ApiModelProperty(value = "儿童人数(占床,按儿童价计算)", example = "1") - @Min(value = 0, message = "儿童人数不能为负数") - private Integer childCount = 0; - -- @ApiModelProperty(value = "小童人数(不占床)", example = "0") -+ @ApiModelProperty(value = "小童人数(不占床,按儿童价 × childDiscountPercent 折扣比例计算)", example = "0") - @Min(value = 0, message = "小童人数不能为负数") - private Integer youngChildCount = 0; - -- @ApiModelProperty(value = "婴儿人数", example = "0") -+ @ApiModelProperty(value = "婴儿人数(按固定 babyPrice 计算)", example = "0") - @Min(value = 0, message = "幼童人数不能为负数") - private Integer babyCount = 0; - -- @ApiModelProperty(value = "儿童是否加床", example = "false") -+ @ApiModelProperty(value = "儿童是否加床(true 时额外加收 childWithBed 费用)", example = "false") - private Boolean childNeedBed = false; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/BatchMaterialIdsRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/BatchMaterialIdsRequest.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/BatchMaterialIdsRequest.java -index 46060ff..63b4dc9 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/BatchMaterialIdsRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/BatchMaterialIdsRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -9,7 +11,9 @@ import java.util.List; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("批量素材ID请求") - public class BatchMaterialIdsRequest { - -+ @ApiModelProperty("素材ID列表") - private List materialIds; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchBindRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchBindRequest.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchBindRequest.java -index e859cea..53c0c3d 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchBindRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchBindRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -9,7 +11,9 @@ import java.util.List; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("批量引用绑定请求") - public class RefBatchBindRequest { - -+ @ApiModelProperty("引用绑定列表") - private List refs; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchUnbindRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchUnbindRequest.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchUnbindRequest.java -index 965c0e9..b532ee1 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchUnbindRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchUnbindRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -9,7 +11,9 @@ import java.util.List; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("批量引用解绑请求") - public class RefBatchUnbindRequest { - -+ @ApiModelProperty("引用解绑列表") - private List refs; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBindRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBindRequest.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBindRequest.java -index 8d95b02..16fdb65 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBindRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBindRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -7,11 +9,21 @@ import lombok.NoArgsConstructor; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("引用绑定请求") - public class RefBindRequest { - -+ @ApiModelProperty("素材ID") - private Long materialId; -+ -+ @ApiModelProperty("业务类型") - private String bizType; -+ -+ @ApiModelProperty("业务ID") - private Long bizId; -+ -+ @ApiModelProperty("业务名称") - private String bizName; -+ -+ @ApiModelProperty("用途类型") - private String usageType; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefUnbindRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefUnbindRequest.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefUnbindRequest.java -index 04252db..cdd7901 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefUnbindRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefUnbindRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -7,10 +9,18 @@ import lombok.NoArgsConstructor; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("引用解绑请求") - public class RefUnbindRequest { - -+ @ApiModelProperty("素材ID") - private Long materialId; -+ -+ @ApiModelProperty("业务类型") - private String bizType; -+ -+ @ApiModelProperty("业务ID") - private Long bizId; -+ -+ @ApiModelProperty("用途类型") - private String usageType; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourceCoverQuery.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourceCoverQuery.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourceCoverQuery.java -index da0d81d..9188dfb 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourceCoverQuery.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourceCoverQuery.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -7,7 +9,12 @@ import lombok.NoArgsConstructor; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("资源封面查询") - public class ResourceCoverQuery { -+ -+ @ApiModelProperty("资源类型") - private String resourceType; -+ -+ @ApiModelProperty("资源ID") - private String resourceId; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourcePriceQuery.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourcePriceQuery.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourcePriceQuery.java -index 90b98cf..685d2e0 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourcePriceQuery.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourcePriceQuery.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Builder; - import lombok.Data; -@@ -12,16 +14,21 @@ import java.util.List; - @Builder - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("资源价格查询") - public class ResourcePriceQuery { - -+ @ApiModelProperty("资源ID列表") - private List resourceIds; - -+ @ApiModelProperty("人员类型列表") - private List staffTypes; - -+ @ApiModelProperty("开始日期") - private LocalDate startDate; - -+ @ApiModelProperty("结束日期") - private LocalDate endDate; - -- /** resource sub-type (e.g. room_type_id for hotel, vehicle category for vehicle) */ -+ @ApiModelProperty("资源子类型(如酒店房型ID、车辆类别)") - private String subType; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/vo/MaterialVO.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/vo/MaterialVO.java b/hl-product-service/src/main/java/com/hulalv/product/feign/vo/MaterialVO.java -index d072f29..ec5b204 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/vo/MaterialVO.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/vo/MaterialVO.java -@@ -1,13 +1,25 @@ - package com.hulalv.product.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("素材信息VO") - public class MaterialVO { - -+ @ApiModelProperty("素材ID") - private String materialId; -+ -+ @ApiModelProperty("OSS访问URL") - private String ossUrl; -+ -+ @ApiModelProperty("缩略图URL") - private String thumbnailUrl; -+ -+ @ApiModelProperty("素材名称") - private String materialName; -+ -+ @ApiModelProperty("文件类型") - private String fileType; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/vo/ResourcePriceVO.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/vo/ResourcePriceVO.java b/hl-product-service/src/main/java/com/hulalv/product/feign/vo/ResourcePriceVO.java -index 4cf6dae..232915a 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/vo/ResourcePriceVO.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/vo/ResourcePriceVO.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Builder; - import lombok.Data; -@@ -12,15 +14,21 @@ import java.time.LocalDate; - @Builder - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("资源价格VO") - public class ResourcePriceVO { - -+ @ApiModelProperty("资源ID") - private Long resourceId; - -+ @ApiModelProperty("人员类型") - private String staffType; - -+ @ApiModelProperty("日期") - private LocalDate date; - -+ @ApiModelProperty("价格") - private BigDecimal price; - -+ @ApiModelProperty("资源名称") - private String resourceName; - } -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantCreateRequest.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantCreateRequest.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantCreateRequest.java -index 629213d..23de858 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantCreateRequest.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantCreateRequest.java -@@ -61,8 +61,8 @@ public class RestaurantCreateRequest { - @Size(max = 30) - private String district; - -- @ApiModelProperty(value = "城市标签", required = true, example = "拉萨") -- @NotBlank(message = "城市标签不能为空") -+ @ApiModelProperty(value = "城市名称(纯文本输入)", required = true, example = "拉萨") -+ @NotBlank(message = "城市名称不能为空") - @Size(max = 30) - private String cityName; - -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantQueryRequest.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantQueryRequest.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantQueryRequest.java -index 34e331b..ba2f6e9 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantQueryRequest.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantQueryRequest.java -@@ -25,7 +25,7 @@ public class RestaurantQueryRequest { - @ApiModelProperty(value = "省份", example = "西藏自治区") - private String province; - -- @ApiModelProperty(value = "城市标签", example = "拉萨") -+ @ApiModelProperty(value = "城市名称筛选(纯文本)", example = "拉萨") - private String cityName; - - @ApiModelProperty(value = "城市", example = "拉萨市") -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantUpdateRequest.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantUpdateRequest.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantUpdateRequest.java -index 8b62d81..51eb13c 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantUpdateRequest.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantUpdateRequest.java -@@ -57,7 +57,7 @@ public class RestaurantUpdateRequest { - @Size(max = 30) - private String district; - -- @ApiModelProperty(value = "城市标签", example = "拉萨") -+ @ApiModelProperty(value = "城市名称(纯文本输入)", example = "拉萨") - @Size(max = 30) - private String cityName; - -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantListVO.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantListVO.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantListVO.java -index df37c80..f0d4d24 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantListVO.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantListVO.java -@@ -36,7 +36,7 @@ public class RestaurantListVO { - @ApiModelProperty("人均消费(元)") - private BigDecimal pricePerPerson; - -- @ApiModelProperty("城市标签") -+ @ApiModelProperty("城市名称(纯文本)") - private String cityName; - - @ApiModelProperty("亮点摘要") -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantVO.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantVO.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantVO.java -index acfd3d8..4396d6e 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantVO.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantVO.java -@@ -54,7 +54,7 @@ public class RestaurantVO { - @ApiModelProperty("区县") - private String district; - -- @ApiModelProperty("城市标签") -+ @ApiModelProperty("城市名称(纯文本)") - private String cityName; - - @ApiModelProperty("详细地址") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/AdminLoginRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/AdminLoginRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/AdminLoginRequest.java -index 3dcbbb3..3bde0cd 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/AdminLoginRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/AdminLoginRequest.java -@@ -6,13 +6,15 @@ import lombok.Data; - import javax.validation.constraints.NotBlank; - - @Data --@ApiModel("管理员登录请求") -+@ApiModel(value = "管理员登录请求", description = "后台管理员通过用户名+密码登录,新设备首次登录需2FA验证") - public class AdminLoginRequest { -- @ApiModelProperty(value = "用户名", required = true, example = "admin") -+ @ApiModelProperty(value = "用户名", required = true, example = "admin", -+ notes = "管理员账号的用户名,由SUPER_ADMIN创建时指定") - @NotBlank(message = "用户名不能为空") - private String username; - -- @ApiModelProperty(value = "密码", required = true, example = "Admin@2026") -+ @ApiModelProperty(value = "密码", required = true, example = "Admin@2026", -+ notes = "须包含大小写字母和数字,长度8-128位。默认密码为Admin@123456") - @NotBlank(message = "密码不能为空") - private String password; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/ContactRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/ContactRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/ContactRequest.java -index 9c59721..160c8c7 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/ContactRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/ContactRequest.java -@@ -9,7 +9,7 @@ import javax.validation.constraints.NotBlank; - @Data - @ApiModel("联系我们请求") - public class ContactRequest { -- @ApiModelProperty(value = "渠道类型:ABOUT=关于我们 ONLINE_CS=在线客服 PHONE=电话咨询", required = true, example = "PHONE") -+ @ApiModelProperty(value = "渠道类型,关联字典contact_channel_type:ABOUT=关于我们, ONLINE_CS=在线客服, PHONE=电话咨询", required = true, example = "PHONE") - @NotBlank(message = "渠道类型不能为空") - private String channelType; - -@@ -32,6 +32,6 @@ public class ContactRequest { - @ApiModelProperty(value = "排序号(越小越靠前)", example = "1") - private Integer sortOrder; - -- @ApiModelProperty(value = "状态:0=下线 1=上线", example = "1") -+ @ApiModelProperty(value = "状态,关联字典common_status:0=下线, 1=上线", example = "1") - private Integer status; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/CreateAdminRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/CreateAdminRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/CreateAdminRequest.java -index 5d0ffe3..72f20fd 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/CreateAdminRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/CreateAdminRequest.java -@@ -7,17 +7,20 @@ import javax.validation.constraints.NotBlank; - import java.util.List; - - @Data --@ApiModel("创建管理员请求") -+@ApiModel(value = "创建管理员请求", description = "创建后台管理员账号,默认密码Admin@123456") - public class CreateAdminRequest { -- @ApiModelProperty(value = "用户名", required = true, example = "zhangsan") -+ @ApiModelProperty(value = "用户名", required = true, example = "zhangsan", -+ notes = "全局唯一的登录用户名,创建后不可修改") - @NotBlank(message = "用户名不能为空") - private String username; - - /** 角色ID列表(多角色),兼容旧的单角色 roleId */ -- @ApiModelProperty(value = "角色ID列表(多角色)", example = "[1,2]") -+ @ApiModelProperty(value = "角色ID列表(多角色)", example = "[1,2]", -+ notes = "支持分配多个角色,管理员登录后可通过切换角色接口切换当前活跃角色") - private List roleIds; - - /** @deprecated 兼容旧接口,优先使用 roleIds */ -- @ApiModelProperty(value = "角色ID(已废弃,请使用roleIds)", example = "1") -+ @ApiModelProperty(value = "角色ID(已废弃,请使用roleIds)", example = "1", -+ notes = "兼容旧接口的单角色参数,优先使用roleIds") - private Long roleId; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/CreateJobRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/CreateJobRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/CreateJobRequest.java -index dff93b6..5d8d05b 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/CreateJobRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/CreateJobRequest.java -@@ -12,18 +12,18 @@ public class CreateJobRequest { - @NotBlank(message = "任务名称不能为空") - private String jobName; - -- @ApiModelProperty(value = "任务分组", example = "SYSTEM") -+ @ApiModelProperty(value = "任务分组,字典类型:job_group(DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步)", example = "SYSTEM") - private String jobGroup; - -- @ApiModelProperty(value = "调用目标(Bean名称.方法名)", required = true, example = "wechatSyncService.syncDepartments") -+ @ApiModelProperty(value = "调用目标(Bean名称.方法名),方法必须是无参公开方法", required = true, example = "wechatSyncService.syncDepartments") - @NotBlank(message = "调用目标不能为空") - private String invokeTarget; - -- @ApiModelProperty(value = "Cron表达式", required = true, example = "0 0 2 * * ?") -+ @ApiModelProperty(value = "Cron表达式,标准6位(秒 分 时 日 月 周)", required = true, example = "0 0 2 * * ?") - @NotBlank(message = "Cron表达式不能为空") - private String cronExpression; - -- @ApiModelProperty(value = "计划执行策略:0=默认 1=立即触发 2=触发一次 3=不触发", example = "0") -+ @ApiModelProperty(value = "计划执行策略,字典类型:job_misfire_policy(DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发)", example = "DEFAULT") - private String misfirePolicy; - - @ApiModelProperty(value = "是否允许并发执行", example = "false") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/FavoriteRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/FavoriteRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/FavoriteRequest.java -index cbb0455..b7b4fbb 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/FavoriteRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/FavoriteRequest.java -@@ -7,13 +7,15 @@ import javax.validation.constraints.NotBlank; - import javax.validation.constraints.NotNull; - - @Data --@ApiModel("收藏请求") -+@ApiModel(value = "收藏请求", description = "添加收藏时的请求体,指定收藏的资源类型和ID") - public class FavoriteRequest { -- @ApiModelProperty(value = "收藏类型", required = true, example = "SCENIC_SPOT") -+ @ApiModelProperty(value = "收藏类型,关联字典favorite_resource_type", required = true, example = "SCENIC_SPOT", -+ notes = "可选值:SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品, EXPLORE=探索分类") - @NotBlank(message = "目标类型不能为空") - private String targetType; - -- @ApiModelProperty(value = "收藏目标ID", required = true, example = "1") -+ @ApiModelProperty(value = "收藏目标ID", required = true, example = "1", -+ notes = "对应资源的ID,如景区ID、活动ID等") - @NotNull(message = "目标ID不能为空") - private Long targetId; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/FootprintRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/FootprintRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/FootprintRequest.java -index 6a9905c..a700a4d 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/FootprintRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/FootprintRequest.java -@@ -7,13 +7,15 @@ import javax.validation.constraints.NotBlank; - import javax.validation.constraints.NotNull; - - @Data --@ApiModel("足迹请求") -+@ApiModel(value = "足迹请求", description = "记录用户浏览足迹时的请求体") - public class FootprintRequest { -- @ApiModelProperty(value = "资源类型", required = true, example = "SCENIC_SPOT") -+ @ApiModelProperty(value = "资源类型,关联字典footprint_resource_type", required = true, example = "SCENIC_SPOT", -+ notes = "可选值:SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品") - @NotBlank(message = "资源类型不能为空") - private String resourceType; - -- @ApiModelProperty(value = "资源ID", required = true, example = "1") -+ @ApiModelProperty(value = "资源ID", required = true, example = "1", -+ notes = "对应资源的ID,同一用户同一资源只保留最新一条足迹") - @NotNull(message = "资源ID不能为空") - private Long resourceId; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/LoginRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/LoginRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/LoginRequest.java -index e8ff874..bdc2f40 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/LoginRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/LoginRequest.java -@@ -6,18 +6,22 @@ import lombok.Data; - import javax.validation.constraints.NotBlank; - - @Data --@ApiModel("微信小程序登录请求") -+@ApiModel(value = "微信小程序登录请求", description = "通过wx.login获取code进行登录,首次登录自动注册") - public class LoginRequest { -- @ApiModelProperty(value = "微信登录授权码", required = true, example = "0c3NKj000...") -+ @ApiModelProperty(value = "微信登录授权码", required = true, example = "0c3NKj000...", -+ notes = "通过wx.login()获取的临时授权码,后端用此code换取openid/unionid") - @NotBlank(message = "微信code不能为空") - private String code; - -- @ApiModelProperty(value = "手机号授权码(用于获取手机号)", example = "0c3NKj000...") -+ @ApiModelProperty(value = "手机号授权码(用于获取手机号)", example = "0c3NKj000...", -+ notes = "通过getPhoneNumber按钮获取的code,后端用此code换取用户手机号并绑定") - private String phoneCode; - -- @ApiModelProperty(value = "用户头像URL", example = "https://thirdwx.qlogo.cn/xxx") -+ @ApiModelProperty(value = "用户头像URL", example = "https://thirdwx.qlogo.cn/xxx", -+ notes = "微信头像地址,首次登录时传入用于设置用户头像") - private String avatar; - -- @ApiModelProperty(value = "用户昵称", example = "微信用户") -+ @ApiModelProperty(value = "用户昵称", example = "微信用户", -+ notes = "微信昵称,首次登录时传入用于设置用户昵称") - private String nickname; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/SwitchRoleRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/SwitchRoleRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/SwitchRoleRequest.java -index 48d700d..945424d 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/SwitchRoleRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/SwitchRoleRequest.java -@@ -7,10 +7,11 @@ import lombok.Data; - import javax.validation.constraints.NotNull; - - @Data --@ApiModel("角色切换请求") -+@ApiModel(value = "角色切换请求", description = "多角色管理员切换当前活跃角色") - public class SwitchRoleRequest { - - @NotNull(message = "角色ID不能为空") -- @ApiModelProperty(value = "目标角色ID", required = true) -+ @ApiModelProperty(value = "目标角色ID", required = true, -+ notes = "只能切换到当前管理员已分配的角色,切换后返回新Token和对应菜单权限") - private Long roleId; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/TravelerRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/TravelerRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/TravelerRequest.java -index f8d33c8..1c67bb6 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/TravelerRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/TravelerRequest.java -@@ -15,10 +15,10 @@ public class TravelerRequest { - @Size(max = 50, message = "姓名长度不能超过50个字符") - private String name; - -- @ApiModelProperty(value = "出行人类型(无需传入,后端根据出生日期自动判断)", hidden = true) -+ @ApiModelProperty(value = "出行人类型,关联字典traveler_type:ADULT=成人, CHILD=儿童, INFANT=婴儿(无需传入,后端根据birthday自动判断)", hidden = true) - private String travelerType; // auto-resolved from birthday - -- @ApiModelProperty(value = "证件类型:ID_CARD=身份证 PASSPORT=护照", example = "ID_CARD") -+ @ApiModelProperty(value = "证件类型,关联字典id_card_type:ID_CARD=身份证, PASSPORT=护照", example = "ID_CARD") - private String idCardType; // Default: ID_CARD - - @ApiModelProperty(value = "证件号码", example = "110101199001011234") -@@ -29,7 +29,7 @@ public class TravelerRequest { - @Size(max = 20, message = "手机号长度不能超过20个字符") - private String phone; - -- @ApiModelProperty(value = "性别:0=女 1=男", example = "1") -+ @ApiModelProperty(value = "性别,关联字典gender:0=女, 1=男", example = "1") - private Integer gender; // 0=female, 1=male - - @ApiModelProperty(value = "出生日期(必填,后端根据此字段自动判断人员类型)", required = true, example = "1990-01-01") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/UpdateAvatarRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateAvatarRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateAvatarRequest.java -index 273a9bc..1e4c1f4 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateAvatarRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateAvatarRequest.java -@@ -7,13 +7,15 @@ import lombok.Data; - import javax.validation.constraints.NotBlank; - - @Data --@ApiModel("头像更新请求") -+@ApiModel(value = "头像更新请求", description = "更新管理员头像,需先通过文件服务上传图片") - public class UpdateAvatarRequest { - - @NotBlank(message = "头像URL不能为空") -- @ApiModelProperty(value = "头像URL", required = true) -+ @ApiModelProperty(value = "头像URL", required = true, -+ notes = "文件服务返回的OSS URL地址") - private String avatar; - -- @ApiModelProperty("文件ID") -+ @ApiModelProperty(value = "文件ID", -+ notes = "文件服务返回的fileId,用于建立文件引用关系,传入后旧头像引用自动解绑") - private Long fileId; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/UpdateJobRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateJobRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateJobRequest.java -index a42399c..4e85a2a 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateJobRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateJobRequest.java -@@ -10,16 +10,16 @@ public class UpdateJobRequest { - @ApiModelProperty(value = "任务名称", example = "同步企微通讯录") - private String jobName; - -- @ApiModelProperty(value = "任务分组", example = "SYSTEM") -+ @ApiModelProperty(value = "任务分组,字典类型:job_group(DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步)", example = "SYSTEM") - private String jobGroup; - -- @ApiModelProperty(value = "调用目标(Bean名称.方法名)", example = "wechatSyncService.syncDepartments") -+ @ApiModelProperty(value = "调用目标(Bean名称.方法名),方法必须是无参公开方法", example = "wechatSyncService.syncDepartments") - private String invokeTarget; - -- @ApiModelProperty(value = "Cron表达式", example = "0 0 2 * * ?") -+ @ApiModelProperty(value = "Cron表达式,标准6位(秒 分 时 日 月 周)", example = "0 0 2 * * ?") - private String cronExpression; - -- @ApiModelProperty(value = "计划执行策略:0=默认 1=立即触发 2=触发一次 3=不触发", example = "0") -+ @ApiModelProperty(value = "计划执行策略,字典类型:job_misfire_policy(DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发)", example = "DEFAULT") - private String misfirePolicy; - - @ApiModelProperty(value = "是否允许并发执行", example = "false") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/dto/CustomPushRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/dto/CustomPushRequest.java b/hl-user-service/src/main/java/com/hulalv/user/notification/dto/CustomPushRequest.java -index 228bb27..2a3ee4f 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/dto/CustomPushRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/dto/CustomPushRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.user.notification.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - import javax.validation.constraints.NotBlank; -@@ -10,28 +12,31 @@ import java.util.List; - * 自定义推送请求 - */ - @Data -+@ApiModel("自定义推送请求") - public class CustomPushRequest { - -+ @ApiModelProperty("推送标题") - @NotBlank(message = "推送标题不能为空") - private String title; - -+ @ApiModelProperty("推送内容") - @NotBlank(message = "推送内容不能为空") - private String content; - -- /** 推送通道: INAPP, SMS, WECHAT_WORK */ -+ @ApiModelProperty("推送通道: INAPP/SMS/WECHAT_WORK") - @NotNull(message = "请选择推送通道") - private String channel; - -- /** 目标类型: ALL_USERS, SPECIFIC_USERS */ -+ @ApiModelProperty("目标类型: ALL_USERS/SPECIFIC_USERS") - @NotNull(message = "请选择目标类型") - private String targetType; - -- /** targetType=SPECIFIC_USERS时必填 */ -+ @ApiModelProperty("目标用户ID列表(目标类型为SPECIFIC_USERS时必填)") - private List userIds; - -- /** 消息分类编码,默认SYSTEM */ -+ @ApiModelProperty("消息分类编码,默认SYSTEM") - private String categoryCode; - -- /** 跳转链接(站内信时使用) */ -+ @ApiModelProperty("跳转链接(站内信时使用)") - private String link; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/vo/CustomPushResultVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/CustomPushResultVO.java b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/CustomPushResultVO.java -index e3cdaf2..495cb3d 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/CustomPushResultVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/CustomPushResultVO.java -@@ -1,19 +1,22 @@ - package com.hulalv.user.notification.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - /** - * 自定义推送结果 - */ - @Data -+@ApiModel("自定义推送结果VO") - public class CustomPushResultVO { - -- /** 推送总数 */ -+ @ApiModelProperty("推送总数") - private int totalCount; - -- /** 成功数 */ -+ @ApiModelProperty("成功数") - private int successCount; - -- /** 失败数 */ -+ @ApiModelProperty("失败数") - private int failCount; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/vo/EventConfigVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/EventConfigVO.java b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/EventConfigVO.java -index 8b7e7d1..7434992 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/EventConfigVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/EventConfigVO.java -@@ -21,7 +21,7 @@ public class EventConfigVO { - @ApiModelProperty("所属分类名称") - private String categoryName; - -- @ApiModelProperty("站内信开关") -+ @ApiModelProperty("站内信开关(0=关闭, 1=开启)") - private Integer inappEnabled; - - @ApiModelProperty("站内信标题模板") -@@ -33,7 +33,7 @@ public class EventConfigVO { - @ApiModelProperty("站内信跳转路径模板") - private String inappLinkTemplate; - -- @ApiModelProperty("短信开关") -+ @ApiModelProperty("短信开关(0=关闭, 1=开启)") - private Integer smsEnabled; - - @ApiModelProperty("阿里云短信模板编号") -@@ -42,7 +42,7 @@ public class EventConfigVO { - @ApiModelProperty("短信签名") - private String smsSignName; - -- @ApiModelProperty("小程序订阅消息开关") -+ @ApiModelProperty("小程序订阅消息开关(0=关闭, 1=开启)") - private Integer miniappEnabled; - - @ApiModelProperty("微信订阅消息模板ID") -@@ -54,7 +54,7 @@ public class EventConfigVO { - @ApiModelProperty("小程序字段映射JSON") - private String miniappFieldMapping; - -- @ApiModelProperty("公众号模板消息开关") -+ @ApiModelProperty("公众号模板消息开关(0=关闭, 1=开启)") - private Integer oaEnabled; - - @ApiModelProperty("公众号模板ID") -@@ -66,10 +66,10 @@ public class EventConfigVO { - @ApiModelProperty("公众号字段映射JSON") - private String oaFieldMapping; - -- @ApiModelProperty("企微通知开关") -+ @ApiModelProperty("企微通知开关(0=关闭, 1=开启)") - private Integer weworkEnabled; - -- @ApiModelProperty("企微接收人类型") -+ @ApiModelProperty("企微接收人类型(ROLE=按角色, DEPT=按部门, SPECIFIC=指定人员)") - private String weworkReceiverType; - - @ApiModelProperty("企微消息内容模板") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/vo/SendLogVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/SendLogVO.java b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/SendLogVO.java -index 8e44260..52c307c 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/SendLogVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/SendLogVO.java -@@ -14,7 +14,7 @@ public class SendLogVO { - @ApiModelProperty("事件编码") - private String eventCode; - -- @ApiModelProperty("通道: INAPP/SMS/MINIAPP/OA/WEWORK") -+ @ApiModelProperty("通道,关联字典notification_channel:INAPP=站内信, SMS=短信, MINIAPP=小程序订阅, OA=公众号模板, WEWORK=企业微信") - private String channel; - - @ApiModelProperty("用户ID") -@@ -38,7 +38,7 @@ public class SendLogVO { - @ApiModelProperty("关联业务类型") - private String bizType; - -- @ApiModelProperty("发送状态: 0成功 1失败 2跳过") -+ @ApiModelProperty("发送状态,关联字典notification_send_status:0=成功, 1=失败, 2=跳过") - private Integer status; - - @ApiModelProperty("失败原因") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/vo/UserSimpleVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/UserSimpleVO.java b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/UserSimpleVO.java -index 448b5df..9ad4b62 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/UserSimpleVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/UserSimpleVO.java -@@ -1,18 +1,25 @@ - package com.hulalv.user.notification.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - /** - * 用户简要信息(自定义推送选择目标用户时使用) - */ - @Data -+@ApiModel("用户简要信息VO") - public class UserSimpleVO { - -+ @ApiModelProperty("用户ID") - private Long id; - -+ @ApiModelProperty("真实姓名") - private String realName; - -+ @ApiModelProperty("手机号") - private String phone; - -+ @ApiModelProperty("头像URL") - private String avatarUrl; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/vo/ContactVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/vo/ContactVO.java b/hl-user-service/src/main/java/com/hulalv/user/vo/ContactVO.java -index 8bd3d9d..53a203c 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/vo/ContactVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/vo/ContactVO.java -@@ -14,7 +14,7 @@ public class ContactVO { - @ApiModelProperty(value = "联系方式ID") - private String id; - -- @ApiModelProperty(value = "渠道类型:ABOUT=关于我们 ONLINE_CS=在线客服 PHONE=电话咨询") -+ @ApiModelProperty(value = "渠道类型,关联字典contact_channel_type:ABOUT=关于我们, ONLINE_CS=在线客服, PHONE=电话咨询") - private String channelType; - - @ApiModelProperty(value = "标题") -@@ -35,7 +35,7 @@ public class ContactVO { - @ApiModelProperty(value = "排序号") - private Integer sortOrder; - -- @ApiModelProperty(value = "状态:0=下线 1=上线") -+ @ApiModelProperty(value = "状态,关联字典common_status:0=下线, 1=上线") - private Integer status; - - @ApiModelProperty(value = "创建时间") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/vo/CustomerVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/vo/CustomerVO.java b/hl-user-service/src/main/java/com/hulalv/user/vo/CustomerVO.java -index d72a7b3..be9f83a 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/vo/CustomerVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/vo/CustomerVO.java -@@ -26,7 +26,7 @@ public class CustomerVO { - @ApiModelProperty(value = "手机号(不脱敏)") - private String phone; - -- @ApiModelProperty(value = "状态:ACTIVE=正常 DISABLED=禁用") -+ @ApiModelProperty(value = "状态,关联字典user_status:ACTIVE=正常, BANNED=已封禁") - private String status; - - @ApiModelProperty(value = "创建时间") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/vo/LoginLogVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/vo/LoginLogVO.java b/hl-user-service/src/main/java/com/hulalv/user/vo/LoginLogVO.java -index 89620fe..3582c3d 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/vo/LoginLogVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/vo/LoginLogVO.java -@@ -18,7 +18,7 @@ public class LoginLogVO { - @ApiModelProperty(value = "管理员名称") - private String adminName; - -- @ApiModelProperty(value = "登录方式:PASSWORD=密码 WECHAT=企微扫码 TWO_FA=二次验证") -+ @ApiModelProperty(value = "登录方式,关联字典login_method:PASSWORD=密码登录, WECHAT_QR=企微扫码登录, TWO_FA=二次验证登录") - private String loginMethod; - - @ApiModelProperty(value = "登录IP地址") -@@ -36,7 +36,7 @@ public class LoginLogVO { - @ApiModelProperty(value = "登录地区") - private String location; - -- @ApiModelProperty(value = "登录状态:SUCCESS=成功 FAILED=失败") -+ @ApiModelProperty(value = "登录状态,关联字典login_status:SUCCESS=成功, FAILED=失败") - private String status; - - @ApiModelProperty(value = "失败原因") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/vo/UserVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/vo/UserVO.java b/hl-user-service/src/main/java/com/hulalv/user/vo/UserVO.java -index cb64d33..bbc0ede 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/vo/UserVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/vo/UserVO.java -@@ -29,20 +29,20 @@ public class UserVO { - @ApiModelProperty(value = "真实手机号(仅内部接口返回,用于订单预填)", hidden = true) - private String rawPhone; // 真实手机号(仅内部接口返回,用于订单预填) - -- @ApiModelProperty(value = "状态:ACTIVE=正常 DISABLED=禁用") -+ @ApiModelProperty(value = "状态,关联字典user_status:ACTIVE=正常, BANNED=已封禁") - private String status; - - // 个人信息字段(用于编辑"本人"出行人信息) - @ApiModelProperty(value = "真实姓名") - private String realName; - -- @ApiModelProperty(value = "证件类型:ID_CARD=身份证 PASSPORT=护照") -+ @ApiModelProperty(value = "证件类型,关联字典id_card_type:ID_CARD=身份证, PASSPORT=护照") - private String idCardType; - - @ApiModelProperty(value = "证件号码") - private String idCardNo; - -- @ApiModelProperty(value = "性别:0=女 1=男") -+ @ApiModelProperty(value = "性别,关联字典gender:0=女, 1=男") - private Integer gender; - - @ApiModelProperty(value = "出生日期") -``` - -## 数据库变更 (SQL) - -### `sql/add_customer_service_role.sql` (A) - -```sql --- 新增客服角色 --- 权限:查看全部订单、全部产品(含定制产品)、配置保险、配置合同、查看素材 - --- 1. 创建角色 -INSERT INTO sys_role (role_id, role_name, role_key, sort_order, status) -VALUES (8, '客服', 'CUSTOMER_SERVICE', 8, 'ACTIVE'); - --- 2. 分配菜单权限 -INSERT INTO sys_role_menu (role_id, menu_id) VALUES --- 订单管理(查看,不含创建) -(8, 700), -- 订单管理(目录) -(8, 710), -- 订单列表 -(8, 730), -- 订单详情 -(8, 740), -- 早鸟优惠 -(8, 750), -- 工单管理 --- 退款管理(查看) -(8, 6001), -- 退款管理(目录) -(8, 6010), -- 退款申请 -(8, 6020), -- 退款政策 -(8, 6030), -- 退款原因 --- 产品管理(查看全部,含定制产品,不含增删改按钮) -(8, 500), -- 产品管理(目录) -(8, 510), -- 产品列表 -(8, 520), -- 产品线管理 -(8, 530), -- 团期管理 --- 保险管理(配置) -(8, 800), -- 保险管理(目录) -(8, 810), -- 保险产品 -(8, 820), -- 保险订单 -(8, 830), -- 保险方案 --- 合同管理(配置) -(8, 850), -- 合同管理(目录) -(8, 851), -- 合同列表 -(8, 852), -- 补充约定模板 --- 素材库(查看) -(8, 1890000000000000100); -- 素材库 -``` - -### `sql/dict_data_seed.sql` (M) - -```diff -diff --git a/sql/dict_data_seed.sql b/sql/dict_data_seed.sql -index b4646bd..933fd27 100644 ---- a/sql/dict_data_seed.sql -+++ b/sql/dict_data_seed.sql -@@ -5,7 +5,7 @@ - USE hl_user_service; - - -- ============================================================ ---- Dict Types (7 types) -+-- Dict Types (9 types) - -- ============================================================ - INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status, remark, created_at, updated_at) - VALUES -@@ -15,7 +15,9 @@ VALUES - (4, '字典分类', 'dict_category', 'BASE', 'ACTIVE', NULL, NOW(), NOW()), - (5, '任务补偿策略', 'job_misfire_policy', 'BASE', 'ACTIVE', NULL, NOW(), NOW()), - (6, '部门状态', 'dept_status', 'BASE', 'ACTIVE', NULL, NOW(), NOW()), -- (7, '任务日志状态', 'job_log_status', 'BASE', 'ACTIVE', NULL, NOW(), NOW()); -+ (7, '任务日志状态', 'job_log_status', 'BASE', 'ACTIVE', NULL, NOW(), NOW()), -+ (8, '任务状态', 'job_status', 'BASE', 'ACTIVE', NULL, NOW(), NOW()), -+ (9, '任务分组', 'job_group', 'BASE', 'ACTIVE', NULL, NOW(), NOW()); - - -- ============================================================ - -- Dict Data (remark stores el-tag type for styling) -@@ -67,4 +69,18 @@ VALUES - (701, 'job_log_status', '成功', 'SUCCESS', 1, 'ACTIVE', 'success', NOW(), NOW()), - (702, 'job_log_status', '失败', 'FAIL', 2, 'ACTIVE', 'danger', NOW(), NOW()); - -+-- job_status -+INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status, remark, created_at, updated_at) -+VALUES -+ (801, 'job_status', '启用', 'ACTIVE', 1, 'ACTIVE', 'success', NOW(), NOW()), -+ (802, 'job_status', '已暂停', 'PAUSED', 2, 'ACTIVE', 'info', NOW(), NOW()); -+ -+-- job_group -+INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status, remark, created_at, updated_at) -+VALUES -+ (901, 'job_group', '默认分组', 'DEFAULT', 1, 'ACTIVE', '', NOW(), NOW()), -+ (902, 'job_group', '系统任务', 'SYSTEM', 2, 'ACTIVE', 'primary', NOW(), NOW()), -+ (903, 'job_group', '企微同步', 'WECHAT', 3, 'ACTIVE', 'success', NOW(), NOW()), -+ (904, 'job_group', '保险同步', 'INSURANCE', 4, 'ACTIVE', 'warning', NOW(), NOW()); -+ - SELECT 'Seed complete' AS result; -``` - -### `sql/dict_fix_frontend.sql` (A) - -```sql --- ============================================================ --- 前端缺失的字典类型和字典数据补齐 --- 对比前端 hl-ui 代码 vs 后端 sys_dict_type 表 --- ============================================================ - --- 1. cities - 城市(树形字典,MobilePreview/useLocation用) -INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) -VALUES (1900000001, '城市', 'cities', 'BASE', 'ACTIVE'); - -INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) -VALUES -(1900100001, 'cities', '海拉尔', 'hailar', 1, 'ACTIVE'), -(1900100002, 'cities', '满洲里', 'manzhouli', 2, 'ACTIVE'), -(1900100003, 'cities', '额尔古纳', 'eergu', 3, 'ACTIVE'), -(1900100004, 'cities', '根河', 'genhe', 4, 'ACTIVE'), -(1900100005, 'cities', '牙克石', 'yakeshi', 5, 'ACTIVE'), -(1900100006, 'cities', '扎兰屯', 'zhalantun', 6, 'ACTIVE'), -(1900100007, 'cities', '阿尔山', 'aershan', 7, 'ACTIVE'), -(1900100008, 'cities', '室韦', 'shiwei', 8, 'ACTIVE'), -(1900100009, 'cities', '恩和', 'enhe', 9, 'ACTIVE'), -(1900100010, 'cities', '黑山头', 'heishantou', 10, 'ACTIVE'), -(1900100011, 'cities', '陈巴尔虎旗', 'chenbaerhu', 11, 'ACTIVE'), -(1900100012, 'cities', '新巴尔虎左旗', 'xinbaerhuzuo', 12, 'ACTIVE'), -(1900100013, 'cities', '新巴尔虎右旗', 'xinbaerhuyou', 13, 'ACTIVE'), -(1900100014, 'cities', '鄂温克旗', 'ewenke', 14, 'ACTIVE'), -(1900100015, 'cities', '莫尔道嘎', 'moerdaoga', 15, 'ACTIVE'); - --- 2. city - 城市筛选(产品行程资源面板用) -INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) -VALUES (1900000002, '城市筛选', 'city', 'BASE', 'ACTIVE'); - -INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) -VALUES -(1900200001, 'city', '海拉尔', 'hailar', 1, 'ACTIVE'), -(1900200002, 'city', '满洲里', 'manzhouli', 2, 'ACTIVE'), -(1900200003, 'city', '额尔古纳', 'eergu', 3, 'ACTIVE'), -(1900200004, 'city', '根河', 'genhe', 4, 'ACTIVE'), -(1900200005, 'city', '阿尔山', 'aershan', 5, 'ACTIVE'), -(1900200006, 'city', '室韦', 'shiwei', 6, 'ACTIVE'), -(1900200007, 'city', '恩和', 'enhe', 7, 'ACTIVE'), -(1900200008, 'city', '黑山头', 'heishantou', 8, 'ACTIVE'); - --- 3. city_label - 城市标签(餐厅列表筛选用) -INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) -VALUES (1900000003, '城市标签', 'city_label', 'BASE', 'ACTIVE'); - -INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) -VALUES -(1900300001, 'city_label', '海拉尔', 'hailar', 1, 'ACTIVE'), -(1900300002, 'city_label', '满洲里', 'manzhouli', 2, 'ACTIVE'), -(1900300003, 'city_label', '额尔古纳', 'eergu', 3, 'ACTIVE'), -(1900300004, 'city_label', '根河', 'genhe', 4, 'ACTIVE'), -(1900300005, 'city_label', '阿尔山', 'aershan', 5, 'ACTIVE'), -(1900300006, 'city_label', '室韦', 'shiwei', 6, 'ACTIVE'), -(1900300007, 'city_label', '恩和', 'enhe', 7, 'ACTIVE'), -(1900300008, 'city_label', '黑山头', 'heishantou', 8, 'ACTIVE'); - --- 4. environment_type - 环境类型(餐厅编辑用,前端key是environment_type) -INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) -VALUES (1900000004, '环境类型', 'environment_type', 'BASE', 'ACTIVE'); - -INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) -VALUES -(1900400001, 'environment_type', '室内', 'INDOOR', 1, 'ACTIVE'), -(1900400002, 'environment_type', '户外', 'OUTDOOR', 2, 'ACTIVE'), -(1900400003, 'environment_type', '混合', 'MIXED', 3, 'ACTIVE'); - --- 5. cost_unit - 费用计价单位(费用项编辑用) -INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) -VALUES (1900000005, '费用计价单位', 'cost_unit', 'BUSINESS', 'ACTIVE'); - -INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) -VALUES -(1900500001, 'cost_unit', '元/人', 'PER_PERSON', 1, 'ACTIVE'), -(1900500002, 'cost_unit', '元/台', 'PER_VEHICLE', 2, 'ACTIVE'), -(1900500003, 'cost_unit', '元/天', 'PER_DAY', 3, 'ACTIVE'), -(1900500004, 'cost_unit', '元/次', 'PER_TIME', 4, 'ACTIVE'), -(1900500005, 'cost_unit', '元/间', 'PER_ROOM', 5, 'ACTIVE'), -(1900500006, 'cost_unit', '元/桌', 'PER_TABLE', 6, 'ACTIVE'), -(1900500007, 'cost_unit', '固定金额', 'FIXED', 7, 'ACTIVE'); - --- 6. service_unit - 服务计价单位(服务项编辑用) -INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) -VALUES (1900000006, '服务计价单位', 'service_unit', 'BUSINESS', 'ACTIVE'); - -INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) -VALUES -(1900600001, 'service_unit', '元/人', 'PER_PERSON', 1, 'ACTIVE'), -(1900600002, 'service_unit', '元/次', 'PER_TIME', 2, 'ACTIVE'), -(1900600003, 'service_unit', '元/天', 'PER_DAY', 3, 'ACTIVE'), -(1900600004, 'service_unit', '元/台', 'PER_VEHICLE', 4, 'ACTIVE'), -(1900600005, 'service_unit', '固定金额', 'FIXED', 5, 'ACTIVE'); - --- 7. material_tag - 素材标签(素材上传/编辑用) -INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) -VALUES (1900000007, '素材标签', 'material_tag', 'BUSINESS', 'ACTIVE'); - -INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) -VALUES -(1900700001, 'material_tag', '风景', 'landscape', 1, 'ACTIVE'), -(1900700002, 'material_tag', '人物', 'portrait', 2, 'ACTIVE'), -(1900700003, 'material_tag', '美食', 'food', 3, 'ACTIVE'), -(1900700004, 'material_tag', '住宿', 'hotel', 4, 'ACTIVE'), -(1900700005, 'material_tag', '交通', 'transport', 5, 'ACTIVE'), -(1900700006, 'material_tag', '活动', 'activity', 6, 'ACTIVE'), -(1900700007, 'material_tag', '冬季', 'winter', 7, 'ACTIVE'), -(1900700008, 'material_tag', '夏季', 'summer', 8, 'ACTIVE'), -(1900700009, 'material_tag', '草原', 'grassland', 9, 'ACTIVE'), -(1900700010, 'material_tag', '森林', 'forest', 10, 'ACTIVE'); - --- 8. product_category - 产品分类(产品基本信息编辑用) -INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) -VALUES (1900000008, '产品分类', 'product_category', 'BUSINESS', 'ACTIVE'); - -INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) -VALUES -(1900800001, 'product_category', '亲子游', 'family', 1, 'ACTIVE'), -(1900800002, 'product_category', '蜜月旅行', 'honeymoon', 2, 'ACTIVE'), -(1900800003, 'product_category', '摄影之旅', 'photography', 3, 'ACTIVE'), -(1900800004, 'product_category', '深度体验', 'experience', 4, 'ACTIVE'), -(1900800005, 'product_category', '自驾越野', 'driving', 5, 'ACTIVE'); - --- 9. settle_status - 结算状态(结算记录用) -INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) -VALUES (1900000009, '结算状态', 'settle_status', 'BUSINESS', 'ACTIVE'); - -INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) -VALUES -(1900900001, 'settle_status', '待结算', 'pending', 1, 'ACTIVE'), -(1900900002, 'settle_status', '已结算', 'settled', 2, 'ACTIVE'), -(1900900003, 'settle_status', '结算中', 'processing', 3, 'ACTIVE'), -(1900900004, 'settle_status', '已取消', 'cancelled', 4, 'ACTIVE'); - --- 10. trip_status - 行程状态(定制行程列表用) -INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) -VALUES (1900000010, '行程状态', 'trip_status', 'BUSINESS', 'ACTIVE'); - -INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) -VALUES -(1901000001, 'trip_status', '草稿', 'draft', 1, 'ACTIVE'), -(1901000002, 'trip_status', '已上线', 'online', 2, 'ACTIVE'), -(1901000003, 'trip_status', '已下线', 'offline', 3, 'ACTIVE'); - --- 11. trip_type - 行程类型(定制行程表单用) -INSERT IGNORE INTO sys_dict_type (dict_type_id, dict_name, dict_type, category, status) -VALUES (1900000011, '行程类型', 'trip_type', 'BUSINESS', 'ACTIVE'); - -INSERT IGNORE INTO sys_dict_data (dict_data_id, dict_type, dict_label, dict_value, sort_order, status) -VALUES -(1901100001, 'trip_type', '跟团游', 'group', 1, 'ACTIVE'), -(1901100002, 'trip_type', '自由行', 'free', 2, 'ACTIVE'), -(1901100003, 'trip_type', '定制游', 'custom', 3, 'ACTIVE'), -(1901100004, 'trip_type', '半自由行', 'semi_free', 4, 'ACTIVE'); -``` - -## 配置变更 - -### `hl-callback-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-callback-service/src/main/resources/bootstrap.yml b/hl-callback-service/src/main/resources/bootstrap.yml -index 7b5d1dc..5d1c2d6 100644 ---- a/hl-callback-service/src/main/resources/bootstrap.yml -+++ b/hl-callback-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -13,6 +13,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u4F01\u5FAE\u56DE\u8C03\u670D\u52A1" -``` - -### `hl-contract-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-contract-service/src/main/resources/bootstrap.yml b/hl-contract-service/src/main/resources/bootstrap.yml -index 2ad048d..9a8fadc 100644 ---- a/hl-contract-service/src/main/resources/bootstrap.yml -+++ b/hl-contract-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -17,6 +17,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u5408\u540C\u670D\u52A1" -``` - -### `hl-file-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-file-service/src/main/resources/bootstrap.yml b/hl-file-service/src/main/resources/bootstrap.yml -index 80be6f4..f060b2f 100644 ---- a/hl-file-service/src/main/resources/bootstrap.yml -+++ b/hl-file-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -13,6 +13,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u6587\u4EF6\u670D\u52A1" -``` - -### `hl-gateway/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-gateway/src/main/resources/bootstrap.yml b/hl-gateway/src/main/resources/bootstrap.yml -index b081310..e4431ac 100644 ---- a/hl-gateway/src/main/resources/bootstrap.yml -+++ b/hl-gateway/src/main/resources/bootstrap.yml -@@ -5,10 +5,10 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u7F51\u5173\u670D\u52A1" -``` - -### `hl-guide-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-guide-service/src/main/resources/bootstrap.yml b/hl-guide-service/src/main/resources/bootstrap.yml -index fe9e45a..e9e3e60 100644 ---- a/hl-guide-service/src/main/resources/bootstrap.yml -+++ b/hl-guide-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -17,6 +17,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u653B\u7565\u670D\u52A1" -``` - -### `hl-insurance-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-insurance-service/src/main/resources/bootstrap.yml b/hl-insurance-service/src/main/resources/bootstrap.yml -index 3fa8071..6a668aa 100644 ---- a/hl-insurance-service/src/main/resources/bootstrap.yml -+++ b/hl-insurance-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -17,6 +17,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u4FDD\u9669\u670D\u52A1" -``` - -### `hl-material-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-material-service/src/main/resources/bootstrap.yml b/hl-material-service/src/main/resources/bootstrap.yml -index a2129ab..affb9da 100644 ---- a/hl-material-service/src/main/resources/bootstrap.yml -+++ b/hl-material-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -13,6 +13,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u7D20\u6750\u5E93\u670D\u52A1" -``` - -### `hl-monitor-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-monitor-service/src/main/resources/bootstrap.yml b/hl-monitor-service/src/main/resources/bootstrap.yml -index d578a0b..32ebbb5 100644 ---- a/hl-monitor-service/src/main/resources/bootstrap.yml -+++ b/hl-monitor-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -17,6 +17,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u76D1\u63A7\u670D\u52A1" -``` - -### `hl-mp-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-mp-service/src/main/resources/bootstrap.yml b/hl-mp-service/src/main/resources/bootstrap.yml -index 826eadd..d3103ee 100644 ---- a/hl-mp-service/src/main/resources/bootstrap.yml -+++ b/hl-mp-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -17,6 +17,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u5C0F\u7A0B\u5E8FBFF\u670D\u52A1" -``` - -### `hl-order-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-order-service/src/main/resources/bootstrap.yml b/hl-order-service/src/main/resources/bootstrap.yml -index 7a5aac5..a5f007a 100644 ---- a/hl-order-service/src/main/resources/bootstrap.yml -+++ b/hl-order-service/src/main/resources/bootstrap.yml -@@ -7,7 +7,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -19,6 +19,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u8BA2\u5355\u670D\u52A1" -``` - -### `hl-payment-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-payment-service/src/main/resources/bootstrap.yml b/hl-payment-service/src/main/resources/bootstrap.yml -index a70de62..00e9efd 100644 ---- a/hl-payment-service/src/main/resources/bootstrap.yml -+++ b/hl-payment-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - discovery: - metadata: - description: "\u652F\u4ED8\u670D\u52A1" -``` - -### `hl-product-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-product-service/src/main/resources/bootstrap.yml b/hl-product-service/src/main/resources/bootstrap.yml -index a9fab53..7f26008 100644 ---- a/hl-product-service/src/main/resources/bootstrap.yml -+++ b/hl-product-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -17,6 +17,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u4EA7\u54C1\u670D\u52A1" -``` - -### `hl-resource-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-resource-service/src/main/resources/bootstrap.yml b/hl-resource-service/src/main/resources/bootstrap.yml -index 2f8d63d..05aece0 100644 ---- a/hl-resource-service/src/main/resources/bootstrap.yml -+++ b/hl-resource-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -17,6 +17,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u8D44\u6E90\u670D\u52A1" -``` - -### `hl-review-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-review-service/src/main/resources/bootstrap.yml b/hl-review-service/src/main/resources/bootstrap.yml -index 5a0bc48..4c5260b 100644 ---- a/hl-review-service/src/main/resources/bootstrap.yml -+++ b/hl-review-service/src/main/resources/bootstrap.yml -@@ -10,7 +10,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -22,6 +22,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u8BC4\u4EF7\u670D\u52A1" -``` - -### `hl-task-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-task-service/src/main/resources/bootstrap.yml b/hl-task-service/src/main/resources/bootstrap.yml -index 810de1f..7bc1d67 100644 ---- a/hl-task-service/src/main/resources/bootstrap.yml -+++ b/hl-task-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -13,6 +13,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u4EFB\u52A1\u670D\u52A1" -``` - -### `hl-user-service/src/main/resources/bootstrap.yml` (M) - -```diff -diff --git a/hl-user-service/src/main/resources/bootstrap.yml b/hl-user-service/src/main/resources/bootstrap.yml -index 520eb90..caedb1f 100644 ---- a/hl-user-service/src/main/resources/bootstrap.yml -+++ b/hl-user-service/src/main/resources/bootstrap.yml -@@ -5,7 +5,7 @@ spring: - active: dev - cloud: - nacos: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - config: - file-extension: yml - shared-configs: -@@ -13,6 +13,6 @@ spring: - group: DEFAULT_GROUP - refresh: true - discovery: -- server-addr: ${NACOS_SERVER_ADDR:192.168.100.236:8848} -+ server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848} - metadata: - description: "\u7528\u6237\u670D\u52A1" -``` - -## Service 业务逻辑变更 - -### `hl-callback-service/src/main/java/com/hulalv/callback/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/config/Knife4jConfig.java b/hl-callback-service/src/main/java/com/hulalv/callback/config/Knife4jConfig.java -index c64ad00..3fd0b5e 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/config/Knife4jConfig.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/config/Knife4jConfig.java -@@ -1,9 +1,9 @@ - package com.hulalv.callback.config; - -+import com.google.common.base.Predicate; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import springfox.documentation.builders.ApiInfoBuilder; --import springfox.documentation.builders.PathSelectors; - import springfox.documentation.builders.RequestHandlerSelectors; - import springfox.documentation.service.ApiInfo; - import springfox.documentation.spi.DocumentationType; -@@ -12,6 +12,11 @@ import springfox.documentation.spring.web.plugins.Docket; - @Configuration - public class Knife4jConfig { - -+ /** 排除内部接口和回调接口路径 */ -+ private Predicate adminPaths() { -+ return input -> input != null && !input.contains("/internal/") && !input.contains("/callback/"); -+ } -+ - @Bean - public Docket callbackApi() { - return new Docket(DocumentationType.SWAGGER_2) -@@ -19,7 +24,7 @@ public class Knife4jConfig { - .apiInfo(apiInfo()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.callback.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/controller/MsgAuditCallbackController.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/controller/MsgAuditCallbackController.java b/hl-callback-service/src/main/java/com/hulalv/callback/controller/MsgAuditCallbackController.java -index a9d6ea9..adf49be 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/controller/MsgAuditCallbackController.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/controller/MsgAuditCallbackController.java -@@ -21,7 +21,7 @@ import java.util.concurrent.Executors; - * 路径: /callback/msg-audit - */ - @Slf4j --@Api(tags = "【回调接口】会话内容存档") -+@Api(tags = "【回调接口】会话内容存档", hidden = true) - @RestController - @RequestMapping("/callback") - public class MsgAuditCallbackController { -@@ -59,7 +59,8 @@ public class MsgAuditCallbackController { - * URL 验证端点。 - * 企业微信配置回调 URL 时发送 GET 请求验证,需解密 echostr 并返回明文。 - */ -- @ApiOperation("会话内容存档回调URL验证") -+ @ApiOperation(value = "会话内容存档回调URL验证", -+ notes = "企业微信会话内容存档的回调URL验证端点。使用独立的Token/AESKey,在企微后台配置会话存档回调URL时进行验证。") - @GetMapping(value = "/msg-audit", produces = MediaType.TEXT_PLAIN_VALUE) - public String verifyUrl( - @RequestParam("msg_signature") String msgSignature, -@@ -89,7 +90,8 @@ public class MsgAuditCallbackController { - * 企业微信在有新的存档消息时 POST 加密 XML 事件通知。 - * 通知仅表示"有新消息可拉取",具体消息内容需通过 API 主动拉取。 - */ -- @ApiOperation("接收会话内容存档事件通知") -+ @ApiOperation(value = "接收会话内容存档事件通知", -+ notes = "企业微信在有新的存档消息时推送事件通知到此端点。通知仅表示'有新消息可拉取',收到后异步触发消息拉取任务(通过Finance SDK API主动拉取具体内容并存储)。必须5秒内返回'success'。") - @PostMapping(value = "/msg-audit", - consumes = {MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_XML_VALUE}, - produces = MediaType.TEXT_PLAIN_VALUE) -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/controller/WxCallbackController.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/controller/WxCallbackController.java b/hl-callback-service/src/main/java/com/hulalv/callback/controller/WxCallbackController.java -index cad043a..0b1d68b 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/controller/WxCallbackController.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/controller/WxCallbackController.java -@@ -27,7 +27,7 @@ import java.io.StringReader; - * No JWT auth required - uses WeChat's own signature verification. - */ - @Slf4j --@Api(tags = "【回调接口】企业微信回调") -+@Api(tags = "【回调接口】企业微信回调", hidden = true) - @RestController - @RequestMapping("/wx/callback") - public class WxCallbackController { -@@ -88,7 +88,8 @@ public class WxCallbackController { - * WeChat sends GET request to verify the callback URL. - * Must decrypt echostr and return it as plain text. - */ -- @ApiOperation("Callback URL verification") -+ @ApiOperation(value = "回调URL验证", -+ notes = "企业微信自建应用的回调URL验证端点。企微在配置回调URL时发送GET请求,需解密echostr并返回明文以完成验证。无需JWT认证,使用企微自有的签名校验机制。") - @GetMapping(value = "/app", produces = MediaType.TEXT_PLAIN_VALUE) - public String verifyUrl( - @RequestParam("msg_signature") String msgSignature, -@@ -118,7 +119,8 @@ public class WxCallbackController { - * WeChat POSTs encrypted XML for all event types. - * We decrypt, parse, dispatch to handler, and return "success". - */ -- @ApiOperation("Receive callback events") -+ @ApiOperation(value = "接收回调事件", -+ notes = "企业微信自建应用的事件接收端点。接收加密XML格式的事件通知(审批变更、消息等),解密后按事件类型分发:change_contact→通讯录变更,change_external_contact→外部联系人变更,open_approval_change→审批状态变更。必须5秒内返回'success'。") - @PostMapping(value = "/app", - consumes = {MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_XML_VALUE}, - produces = MediaType.TEXT_PLAIN_VALUE) -@@ -162,7 +164,8 @@ public class WxCallbackController { - // Contact Sync Callback Endpoints - // ========================================== - -- @ApiOperation("Contact sync URL verification") -+ @ApiOperation(value = "联系人同步URL验证", -+ notes = "企业微信通讯录同步的回调URL验证端点。使用独立的Token/AESKey(与应用回调不同),用于接收通讯录变更事件的回调URL配置验证。") - @GetMapping(value = "/contacts", produces = MediaType.TEXT_PLAIN_VALUE) - public String verifyContactsUrl( - @RequestParam("msg_signature") String msgSignature, -@@ -187,7 +190,8 @@ public class WxCallbackController { - return result; - } - -- @ApiOperation("Receive contact sync events") -+ @ApiOperation(value = "接收联系人同步事件", -+ notes = "企业微信通讯录变更事件接收端点。接收员工创建/更新/删除、部门变更等事件,解密后转发给ContactChangeHandler处理,同步更新本地管理员数据。必须5秒内返回'success'。") - @PostMapping(value = "/contacts", - consumes = {MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_XML_VALUE}, - produces = MediaType.TEXT_PLAIN_VALUE) -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/feign/UserServiceClient.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/feign/UserServiceClient.java b/hl-callback-service/src/main/java/com/hulalv/callback/feign/UserServiceClient.java -index 127e6f5..e8b0be4 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/feign/UserServiceClient.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/feign/UserServiceClient.java -@@ -11,17 +11,17 @@ import org.springframework.web.bind.annotation.*; - public interface UserServiceClient { - - @PostMapping("/internal/wechat/user/sync") -- Result syncUser(@RequestBody WechatUserSyncDTO dto); -+ Result syncUser(@RequestBody WechatUserSyncDTO dto); - - @DeleteMapping("/internal/wechat/user/{userid}") -- Result deleteUser(@PathVariable("userid") String userid); -+ Result deleteUser(@PathVariable("userid") String userid); - - @PostMapping("/internal/wechat/department/sync") -- Result syncDepartment(@RequestBody WechatDeptSyncDTO dto); -+ Result syncDepartment(@RequestBody WechatDeptSyncDTO dto); - - @DeleteMapping("/internal/wechat/department/{deptId}") -- Result deleteDepartment(@PathVariable("deptId") Long deptId); -+ Result deleteDepartment(@PathVariable("deptId") Long deptId); - - @PostMapping("/internal/wechat/external-contact/event") -- Result notifyExternalContactEvent(@RequestBody ExternalContactEventDTO dto); -+ Result notifyExternalContactEvent(@RequestBody ExternalContactEventDTO dto); - } -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/feign/UserServiceClientFallback.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/feign/UserServiceClientFallback.java b/hl-callback-service/src/main/java/com/hulalv/callback/feign/UserServiceClientFallback.java -index fe9a971..9a8d5e2 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/feign/UserServiceClientFallback.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/feign/UserServiceClientFallback.java -@@ -17,31 +17,31 @@ public class UserServiceClientFallback implements FallbackFactory syncUser(WechatUserSyncDTO dto) { -+ public Result syncUser(WechatUserSyncDTO dto) { - log.error("Failed to sync user: {}", dto.getUserid()); - return Result.error(500, "user-service unavailable"); - } - - @Override -- public Result deleteUser(String userid) { -+ public Result deleteUser(String userid) { - log.error("Failed to delete user: {}", userid); - return Result.error(500, "user-service unavailable"); - } - - @Override -- public Result syncDepartment(WechatDeptSyncDTO dto) { -+ public Result syncDepartment(WechatDeptSyncDTO dto) { - log.error("Failed to sync department: {}", dto.getId()); - return Result.error(500, "user-service unavailable"); - } - - @Override -- public Result deleteDepartment(Long deptId) { -+ public Result deleteDepartment(Long deptId) { - log.error("Failed to delete department: {}", deptId); - return Result.error(500, "user-service unavailable"); - } - - @Override -- public Result notifyExternalContactEvent(ExternalContactEventDTO dto) { -+ public Result notifyExternalContactEvent(ExternalContactEventDTO dto) { - log.error("Failed to notify external contact event: userId={}, changeType={}", - dto.getUserId(), dto.getChangeType()); - return Result.error(500, "user-service unavailable"); -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/handler/ApprovalEventHandler.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/handler/ApprovalEventHandler.java b/hl-callback-service/src/main/java/com/hulalv/callback/handler/ApprovalEventHandler.java -index 2f75d43..cd97724 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/handler/ApprovalEventHandler.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/handler/ApprovalEventHandler.java -@@ -117,7 +117,7 @@ public class ApprovalEventHandler { - // MQ-first for approval log, Feign fallback - if (!mqLogProducer.sendApprovalLog(dto)) { - try { -- Result result = monitorFeignClient.pushApprovalLog(dto); -+ Result result = monitorFeignClient.pushApprovalLog(dto); - if (result.getCode() != 200) { - log.error("Feign pushApprovalLog failed: code={}, msg={}", - result.getCode(), result.getMessage()); -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/handler/ContactChangeHandler.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/handler/ContactChangeHandler.java b/hl-callback-service/src/main/java/com/hulalv/callback/handler/ContactChangeHandler.java -index a288d73..85f2ff0 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/handler/ContactChangeHandler.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/handler/ContactChangeHandler.java -@@ -70,7 +70,7 @@ public class ContactChangeHandler { - } - - log.info("Syncing user via Feign: changeType={}, userid={}", changeType, userid); -- Result result = userServiceClient.syncUser(dto); -+ Result result = userServiceClient.syncUser(dto); - if (result.getCode() != 200) { - log.error("Feign syncUser failed: code={}, msg={}", result.getCode(), result.getMessage()); - } -@@ -84,7 +84,7 @@ public class ContactChangeHandler { - } - - log.info("Deleting user via Feign: userid={}", userid); -- Result result = userServiceClient.deleteUser(userid); -+ Result result = userServiceClient.deleteUser(userid); - if (result.getCode() != 200) { - log.error("Feign deleteUser failed: code={}, msg={}", result.getCode(), result.getMessage()); - } -@@ -119,7 +119,7 @@ public class ContactChangeHandler { - } - - log.info("Syncing department via Feign: changeType={}, deptId={}", changeType, dto.getId()); -- Result result = userServiceClient.syncDepartment(dto); -+ Result result = userServiceClient.syncDepartment(dto); - if (result.getCode() != 200) { - log.error("Feign syncDepartment failed: code={}, msg={}", result.getCode(), result.getMessage()); - } -@@ -140,7 +140,7 @@ public class ContactChangeHandler { - return; - } - log.info("Deleting department via Feign: deptId={}", deptId); -- Result result = userServiceClient.deleteDepartment(deptId); -+ Result result = userServiceClient.deleteDepartment(deptId); - if (result.getCode() != 200) { - log.error("Feign deleteDepartment failed: code={}, msg={}", result.getCode(), result.getMessage()); - } -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/handler/ExternalContactHandler.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/handler/ExternalContactHandler.java b/hl-callback-service/src/main/java/com/hulalv/callback/handler/ExternalContactHandler.java -index 9715b66..87f6e0b 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/handler/ExternalContactHandler.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/handler/ExternalContactHandler.java -@@ -55,7 +55,7 @@ public class ExternalContactHandler { - dto.setExternalUserId(externalUserId); - - try { -- Result result = userServiceClient.notifyExternalContactEvent(dto); -+ Result result = userServiceClient.notifyExternalContactEvent(dto); - if (result.getCode() != 200) { - log.error("Feign notifyExternalContactEvent failed: code={}, msg={}", - result.getCode(), result.getMessage()); -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/InternalChatMessageController.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/InternalChatMessageController.java b/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/InternalChatMessageController.java -index 36b5a17..88ee4df 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/InternalChatMessageController.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/InternalChatMessageController.java -@@ -27,7 +27,8 @@ public class InternalChatMessageController { - * @param roomId 群聊ID - * @param limit 最大条数(默认20,最大50) - */ -- @ApiOperation("查询指定群的最近消息") -+ @ApiOperation(value = "查询指定群的最近消息", -+ notes = "内部服务间调用。供其他服务通过Feign查询指定群聊的最近消息记录。返回消息基本信息(发送人、时间、类型、内容),不含发送人姓名/头像解析。limit默认20,最大50。") - @GetMapping("/messages") - public Result> getRecentMessages( - @RequestParam String roomId, -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/MsgAuditController.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/MsgAuditController.java b/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/MsgAuditController.java -index 57b84e3..9689460 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/MsgAuditController.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/MsgAuditController.java -@@ -29,7 +29,8 @@ public class MsgAuditController { - private final WechatGroupService wechatGroupService; - private final ChatMessageService chatMessageService; - -- @ApiOperation("获取开启存档的成员列表") -+ @ApiOperation(value = "获取开启存档的成员列表", -+ notes = "调用企微API获取已开启会话内容存档的企业成员列表,返回原始JSON。用于管理员查看哪些成员的聊天记录正在被存档。") - @GetMapping("/permit-users") - public Result getPermitUsers() { - try { -@@ -41,7 +42,8 @@ public class MsgAuditController { - } - } - -- @ApiOperation("获取群聊信息") -+ @ApiOperation(value = "获取群聊信息", -+ notes = "通过roomId调用企微API获取企业内部群的群聊信息(群名、群主、成员等),返回原始JSON。外部群无法通过此接口查询。") - @GetMapping("/group-chat") - public Result getGroupChatInfo( - @ApiParam("群聊ID (roomid)") @RequestParam String roomId) { -@@ -54,7 +56,8 @@ public class MsgAuditController { - } - } - -- @ApiOperation("检查群聊同意情况") -+ @ApiOperation(value = "检查群聊同意情况", -+ notes = "调用企微API检查指定群聊中各成员是否已同意会话内容存档。未同意的成员其聊天记录不会被存档。返回原始JSON。") - @GetMapping("/group-chat/agree") - public Result checkRoomAgree( - @ApiParam("群聊ID (roomid)") @RequestParam String roomId) { -@@ -67,7 +70,8 @@ public class MsgAuditController { - } - } - -- @ApiOperation("拉取聊天记录(需要 Finance SDK)") -+ @ApiOperation(value = "拉取聊天记录(需要 Finance SDK)", -+ notes = "通过Finance SDK拉取会话存档的聊天记录原始数据。需要本地部署Finance SDK动态库。seq为起始序号(0表示从头开始),limit为最大返回条数(上限1000)。返回原始JSON。") - @GetMapping("/chat-data") - public Result getChatData( - @ApiParam("起始序号(0=从头开始)") @RequestParam(defaultValue = "0") long seq, -@@ -81,7 +85,8 @@ public class MsgAuditController { - } - } - -- @ApiOperation("获取 SDK 状态") -+ @ApiOperation(value = "获取 SDK 状态", -+ notes = "检查Finance SDK动态库是否可用。可用时支持拉取聊天记录和下载媒体文件;不可用时仅支持HTTP管理API(成员列表、群聊信息等)。") - @GetMapping("/status") - public Result getStatus() { - boolean sdkAvailable = msgAuditService.isSdkAvailable(); -@@ -91,14 +96,16 @@ public class MsgAuditController { - return Result.success(status); - } - -- @ApiOperation("手动触发拉取消息") -+ @ApiOperation(value = "手动触发拉取消息", -+ notes = "手动触发一次消息拉取任务,从上次拉取位置开始拉取新消息并存入数据库。正常情况下由回调事件自动触发,此接口用于手动补拉或调试。返回本次新增的消息数量。") - @PostMapping("/pull") - public Result pullMessages() { - int count = chatMessageService.pullAndStoreMessages(); - return Result.success("拉取完成,新增 " + count + " 条消息"); - } - -- @ApiOperation("下载媒体文件(图片、视频等)") -+ @ApiOperation(value = "下载媒体文件(图片、视频等)", -+ notes = "通过Finance SDK下载会话存档中的媒体文件(图片、视频、语音、文件等)。需提供sdkfileid(从聊天记录中获取),可选md5sum用于校验。返回二进制文件流(默认Content-Type为image/jpeg)。需要Finance SDK可用。") - @GetMapping("/media") - public ResponseEntity downloadMedia( - @ApiParam("SDK文件ID") @RequestParam String sdkfileid, -@@ -119,19 +126,22 @@ public class MsgAuditController { - // 群组管理 - // ========================================== - -- @ApiOperation("群组列表") -+ @ApiOperation(value = "群组列表", -+ notes = "获取已添加的企微群组列表。返回所有已录入的群组信息(群名、roomId、群主、成员数、备注等)。群组需先通过'添加群组'接口录入。") - @GetMapping("/groups") - public Result> listGroups() { - return Result.success(wechatGroupService.listGroups()); - } - -- @ApiOperation("发现群组(从消息记录中自动发现未添加的群)") -+ @ApiOperation(value = "发现群组(从消息记录中自动发现未添加的群)", -+ notes = "扫描已拉取的聊天消息记录,自动发现尚未录入群组管理的群聊roomId。返回未添加的群列表及基本信息,管理员可据此选择性添加需要监控的群组。") - @GetMapping("/groups/discover") - public Result>> discoverGroups() { - return Result.success(wechatGroupService.discoverGroups()); - } - -- @ApiOperation("查看群最近消息") -+ @ApiOperation(value = "查看群最近消息", -+ notes = "查询指定群聊的最近消息记录。返回消息列表(含发送人姓名、头像、消息类型、内容、时间等)。limit最大50条。发送人信息通过批量解析userId获取(企微成员显示姓名+头像,外部人员显示userId)。") - @GetMapping("/groups/messages") - public Result> getGroupMessages( - @ApiParam("群聊ID") @RequestParam String roomId, -@@ -162,7 +172,8 @@ public class MsgAuditController { - return Result.success(voList); - } - -- @ApiOperation("添加群组(输入roomId,自动尝试同步群信息)") -+ @ApiOperation(value = "添加群组(输入roomId,自动尝试同步群信息)", -+ notes = "将指定群聊添加到群组管理列表。自动尝试通过企微API同步群信息(群名、群主、成员等)。内部群可自动获取群信息,外部群需手动填写groupName。可选填写remark备注。") - @PostMapping("/groups") - public Result addGroup( - @ApiParam("群聊ID") @RequestParam String roomId, -@@ -175,7 +186,8 @@ public class MsgAuditController { - } - } - -- @ApiOperation("同步群组信息(从企微API刷新)") -+ @ApiOperation(value = "同步群组信息(从企微API刷新)", -+ notes = "从企微API重新拉取指定群组的最新信息(群名、群主、成员列表等)并更新本地记录。仅对内部群有效,外部群无法通过API同步。") - @PostMapping("/groups/{id}/sync") - public Result syncGroup(@PathVariable Long id) { - try { -@@ -185,7 +197,8 @@ public class MsgAuditController { - } - } - -- @ApiOperation("更新群组信息(群名、备注)") -+ @ApiOperation(value = "更新群组信息(群名、备注)", -+ notes = "手动修改群组的显示名称和备注信息。适用于外部群(无法自动同步群名)或需要自定义备注的场景。groupName和remark均为可选,传入哪个更新哪个。") - @PutMapping("/groups/{id}") - public Result updateGroup( - @PathVariable Long id, -@@ -195,7 +208,8 @@ public class MsgAuditController { - return Result.success(null); - } - -- @ApiOperation("删除群组") -+ @ApiOperation(value = "删除群组", -+ notes = "从群组管理列表中删除指定群组。仅删除本地管理记录,不影响企微实际群聊和已拉取的历史消息数据。") - @DeleteMapping("/groups/{id}") - public Result deleteGroup(@PathVariable Long id) { - wechatGroupService.deleteGroup(id); -``` - -### `hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/vo/ChatMessageVO.java` (M) - -```diff -diff --git a/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/vo/ChatMessageVO.java b/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/vo/ChatMessageVO.java -index cc334e0..001c095 100644 ---- a/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/vo/ChatMessageVO.java -+++ b/hl-callback-service/src/main/java/com/hulalv/callback/msgaudit/vo/ChatMessageVO.java -@@ -1,15 +1,33 @@ - package com.hulalv.callback.msgaudit.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("聊天消息VO") - public class ChatMessageVO { -+ @ApiModelProperty("消息ID") - private String msgId; -+ -+ @ApiModelProperty("发送人ID") - private String fromUser; -+ -+ @ApiModelProperty("发送人姓名") - private String fromUserName; -+ -+ @ApiModelProperty("发送人头像") - private String fromUserAvatar; -+ -+ @ApiModelProperty("群聊ID") - private String roomId; -+ -+ @ApiModelProperty("消息时间戳") - private Long msgTime; -+ -+ @ApiModelProperty("消息类型") - private String msgType; -+ -+ @ApiModelProperty("消息内容") - private String content; - } -``` - -### `hl-contract-service/src/main/java/com/hulalv/contract/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-contract-service/src/main/java/com/hulalv/contract/config/Knife4jConfig.java b/hl-contract-service/src/main/java/com/hulalv/contract/config/Knife4jConfig.java -index 9813464..ca855b5 100644 ---- a/hl-contract-service/src/main/java/com/hulalv/contract/config/Knife4jConfig.java -+++ b/hl-contract-service/src/main/java/com/hulalv/contract/config/Knife4jConfig.java -@@ -1,9 +1,9 @@ - package com.hulalv.contract.config; - -+import com.google.common.base.Predicate; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import springfox.documentation.builders.ApiInfoBuilder; --import springfox.documentation.builders.PathSelectors; - import springfox.documentation.builders.RequestHandlerSelectors; - import springfox.documentation.spi.DocumentationType; - import springfox.documentation.spring.web.plugins.Docket; -@@ -11,6 +11,11 @@ import springfox.documentation.spring.web.plugins.Docket; - @Configuration - public class Knife4jConfig { - -+ /** 排除内部接口和回调接口路径 */ -+ private Predicate adminPaths() { -+ return input -> input != null && !input.contains("/internal/") && !input.contains("/callback/"); -+ } -+ - @Bean - public Docket contractApi() { - return new Docket(DocumentationType.SWAGGER_2) -@@ -22,7 +27,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.contract.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - } -``` - -### `hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminClauseTemplateController.java` (M) - -```diff -diff --git a/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminClauseTemplateController.java b/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminClauseTemplateController.java -index f955c57..91ac6ed 100644 ---- a/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminClauseTemplateController.java -+++ b/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminClauseTemplateController.java -@@ -21,31 +21,33 @@ public class AdminClauseTemplateController { - - private final ClauseTemplateService clauseTemplateService; - -- @ApiOperation("获取启用的补充约定模板列表(创建合同用)") -+ @ApiOperation(value = "获取启用的补充约定模板列表(创建合同用)", -+ notes = "返回所有启用状态的补充约定模板,创建合同时选择需要附加的补充约定条款。\n\n**权限**:需管理员登录。") - @GetMapping("/list") - public Result> listActive() { - return Result.success(clauseTemplateService.listActive()); - } - -- @ApiOperation("获取全部补充约定模板(管理页用)") -+ @ApiOperation(value = "获取全部补充约定模板(管理页用)", notes = "**关联字典**:\n- common_status:通用状态(列表显示,ACTIVE=启用/INACTIVE=停用)") - @GetMapping("/list-all") - public Result> listAll() { - return Result.success(clauseTemplateService.listAll()); - } - -- @ApiOperation("切换模板启用/停用状态") -+ @ApiOperation(value = "切换模板启用/停用状态", notes = "**关联字典**:\n- common_status:通用状态(状态切换,ACTIVE=启用/INACTIVE=停用)") - @PutMapping("/{id}/toggle-status") - public Result toggleStatus(@ApiParam("模板ID") @PathVariable("id") Long templateId) { - return Result.success(clauseTemplateService.toggleStatus(templateId)); - } - -- @ApiOperation("创建补充约定模板") -+ @ApiOperation(value = "创建补充约定模板", notes = "创建合同补充约定的模板,支持变量占位符。创建后默认启用") - @PostMapping - public Result create(@Valid @RequestBody ClauseTemplateRequest request) { - return Result.success(clauseTemplateService.create(request)); - } - -- @ApiOperation("更新补充约定模板") -+ @ApiOperation(value = "更新补充约定模板", -+ notes = "更新模板的标题和内容。已被合同引用的模板更新不影响已创建的合同(合同记录的是快照内容)。\n\n**权限**:需管理员登录。") - @PutMapping("/{id}") - public Result update( - @ApiParam("模板ID") @PathVariable("id") Long templateId, -@@ -53,7 +55,7 @@ public class AdminClauseTemplateController { - return Result.success(clauseTemplateService.update(templateId, request)); - } - -- @ApiOperation("删除补充约定模板") -+ @ApiOperation(value = "删除补充约定模板", notes = "软删除模板。已被合同引用的模板仍可删除,不影响已创建的合同") - @DeleteMapping("/{id}") - public Result delete(@ApiParam("模板ID") @PathVariable("id") Long templateId) { - clauseTemplateService.delete(templateId); -``` - -### `hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminContractController.java` (M) - -```diff -diff --git a/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminContractController.java b/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminContractController.java -index a6a6dbe..437717e 100644 ---- a/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminContractController.java -+++ b/hl-contract-service/src/main/java/com/hulalv/contract/controller/AdminContractController.java -@@ -30,19 +30,20 @@ public class AdminContractController { - - private final ContractService contractService; - -- @ApiOperation("可用旅行社列表") -+ @ApiOperation(value = "可用旅行社列表", notes = "返回系统配置的旅行社列表,创建合同时选择签约旅行社") - @GetMapping("/agencies") - public Result> listAgencies() { - return Result.success(contractService.listAgencies()); - } - -- @ApiOperation("合同模板列表") -+ @ApiOperation(value = "合同模板列表", notes = "返回合同平台可用的合同模板列表,创建合同时选择模板") - @GetMapping("/templates") - public Result> listTemplates() { - return Result.success(contractService.listTemplates()); - } - -- @ApiOperation("创建合同(标准模式)") -+ @ApiOperation(value = "创建合同(标准模式)", notes = "标准电子签约流程:创建合同 → 平台生成合同PDF → 发送签署短信给出行人 → 出行人在线签署 → 回调更新状态。" -+ + "状态流转:CREATED → SIGNING → SIGNED") - @PostMapping("/create") - public Result createContract( - @ApiParam("创建合同请求") @Valid @RequestBody CreateContractRequest request, -@@ -51,7 +52,8 @@ public class AdminContractController { - return Result.success(contractService.createContract(request, adminId)); - } - -- @ApiOperation("报备合同(同步模式)") -+ @ApiOperation(value = "报备合同(同步模式)", notes = "线下签约模式:创建合同记录 → 管理员上传已签署的PDF → 同步到12301报备平台。" -+ + "状态流转:CREATED → UPLOADED → REPORTED") - @PostMapping("/report") - public Result reportContract( - @ApiParam("报备合同请求") @Valid @RequestBody ReportContractRequest request, -@@ -60,49 +62,51 @@ public class AdminContractController { - return Result.success(contractService.reportContract(request, adminId)); - } - -- @ApiOperation("合同列表") -+ @ApiOperation(value = "合同列表", notes = "分页查询合同记录,支持按订单号、合同状态、旅行社筛选\n\n**关联字典**:\n- contract_status:合同状态(列表筛选+显示)") - @GetMapping("/list") - public Result> listContracts(@ApiParam("合同查询条件") ContractQueryRequest request) { - return Result.success(contractService.listContracts(request)); - } - -- @ApiOperation("合同详情") -+ @ApiOperation(value = "合同详情", notes = "**关联字典**:\n- contract_status:合同状态(显示)") - @GetMapping("/{id}") - public Result getContractDetail(@ApiParam("合同ID") @PathVariable("id") Long contractId) { - return Result.success(contractService.getContractDetail(contractId)); - } - -- @ApiOperation("按订单查询合同") -+ @ApiOperation(value = "按订单查询合同", -+ notes = "查询指定订单下的所有合同记录(含已作废),按创建时间倒序排列。用于订单详情页展示合同历史。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- contract_status:合同状态(列表显示)") - @GetMapping("/by-order/{orderId}") - public Result> getByOrder(@ApiParam("订单ID") @PathVariable Long orderId) { - return Result.success(contractService.getByOrderId(orderId)); - } - -- @ApiOperation("获取订单有效合同") -+ @ApiOperation(value = "获取订单有效合同", -+ notes = "返回订单当前有效的合同(非作废状态的最新合同),用于检查订单是否已有签署中或已签署的合同。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- contract_status:合同状态(显示)") - @GetMapping("/active-by-order/{orderId}") - public Result getActiveByOrder(@ApiParam("订单ID") @PathVariable Long orderId) { - return Result.success(contractService.getActiveContractByOrderId(orderId)); - } - -- @ApiOperation("刷新合同状态(从平台同步)") -+ @ApiOperation(value = "刷新合同状态(从平台同步)", notes = "主动查询合同平台的最新签署状态并同步到本地,适用于回调未到达的场景") - @GetMapping("/{id}/status") - public Result refreshStatus(@ApiParam("合同ID") @PathVariable("id") Long contractId) { - return Result.success(contractService.refreshStatus(contractId)); - } - -- @ApiOperation("作废合同") -+ @ApiOperation(value = "作废合同", notes = "将合同标记为作废状态(不可恢复)。作废后该合同不再有效,可重新为订单创建新合同") - @PostMapping("/{id}/invalidate") - public Result invalidateContract(@ApiParam("合同ID") @PathVariable("id") Long contractId) { - return Result.success(contractService.invalidateContract(contractId)); - } - -- @ApiOperation("重发签署短信") -+ @ApiOperation(value = "重发签署短信", notes = "重新发送签署短信给出行人,用于签署短信过期或未收到的场景。仅SIGNING状态的合同可操作") - @PostMapping("/{id}/resend-sms") - public Result resendSms(@ApiParam("合同ID") @PathVariable("id") Long contractId) { - return Result.success(contractService.resendSms(contractId)); - } - -- @ApiOperation("上传已签署PDF(同步模式)") -+ @ApiOperation(value = "上传已签署PDF(同步模式)", notes = "同步模式专用:上传线下签署完成的合同PDF文件,上传后合同状态变为UPLOADED,可进一步报备") - @PostMapping("/{id}/upload-pdf") - public Result uploadPdf( - @ApiParam("合同ID") @PathVariable("id") Long contractId, -``` - -### `hl-contract-service/src/main/java/com/hulalv/contract/controller/ContractCallbackController.java` (M) - -```diff -diff --git a/hl-contract-service/src/main/java/com/hulalv/contract/controller/ContractCallbackController.java b/hl-contract-service/src/main/java/com/hulalv/contract/controller/ContractCallbackController.java -index 8415d27..bad13a5 100644 ---- a/hl-contract-service/src/main/java/com/hulalv/contract/controller/ContractCallbackController.java -+++ b/hl-contract-service/src/main/java/com/hulalv/contract/controller/ContractCallbackController.java -@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.*; - - import javax.validation.Valid; - --@Api(tags = "【回调接口】合同回调") -+@Api(tags = "【回调接口】合同回调", hidden = true) - @Slf4j - @RestController - @RequestMapping("/contract/callback") -@@ -20,7 +20,7 @@ public class ContractCallbackController { - - private final ContractCallbackService callbackService; - -- @ApiOperation("12301合同状态回调") -+ @ApiOperation(value = "12301合同状态回调", notes = "接收12301全国旅游监管平台的合同签署状态回调。出行人签署完成后平台推送状态变更到此接口,自动更新本地合同状态") - @PostMapping("/12301") - public ResponseEntity handle12301Callback(@Valid @RequestBody ContractCallbackPayload payload) { - log.info("Received 12301 callback: contractNumber={}, state={}", -``` - -### `hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalContractController.java` (M) - -```diff -diff --git a/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalContractController.java b/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalContractController.java -index 8929f18..3c25a33 100644 ---- a/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalContractController.java -+++ b/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalContractController.java -@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "【内部接口】合同(Feign调用)") -+@Api(tags = "【内部接口】合同(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/contract") - @RequiredArgsConstructor -@@ -19,19 +19,19 @@ public class InternalContractController { - - private final ContractService contractService; - -- @ApiOperation("按订单查询合同(内部调用)") -+ @ApiOperation(value = "按订单查询合同(内部调用)", notes = "**关联字典**:\n- contract_status:合同状态(返回字段)") - @GetMapping("/by-order/{orderId}") - public Result> getByOrder(@PathVariable Long orderId) { - return Result.success(contractService.getByOrderId(orderId)); - } - -- @ApiOperation("按订单批量查询合同(内部调用)") -+ @ApiOperation(value = "按订单批量查询合同(内部调用)", notes = "**关联字典**:\n- contract_status:合同状态(返回字段)") - @PostMapping("/by-orders") - public Result>> getByOrders(@RequestBody List orderIds) { - return Result.success(contractService.getByOrderIds(orderIds)); - } - -- @ApiOperation("检查订单是否有已签署合同(内部调用)") -+ @ApiOperation(value = "检查订单是否有已签署合同(内部调用)", notes = "检查订单是否存在有效签署的合同(SIGNED/REPORTED/UPLOADED状态),用于订单流程中的合同校验") - @GetMapping("/has-signed/{orderId}") - public Result hasSigned(@PathVariable Long orderId) { - List contracts = contractService.getByOrderId(orderId); -@@ -41,7 +41,7 @@ public class InternalContractController { - return Result.success(signed); - } - -- @ApiOperation("按订单作废所有有效合同(级联调用)") -+ @ApiOperation(value = "按订单作废所有有效合同(级联调用)", notes = "订单取消或退款时级联作废该订单下所有有效合同,reason参数记录作废原因") - @PostMapping("/invalidate/{orderId}") - public Result invalidateByOrder(@PathVariable Long orderId, - @RequestParam(value = "reason", required = false) String reason) { -``` - -### `hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalMpContractController.java` (M) - -```diff -diff --git a/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalMpContractController.java b/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalMpContractController.java -index 90d323c..bbb5883 100644 ---- a/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalMpContractController.java -+++ b/hl-contract-service/src/main/java/com/hulalv/contract/controller/InternalMpContractController.java -@@ -16,7 +16,7 @@ import java.util.Map; - * C端合同内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "【内部接口】小程序合同(Feign调用)") -+@Api(tags = "【内部接口】小程序合同(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/contract") - @RequiredArgsConstructor -@@ -24,7 +24,7 @@ public class InternalMpContractController { - - private final ContractService contractService; - -- @ApiOperation("用户合同列表") -+ @ApiOperation(value = "用户合同列表", notes = "**关联字典**:\n- contract_status:合同状态(列表筛选+显示)") - @GetMapping("/list") - public Result> listContracts( - @RequestParam Long userId, -@@ -34,7 +34,7 @@ public class InternalMpContractController { - return Result.success(contractService.listUserContracts(userId, status, page, pageSize)); - } - -- @ApiOperation("用户合同详情") -+ @ApiOperation(value = "用户合同详情", notes = "**关联字典**:\n- contract_status:合同状态(显示)") - @GetMapping("/{id}") - public Result getContractDetail( - @PathVariable("id") Long contractId, -@@ -42,7 +42,7 @@ public class InternalMpContractController { - return Result.success(contractService.getUserContractDetail(contractId, userId)); - } - -- @ApiOperation("按订单查合同(返回最新有效合同)") -+ @ApiOperation(value = "按订单查合同(返回最新有效合同)", notes = "**关联字典**:\n- contract_status:合同状态(显示)") - @GetMapping("/by-order/{orderId}") - public Result getContractByOrder( - @PathVariable Long orderId, -@@ -50,7 +50,7 @@ public class InternalMpContractController { - return Result.success(contractService.getUserContractByOrderId(orderId, userId)); - } - -- @ApiOperation("按订单查所有有效合同(TOUR+INSURANCE各一条)") -+ @ApiOperation(value = "按订单查所有有效合同(TOUR+INSURANCE各一条)", notes = "**关联字典**:\n- contract_status:合同状态(显示)") - @GetMapping("/by-order/{orderId}/all") - public Result> getContractsByOrder( - @PathVariable Long orderId, -@@ -58,7 +58,8 @@ public class InternalMpContractController { - return Result.success(contractService.getUserContractsByOrderId(orderId, userId)); - } - -- @ApiOperation("重新发送合同签署短信") -+ @ApiOperation(value = "重新发送合同签署短信", -+ notes = "内部服务间调用。小程序端用户请求重发签署短信,用于签署链接过期或短信未收到的场景。仅SIGNING状态的合同可操作。\n\n**关联字典**:\n- contract_status:合同状态(仅SIGNING可操作)") - @PostMapping("/{contractId}/resend-sms") - public Result resendContractSms( - @PathVariable("contractId") Long contractId, -``` - -### `hl-file-service/src/main/java/com/hulalv/file/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-file-service/src/main/java/com/hulalv/file/config/Knife4jConfig.java b/hl-file-service/src/main/java/com/hulalv/file/config/Knife4jConfig.java -index 59a5ded..39f6e7a 100644 ---- a/hl-file-service/src/main/java/com/hulalv/file/config/Knife4jConfig.java -+++ b/hl-file-service/src/main/java/com/hulalv/file/config/Knife4jConfig.java -@@ -1,9 +1,9 @@ - package com.hulalv.file.config; - -+import com.google.common.base.Predicate; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import springfox.documentation.builders.ApiInfoBuilder; --import springfox.documentation.builders.PathSelectors; - import springfox.documentation.builders.RequestHandlerSelectors; - import springfox.documentation.spi.DocumentationType; - import springfox.documentation.spring.web.plugins.Docket; -@@ -11,6 +11,11 @@ import springfox.documentation.spring.web.plugins.Docket; - @Configuration - public class Knife4jConfig { - -+ /** 排除内部接口和回调接口路径 */ -+ private Predicate adminPaths() { -+ return input -> input != null && !input.contains("/internal/") && !input.contains("/callback/"); -+ } -+ - @Bean - public Docket fileApi() { - return new Docket(DocumentationType.SWAGGER_2) -@@ -22,7 +27,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.file.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - } -``` - -### `hl-file-service/src/main/java/com/hulalv/file/controller/FileController.java` (M) - -```diff -diff --git a/hl-file-service/src/main/java/com/hulalv/file/controller/FileController.java b/hl-file-service/src/main/java/com/hulalv/file/controller/FileController.java -index 5b04b02..c78b2d2 100644 ---- a/hl-file-service/src/main/java/com/hulalv/file/controller/FileController.java -+++ b/hl-file-service/src/main/java/com/hulalv/file/controller/FileController.java -@@ -33,7 +33,7 @@ public class FileController { - private final FileService fileService; - private final FileRefService fileRefService; - -- @ApiOperation("请求上传凭证") -+ @ApiOperation(value = "请求上传凭证", notes = "上传流程第一步:前端请求上传凭证 → 获取OSS预签名URL和临时凭证 → 前端直传OSS → 调用确认上传接口。凭证有效期有限,过期需重新请求") - @OperationLog(value = "请求上传凭证", module = "文件管理") - @PostMapping("/upload/token") - public Result requestUploadToken( -@@ -44,7 +44,7 @@ public class FileController { - return Result.success(vo); - } - -- @ApiOperation("确认上传完成") -+ @ApiOperation(value = "确认上传完成", notes = "上传流程第二步:前端直传OSS完成后调用此接口,系统验证文件存在性并创建文件记录。支持MD5去重,相同文件不会重复存储") - @OperationLog(value = "确认上传", module = "文件管理") - @PostMapping("/upload/confirm") - public Result confirmUpload( -@@ -55,21 +55,21 @@ public class FileController { - return Result.success(vo); - } - -- @ApiOperation("文件列表(分页)") -+ @ApiOperation(value = "文件列表(分页)", notes = "支持按文件类型、分组、上传者等条件筛选,按上传时间倒序分页返回\n\n**关联字典**:\n- file_type:文件类型(列表筛选+显示)\n- file_status:文件状态(显示)") - @GetMapping("/list") - public Result> listFiles(@ApiParam("文件查询条件") @Valid FileQueryRequest request) { - IPage page = fileService.listFiles(request); - return Result.success(page); - } - -- @ApiOperation("文件详情") -+ @ApiOperation(value = "文件详情", notes = "**关联字典**:\n- file_type:文件类型(显示)\n- file_status:文件状态(显示)") - @GetMapping("/{fileId}") - public Result getFileDetail(@ApiParam("文件ID") @PathVariable Long fileId) { - FileVO vo = fileService.getFileDetail(fileId); - return Result.success(vo); - } - -- @ApiOperation("删除文件") -+ @ApiOperation(value = "删除文件", notes = "软删除文件记录,如果文件存在引用关系则不允许删除。OSS上的物理文件由定时任务清理") - @OperationLog(value = "删除文件", module = "文件管理") - @DeleteMapping("/{fileId}") - public Result deleteFile(@ApiParam("文件ID") @PathVariable Long fileId) { -@@ -77,21 +77,21 @@ public class FileController { - return Result.success(null); - } - -- @ApiOperation("文件引用列表") -+ @ApiOperation(value = "文件引用列表", notes = "查看文件被哪些业务实体引用(如景区封面、酒店图片等),用于判断文件是否可安全删除") - @GetMapping("/{fileId}/refs") - public Result> getFileRefs(@ApiParam("文件ID") @PathVariable Long fileId) { - List refs = fileRefService.getRefsByFileId(fileId); - return Result.success(refs); - } - -- @ApiOperation("存储统计") -+ @ApiOperation(value = "存储统计", notes = "返回文件总数、总存储空间、各类型文件占比等统计信息") - @GetMapping("/stats") - public Result getStats() { - FileStatsVO stats = fileService.getStats(); - return Result.success(stats); - } - -- @ApiOperation("文件内容流式预览") -+ @ApiOperation(value = "文件内容流式预览", notes = "流式输出文件内容,设置正确的Content-Type头,支持浏览器直接预览图片和PDF等文件") - @GetMapping("/{fileId}/preview") - public void previewContent(@ApiParam("文件ID") @PathVariable Long fileId, HttpServletResponse response) throws IOException { - fileService.streamContent(fileId, response); -``` - -### `hl-file-service/src/main/java/com/hulalv/file/controller/InternalFileController.java` (M) - -```diff -diff --git a/hl-file-service/src/main/java/com/hulalv/file/controller/InternalFileController.java b/hl-file-service/src/main/java/com/hulalv/file/controller/InternalFileController.java -index cf46b6b..3690ff3 100644 ---- a/hl-file-service/src/main/java/com/hulalv/file/controller/InternalFileController.java -+++ b/hl-file-service/src/main/java/com/hulalv/file/controller/InternalFileController.java -@@ -30,7 +30,7 @@ import org.springframework.web.multipart.MultipartFile; - import javax.validation.Valid; - import java.util.List; - --@Api(tags = "【内部接口】文件(Feign调用)") -+@Api(tags = "【内部接口】文件(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/file") - @RequiredArgsConstructor -@@ -40,28 +40,30 @@ public class InternalFileController { - private final FileRefService fileRefService; - private final ChunkUploadService chunkUploadService; - -- @ApiOperation("绑定文件到业务实体") -+ @ApiOperation(value = "绑定文件到业务实体", notes = "将文件与业务实体建立引用关系(如景区ID+封面图),同一文件可被多个业务实体引用") - @PostMapping("/bindRefs") - public Result bindRefs(@Valid @RequestBody BindRefsRequest request) { - fileRefService.bindRefs(request.getBizType(), request.getBizId(), request.getFileIds()); - return Result.success(null); - } - -- @ApiOperation("解绑业务实体的所有文件") -+ @ApiOperation(value = "解绑业务实体的所有文件", notes = "删除指定业务类型+业务ID下的所有文件引用关系,常用于业务实体删除时的级联清理") - @PostMapping("/unbindRefs") - public Result unbindRefs(@Valid @RequestBody UnbindRefsRequest request) { - fileRefService.unbindRefs(request.getBizType(), request.getBizId()); - return Result.success(null); - } - -- @ApiOperation("批量获取文件信息") -+ @ApiOperation(value = "批量获取文件信息", -+ notes = "内部服务间调用。根据文件ID列表批量查询文件信息(含OSS URL、文件名、类型等),用于其他服务获取关联文件的详细数据。") - @PostMapping("/byIds") - public Result> getFilesByIds(@Valid @RequestBody BatchFileRequest request) { - List files = fileService.getFilesByIds(request.getFileIds()); - return Result.success(files); - } - -- @ApiOperation("内部上传凭证(素材服务调用)") -+ @ApiOperation(value = "内部上传凭证(素材服务调用)", -+ notes = "内部服务间调用。素材服务代理调用,为指定管理员生成OSS上传预签名URL和临时凭证,用于素材库的文件上传流程。") - @PostMapping("/upload/token") - public Result requestUploadTokenInternal( - @Valid @RequestBody UploadTokenRequest request, -@@ -69,7 +71,7 @@ public class InternalFileController { - return Result.success(fileService.requestUploadToken(request, adminId)); - } - -- @ApiOperation("内部直接上传文件(服务间调用)") -+ @ApiOperation(value = "内部直接上传文件(服务间调用)", notes = "服务间直接上传文件到OSS,跳过预签名流程。返回OSS公开访问URL,适用于后端生成的文件(如路线地图截图)") - @PostMapping("/upload/direct") - public Result uploadDirect( - @RequestParam("file") MultipartFile file, -@@ -78,7 +80,8 @@ public class InternalFileController { - return Result.success(vo.getOssUrl()); - } - -- @ApiOperation("内部确认上传(素材服务调用)") -+ @ApiOperation(value = "内部确认上传(素材服务调用)", -+ notes = "内部服务间调用。素材服务代理调用,确认文件已上传至OSS并创建文件记录。支持MD5去重。") - @PostMapping("/upload/confirm") - public Result confirmUploadInternal( - @Valid @RequestBody UploadConfirmRequest request, -@@ -88,7 +91,7 @@ public class InternalFileController { - - // ==================== 分片上传 ==================== - -- @ApiOperation("分片上传-初始化") -+ @ApiOperation(value = "分片上传-初始化", notes = "大文件上传第一步:初始化分片上传任务,返回uploadId和每个分片的预签名URL。前端按分片并发上传后调用complete接口合并") - @PostMapping("/upload/chunk/init") - public Result chunkUploadInit( - @Valid @RequestBody ChunkUploadInitRequest request, -@@ -96,7 +99,7 @@ public class InternalFileController { - return Result.success(chunkUploadService.initChunkUpload(request, adminId)); - } - -- @ApiOperation("分片上传-上传分片") -+ @ApiOperation(value = "分片上传-上传分片", notes = "大文件上传第二步:逐个上传分片,返回分片的ETag用于后续合并校验。支持断点续传,已上传的分片无需重传") - @PostMapping("/upload/chunk") - public Result chunkUploadPart( - @RequestParam("uploadId") String uploadId, -@@ -105,14 +108,14 @@ public class InternalFileController { - return Result.success(chunkUploadService.uploadChunk(uploadId, chunkIndex, chunk)); - } - -- @ApiOperation("分片上传-完成合并") -+ @ApiOperation(value = "分片上传-完成合并", notes = "大文件上传第三步:所有分片上传完成后调用,OSS端合并分片为完整文件并创建文件记录") - @PostMapping("/upload/chunk/complete") - public Result chunkUploadComplete( - @Valid @RequestBody ChunkUploadCompleteRequest request) { - return Result.success(chunkUploadService.completeChunkUpload(request.getUploadId())); - } - -- @ApiOperation("分片上传-取消") -+ @ApiOperation(value = "分片上传-取消", notes = "取消分片上传任务,清理已上传的分片数据和OSS临时文件") - @PostMapping("/upload/chunk/cancel") - public Result chunkUploadCancel( - @Valid @RequestBody ChunkUploadCancelRequest request) { -``` - -### `hl-file-service/src/main/java/com/hulalv/file/controller/MpFileController.java` (M) - -```diff -diff --git a/hl-file-service/src/main/java/com/hulalv/file/controller/MpFileController.java b/hl-file-service/src/main/java/com/hulalv/file/controller/MpFileController.java -index b78e094..73b8a70 100644 ---- a/hl-file-service/src/main/java/com/hulalv/file/controller/MpFileController.java -+++ b/hl-file-service/src/main/java/com/hulalv/file/controller/MpFileController.java -@@ -23,7 +23,7 @@ public class MpFileController { - - private final FileService fileService; - -- @ApiOperation("上传文件(C端用户)") -+ @ApiOperation(value = "上传文件(C端用户)", notes = "小程序端直接上传文件,支持头像、评价图片等场景。groupKey决定存储路径和文件策略,默认为avatar") - @PostMapping("/upload") - public Result upload( - @ApiParam("上传文件") @RequestParam("file") MultipartFile file, -@@ -34,7 +34,8 @@ public class MpFileController { - return Result.success(vo); - } - -- @ApiOperation("文件内容流式预览") -+ @ApiOperation(value = "文件内容流式预览", -+ notes = "流式输出文件内容,设置正确的Content-Type头。用于小程序端通过web-view直接预览图片和PDF等文件。") - @GetMapping("/{fileId}/preview") - public void previewContent(@ApiParam("文件ID") @PathVariable Long fileId, HttpServletResponse response) throws IOException { - fileService.streamContent(fileId, response); -``` - -### `hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideArticleController.java` (M) - -```diff -diff --git a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideArticleController.java b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideArticleController.java -index a96b208..10fe073 100644 ---- a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideArticleController.java -+++ b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideArticleController.java -@@ -22,19 +22,20 @@ public class AdminGuideArticleController { - - private final GuideArticleService articleService; - -- @ApiOperation("文章列表") -+ @ApiOperation(value = "文章列表", notes = "分页查询攻略文章,支持按分类、状态、关键词筛选\n\n**关联字典**:\n- wiki_status:文章状态(列表筛选+显示)") - @GetMapping("/list") - public Result> listArticles(@Valid ArticleQueryRequest query) { - return Result.success(articleService.listArticles(query)); - } - -- @ApiOperation("文章详情") -+ @ApiOperation(value = "文章详情", notes = "**关联字典**:\n- wiki_status:文章状态(显示)") - @GetMapping("/{articleId}") - public Result getArticle(@PathVariable Long articleId) { - return Result.success(articleService.getArticle(articleId)); - } - -- @ApiOperation("创建文章") -+ @ApiOperation(value = "创建文章", -+ notes = "创建攻略文章,需指定分类。创建后默认为草稿状态,需手动发布后小程序端才可见。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- wiki_status:文章状态(创建后默认DRAFT)") - @PostMapping - public Result createArticle( - @Valid @RequestBody ArticleCreateRequest request, -@@ -43,7 +44,8 @@ public class AdminGuideArticleController { - return Result.success(articleService.createArticle(request, adminId)); - } - -- @ApiOperation("更新文章") -+ @ApiOperation(value = "更新文章", -+ notes = "更新攻略文章的标题、内容、封面图、分类等信息。已发布的文章更新后立即生效。\n\n**权限**:需管理员登录。") - @PutMapping("/{articleId}") - public Result updateArticle( - @PathVariable Long articleId, -@@ -51,14 +53,15 @@ public class AdminGuideArticleController { - return Result.success(articleService.updateArticle(articleId, request)); - } - -- @ApiOperation("删除文章") -+ @ApiOperation(value = "删除文章", -+ notes = "软删除攻略文章,同时清除文章的标签关联。\n\n**权限**:需管理员登录。") - @DeleteMapping("/{articleId}") - public Result deleteArticle(@PathVariable Long articleId) { - articleService.deleteArticle(articleId); - return Result.success(); - } - -- @ApiOperation("发布/下架") -+ @ApiOperation(value = "发布/下架", notes = "切换文章发布状态。发布后小程序端可见,下架后小程序端不再展示但管理端仍可查看\n\n**关联字典**:\n- wiki_status:文章状态(状态切换)") - @PutMapping("/{articleId}/status") - public Result updateStatus( - @PathVariable Long articleId, -@@ -67,7 +70,7 @@ public class AdminGuideArticleController { - return Result.success(); - } - -- @ApiOperation("设置推荐") -+ @ApiOperation(value = "设置推荐", notes = "设置/取消文章推荐。推荐文章会在小程序首页和推荐列表中优先展示") - @PutMapping("/{articleId}/recommend") - public Result updateRecommend( - @PathVariable Long articleId, -@@ -76,7 +79,7 @@ public class AdminGuideArticleController { - return Result.success(); - } - -- @ApiOperation("设置置顶") -+ @ApiOperation(value = "设置置顶", notes = "设置/取消文章置顶。置顶文章在分类列表中始终排在最前面") - @PutMapping("/{articleId}/top") - public Result updateTop( - @PathVariable Long articleId, -``` - -### `hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideCategoryController.java` (M) - -```diff -diff --git a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideCategoryController.java b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideCategoryController.java -index 8b849da..0eddd64 100644 ---- a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideCategoryController.java -+++ b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideCategoryController.java -@@ -24,19 +24,20 @@ public class AdminGuideCategoryController { - - private final GuideCategoryService categoryService; - -- @ApiOperation("分类列表") -+ @ApiOperation(value = "分类列表", notes = "返回全部攻略分类(含启用和停用),按排序值升序排列\n\n**关联字典**:\n- common_status:通用状态(列表显示,ACTIVE=启用/INACTIVE=停用)") - @GetMapping("/list") - public Result> listCategories() { - return Result.success(categoryService.listCategories()); - } - -- @ApiOperation("启用的分类列表") -+ @ApiOperation(value = "启用的分类列表", notes = "仅返回状态为启用的分类,创建文章时用于选择分类") - @GetMapping("/enabled") - public Result> listEnabledCategories() { - return Result.success(categoryService.listEnabledCategories()); - } - -- @ApiOperation("创建分类") -+ @ApiOperation(value = "创建分类", -+ notes = "创建攻略分类,分类名称不可重复。创建后默认启用,排序值越小越靠前。\n\n**权限**:需管理员登录。") - @PostMapping - public Result createCategory( - @Valid @RequestBody CategoryCreateRequest request, -@@ -45,7 +46,8 @@ public class AdminGuideCategoryController { - return Result.success(categoryService.createCategory(request, adminId)); - } - -- @ApiOperation("更新分类") -+ @ApiOperation(value = "更新分类", -+ notes = "更新攻略分类的名称、图标、描述等信息。\n\n**权限**:需管理员登录。") - @PutMapping("/{categoryId}") - public Result updateCategory( - @PathVariable Long categoryId, -@@ -53,14 +55,14 @@ public class AdminGuideCategoryController { - return Result.success(categoryService.updateCategory(categoryId, request)); - } - -- @ApiOperation("删除分类") -+ @ApiOperation(value = "删除分类", notes = "删除分类前需确保分类下无文章,否则删除失败") - @DeleteMapping("/{categoryId}") - public Result deleteCategory(@PathVariable Long categoryId) { - categoryService.deleteCategory(categoryId); - return Result.success(); - } - -- @ApiOperation("更新分类状态") -+ @ApiOperation(value = "更新分类状态", notes = "启用或停用分类。停用后该分类下的文章不会在小程序端展示,但不影响已有文章\n\n**关联字典**:\n- common_status:通用状态(状态切换,ACTIVE=启用/INACTIVE=停用)") - @PutMapping("/{categoryId}/status") - public Result updateStatus( - @PathVariable Long categoryId, -@@ -69,7 +71,8 @@ public class AdminGuideCategoryController { - return Result.success(); - } - -- @ApiOperation("更新分类排序") -+ @ApiOperation(value = "更新分类排序", -+ notes = "更新分类的排序值,排序值越小越靠前。影响小程序端分类导航的展示顺序。\n\n**权限**:需管理员登录。") - @PutMapping("/{categoryId}/sort") - public Result updateSort( - @PathVariable Long categoryId, -``` - -### `hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideTagController.java` (M) - -```diff -diff --git a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideTagController.java b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideTagController.java -index acd32b1..d747ae4 100644 ---- a/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideTagController.java -+++ b/hl-guide-service/src/main/java/com/hulalv/guide/controller/AdminGuideTagController.java -@@ -23,19 +23,20 @@ public class AdminGuideTagController { - - private final GuideTagService tagService; - -- @ApiOperation("系统标签列表") -+ @ApiOperation(value = "系统标签列表", notes = "返回管理员创建的系统标签(不含用户自定义标签),用于标签管理页") - @GetMapping("/managed") - public Result> listManagedTags() { - return Result.success(tagService.listManagedTags()); - } - -- @ApiOperation("所有标签列表") -+ @ApiOperation(value = "所有标签列表", notes = "返回全部标签(含系统标签和用户自定义标签),用于文章编辑时的标签选择器") - @GetMapping("/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建标签") -+ @ApiOperation(value = "创建标签", -+ notes = "创建攻略系统标签,标签名称不可重复。创建后可用于文章分类和筛选。\n\n**权限**:需管理员登录。") - @PostMapping - public Result createTag( - @Valid @RequestBody TagCreateRequest request, -@@ -44,7 +45,8 @@ public class AdminGuideTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("更新标签") -+ @ApiOperation(value = "更新标签", -+ notes = "更新标签名称。标签名称不可与其他已有标签重复。\n\n**权限**:需管理员登录。") - @PutMapping("/{tagId}") - public Result updateTag( - @PathVariable Long tagId, -@@ -52,14 +54,15 @@ public class AdminGuideTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", -+ notes = "删除标签并自动解除与所有文章的关联关系。\n\n**权限**:需管理员登录。") - @DeleteMapping("/{tagId}") - public Result deleteTag(@PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("更新文章标签") -+ @ApiOperation(value = "更新文章标签", notes = "全量替换文章的标签关联,传入新的标签ID列表(空数组表示清除所有标签)") - @PutMapping("/article/{articleId}") - public Result updateArticleTags( - @PathVariable Long articleId, -``` - -### `hl-guide-service/src/main/java/com/hulalv/guide/controller/InternalWikiController.java` (M) - -```diff -diff --git a/hl-guide-service/src/main/java/com/hulalv/guide/controller/InternalWikiController.java b/hl-guide-service/src/main/java/com/hulalv/guide/controller/InternalWikiController.java -index 42c16dd..62838a6 100644 ---- a/hl-guide-service/src/main/java/com/hulalv/guide/controller/InternalWikiController.java -+++ b/hl-guide-service/src/main/java/com/hulalv/guide/controller/InternalWikiController.java -@@ -16,7 +16,7 @@ import java.util.Map; - /** - * 内部接口 - 供 mp-service Feign 调用 - */ --@Api(tags = "【内部接口】攻略百科(Feign调用)") -+@Api(tags = "【内部接口】攻略百科(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/wiki") - @RequiredArgsConstructor -@@ -25,13 +25,14 @@ public class InternalWikiController { - private final GuideCategoryService categoryService; - private final GuideArticleService articleService; - -- @ApiOperation("查询已启用的攻略分类列表") -+ @ApiOperation(value = "查询已启用的攻略分类列表", -+ notes = "内部服务间调用。返回所有状态为启用的攻略分类,供小程序端展示分类导航。\n\n**关联字典**:\n- common_status:通用状态(仅返回ACTIVE状态的分类)") - @GetMapping("/categories") - public Result> listEnabledCategories() { - return Result.success(categoryService.listEnabledCategories()); - } - -- @ApiOperation("分页查询指定分类下的已发布文章") -+ @ApiOperation(value = "分页查询指定分类下的已发布文章", notes = "**关联字典**:\n- wiki_status:文章状态(返回字段)") - @GetMapping("/category/{categoryId}/articles") - public Result>> listCategoryArticles( - @PathVariable Long categoryId, -@@ -40,13 +41,14 @@ public class InternalWikiController { - return Result.success(articleService.listPublishedArticlesByCategory(categoryId, page, pageSize)); - } - -- @ApiOperation("查询已发布文章详情") -+ @ApiOperation(value = "查询已发布文章详情", notes = "**关联字典**:\n- wiki_status:文章状态(返回字段)") - @GetMapping("/article/{articleId}") - public Result> getArticle(@PathVariable Long articleId) { - return Result.success(articleService.getPublishedArticle(articleId)); - } - -- @ApiOperation("查询推荐文章列表") -+ @ApiOperation(value = "查询推荐文章列表", -+ notes = "内部服务间调用。返回已发布且标记为推荐的文章列表,用于小程序首页推荐位展示。默认返回5条。") - @GetMapping("/recommend-articles") - public Result>> listRecommendArticles( - @RequestParam(defaultValue = "5") Integer limit) { -``` - -### `hl-insurance-service/src/main/java/com/hulalv/insurance/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-insurance-service/src/main/java/com/hulalv/insurance/config/Knife4jConfig.java b/hl-insurance-service/src/main/java/com/hulalv/insurance/config/Knife4jConfig.java -index 3528af0..9b09f25 100644 ---- a/hl-insurance-service/src/main/java/com/hulalv/insurance/config/Knife4jConfig.java -+++ b/hl-insurance-service/src/main/java/com/hulalv/insurance/config/Knife4jConfig.java -@@ -1,9 +1,9 @@ - package com.hulalv.insurance.config; - -+import com.google.common.base.Predicate; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import springfox.documentation.builders.ApiInfoBuilder; --import springfox.documentation.builders.PathSelectors; - import springfox.documentation.builders.RequestHandlerSelectors; - import springfox.documentation.spi.DocumentationType; - import springfox.documentation.spring.web.plugins.Docket; -@@ -11,6 +11,11 @@ import springfox.documentation.spring.web.plugins.Docket; - @Configuration - public class Knife4jConfig { - -+ /** 排除内部接口和回调接口路径 */ -+ private Predicate adminPaths() { -+ return input -> input != null && !input.contains("/internal/") && !input.contains("/callback/"); -+ } -+ - @Bean - public Docket insuranceApi() { - return new Docket(DocumentationType.SWAGGER_2) -@@ -22,7 +27,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.insurance.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - } -``` - -### `hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceController.java` (M) - -```diff -diff --git a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceController.java b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceController.java -index 852da1c..1505c2c 100644 ---- a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceController.java -+++ b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceController.java -@@ -48,7 +48,8 @@ public class AdminInsuranceController { - private final InsuranceEntityProperties entityProperties; - private final PolicyShareService policyShareService; - -- @ApiOperation("保险产品列表") -+ @ApiOperation(value = "保险产品列表", -+ notes = "分页查询已同步的保险产品,支持按是否境外筛选。产品数据来源于保游网同步。\n\n**权限**:需管理员登录。") - @GetMapping("/products") - public Result> listProducts( - @ApiParam("页码") @RequestParam(defaultValue = "1") Integer page, -@@ -57,26 +58,30 @@ public class AdminInsuranceController { - return Result.success(orderService.listProducts(page, pageSize, isOverseas)); - } - -- @ApiOperation("保险产品详情") -+ @ApiOperation(value = "保险产品详情", -+ notes = "返回保险产品完整信息,包含产品名称、保险公司、保障范围、适用地区等。\n\n**权限**:需管理员登录。") - @GetMapping("/products/{id}") - public Result getProduct(@ApiParam("保险产品ID") @PathVariable("id") Long productId) { - return Result.success(orderService.getProductDetail(productId)); - } - -- @ApiOperation("保险产品计划及费率") -+ @ApiOperation(value = "保险产品计划及费率", -+ notes = "返回指定保险产品的所有投保计划及对应费率表,包含不同天数区间的保费价格。投保下单前需选择具体计划。\n\n**权限**:需管理员登录。") - @GetMapping("/products/{id}/plans") - public Result> getProductPlans(@ApiParam("保险产品ID") @PathVariable("id") Long productId) { - return Result.success(orderService.getProductPlans(productId)); - } - -- @ApiOperation("从保游网同步产品数据") -+ @ApiOperation(value = "从保游网同步产品数据", -+ notes = "手动触发从保游网API拉取最新保险产品数据(含计划和费率),同步到本地数据库。返回同步的产品数量。\n\n**权限**:需管理员登录。") - @PostMapping("/sync-products") - public Result syncProducts() { - int count = syncService.syncAll(); - return Result.success(count); - } - -- @ApiOperation("投保公司主体列表") -+ @ApiOperation(value = "投保公司主体列表", -+ notes = "返回系统配置的投保公司主体列表(来自Nacos配置),投保下单时选择以哪个公司主体投保。每个主体包含编码、公司名称和商户ID。\n\n**权限**:需管理员登录。") - @GetMapping("/entities") - public Result>> listEntities() { - List> list = entityProperties.getList().stream().map(e -> { -@@ -91,7 +96,7 @@ public class AdminInsuranceController { - return Result.success(list); - } - -- @ApiOperation("投保下单(每人独立保单)") -+ @ApiOperation(value = "投保下单(每人独立保单)", notes = "**关联字典**:\n- gender:性别(被保人信息)\n- id_card_type:证件类型(被保人信息)") - @PostMapping("/purchase") - public Result> purchase( - @ApiParam("投保请求") @Valid @RequestBody PurchaseInsuranceRequest request, -@@ -100,43 +105,48 @@ public class AdminInsuranceController { - return Result.success(orderService.purchase(request, adminId)); - } - -- @ApiOperation("退保") -+ @ApiOperation(value = "退保", -+ notes = "对单个保险订单发起退保,调用保游网退保API。退保成功后保险状态变为CANCELLED。\n\n**权限**:需管理员登录。\n**注意**:已生效的保单退保可能产生手续费。\n\n**关联字典**:\n- insurance_status:保险状态(状态流转)") - @PostMapping("/cancel/{id}") - public Result cancel(@ApiParam("保险订单ID") @PathVariable("id") Long insuranceOrderId) { - return Result.success(orderService.cancel(insuranceOrderId)); - } - -- @ApiOperation("保险订单列表") -+ @ApiOperation(value = "保险订单列表", notes = "**关联字典**:\n- insurance_status:保险状态(列表筛选+显示)") - @GetMapping("/orders") - public Result> listOrders(@ApiParam("查询条件") InsuranceQueryRequest request) { - return Result.success(orderService.listOrders(request)); - } - -- @ApiOperation("保险订单详情(含被保人)") -+ @ApiOperation(value = "保险订单详情(含被保人)", notes = "**关联字典**:\n- insurance_status:保险状态(显示)\n- gender:性别(被保人信息显示)\n- id_card_type:证件类型(被保人信息显示)") - @GetMapping("/orders/{id}") - public Result getOrderDetail(@ApiParam("保险订单ID") @PathVariable("id") Long insuranceOrderId) { - return Result.success(orderService.getOrderDetail(insuranceOrderId)); - } - -- @ApiOperation("按旅行订单查询保险单") -+ @ApiOperation(value = "按旅行订单查询保险单", -+ notes = "根据旅行订单ID查询关联的所有保险订单列表。在订单详情页展示保险购买情况。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- insurance_status:保险状态(列表显示)") - @GetMapping("/orders/by-order/{orderId}") - public Result> getByOrder(@ApiParam("旅行订单ID") @PathVariable Long orderId) { - return Result.success(orderService.getByOrderId(orderId)); - } - -- @ApiOperation("查询订单保险保障(含被保人详情)") -+ @ApiOperation(value = "查询订单保险保障(含被保人详情)", -+ notes = "返回订单维度的保险保障汇总信息,包含覆盖人数、保障期间、每位被保人的保单明细。用于订单详情页的保险保障展示。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- insurance_status:保险状态(显示)\n- gender:性别(被保人信息显示)\n- id_card_type:证件类型(被保人信息显示)") - @GetMapping("/coverage/{orderId}") - public Result getCoverage(@ApiParam("旅行订单ID") @PathVariable Long orderId) { - return Result.success(orderService.getCoverageByOrderId(orderId)); - } - -- @ApiOperation("保费试算(本地费率)") -+ @ApiOperation(value = "保费试算(本地费率)", -+ notes = "根据保险计划、投保天数和人数,使用本地同步的费率表试算保费。不调用保游网API,用于投保前的费用预估。\n\n**权限**:需管理员登录。") - @PostMapping("/trial-price") - public Result> trialPrice(@ApiParam("试算请求") @Valid @RequestBody TrialPriceRequest request) { - return Result.success(orderService.trialPrice(request)); - } - -- @ApiOperation("查询保游网账户余额") -+ @ApiOperation(value = "查询保游网账户余额", -+ notes = "查询保游网平台的账户余额,用于管理端展示当前可用投保额度。查询失败时返回null(非关键信息,不影响业务)。\n\n**权限**:需管理员登录。") - @GetMapping("/balance") - public Result getBalance() { - try { -@@ -152,13 +162,15 @@ public class AdminInsuranceController { - return Result.success(null); - } - -- @ApiOperation("下载保单PDF(Base64)") -+ @ApiOperation(value = "下载保单PDF(Base64)", -+ notes = "从保游网下载指定保险订单的电子保单PDF,以Base64编码返回。前端可解码后展示或提供下载。\n\n**权限**:需管理员登录。") - @GetMapping("/policy/{id}/download") - public Result downloadPolicy(@ApiParam("保险订单ID") @PathVariable("id") Long insuranceOrderId) { - return Result.success(orderService.downloadPolicy(insuranceOrderId)); - } - -- @ApiOperation("获取保游网充值链接(旧接口,保留兼容)") -+ @ApiOperation(value = "获取保游网充值链接(旧接口,保留兼容)", -+ notes = "返回保游网平台的充值页面URL。此为旧版接口,保留用于向后兼容,推荐使用在线充值接口。\n\n**权限**:需管理员登录。") - @GetMapping("/recharge-url") - public Result getRechargeUrl() { - String url = baoyouProperties.getRechargeUrl(); -@@ -168,13 +180,15 @@ public class AdminInsuranceController { - return Result.success(url); - } - -- @ApiOperation("在线充值(调用保游网支付API)") -+ @ApiOperation(value = "在线充值(调用保游网支付API)", -+ notes = "调用保游网在线充值API,生成充值支付链接。支持选择支付方式(支付宝/微信),充值完成后账户余额自动更新。\n\n**权限**:需管理员登录。") - @PostMapping("/recharge") - public Result> recharge(@ApiParam("充值请求") @Valid @RequestBody RechargeRequest request) { - return Result.success(orderService.recharge(request.getMoney(), request.getPayType(), request.getBackUrl())); - } - -- @ApiOperation("分享保单(合并某出行人所有有效保单PDF,上传OSS返回链接)") -+ @ApiOperation(value = "分享保单(合并某出行人所有有效保单PDF,上传OSS返回链接)", -+ notes = "合并指定出行人的所有有效保单PDF为一个文件,上传至OSS后返回公开访问链接。用于管理端分享保单给出行人。\n\n**权限**:需管理员登录。") - @PostMapping("/share-policy") - public Result sharePolicy( - @ApiParam("分享保单请求") @Valid @RequestBody SharePolicyRequest request) { -``` - -### `hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceSchemeController.java` (M) - -```diff -diff --git a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceSchemeController.java b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceSchemeController.java -index 9497720..04db6d6 100644 ---- a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceSchemeController.java -+++ b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/AdminInsuranceSchemeController.java -@@ -24,26 +24,30 @@ public class AdminInsuranceSchemeController { - - private final InsuranceSchemeService schemeService; - -- @ApiOperation("活跃方案列表(下拉选择用)") -+ @ApiOperation(value = "活跃方案列表(下拉选择用)", -+ notes = "返回所有状态为启用的保险方案模板,用于投保下单时的方案下拉选择。\n\n**权限**:需管理员登录。") - @GetMapping("/list") - public Result> listActiveSchemes() { - return Result.success(schemeService.listActiveSchemes()); - } - -- @ApiOperation("全部方案列表(管理用)") -+ @ApiOperation(value = "全部方案列表(管理用)", -+ notes = "返回所有保险方案模板(含启用和停用),用于方案管理页面展示和编辑。\n\n**权限**:需管理员登录。") - @GetMapping("/list-all") - public Result> listAllSchemes() { - return Result.success(schemeService.listAllSchemes()); - } - -- @ApiOperation("方案详情") -+ @ApiOperation(value = "方案详情", -+ notes = "返回单个保险方案模板的完整信息,包含方案名称、保险产品关联、天数规则、费率配置等。\n\n**权限**:需管理员登录。") - @GetMapping("/{id}") - public Result getSchemeDetail( - @ApiParam("方案ID") @PathVariable("id") Long schemeId) { - return Result.success(schemeService.getSchemeDetail(schemeId)); - } - -- @ApiOperation("创建方案") -+ @ApiOperation(value = "创建方案", -+ notes = "创建保险方案模板,配置关联保险产品、投保天数规则和费率。创建后默认启用。\n\n**权限**:需管理员登录。") - @PostMapping - public Result createScheme( - @ApiParam("方案请求") @Valid @RequestBody InsuranceSchemeRequest request, -@@ -52,7 +56,8 @@ public class AdminInsuranceSchemeController { - return Result.success(schemeService.createScheme(request, adminId)); - } - -- @ApiOperation("更新方案") -+ @ApiOperation(value = "更新方案", -+ notes = "更新保险方案模板的配置信息,包括方案名称、关联产品、天数规则、费率等。\n\n**权限**:需管理员登录。") - @PutMapping("/{id}") - public Result updateScheme( - @ApiParam("方案ID") @PathVariable("id") Long schemeId, -@@ -62,14 +67,16 @@ public class AdminInsuranceSchemeController { - return Result.success(schemeService.updateScheme(schemeId, request, adminId)); - } - -- @ApiOperation("切换方案状态(启用/停用)") -+ @ApiOperation(value = "切换方案状态(启用/停用)", -+ notes = "切换保险方案模板的启用/停用状态。停用后不会出现在投保下单的方案选择列表中。\n\n**权限**:需管理员登录。\n\n**关联字典**:\n- common_status:通用状态(ACTIVE=启用/INACTIVE=停用)") - @PutMapping("/{id}/toggle-status") - public Result toggleStatus( - @ApiParam("方案ID") @PathVariable("id") Long schemeId) { - return Result.success(schemeService.toggleStatus(schemeId)); - } - -- @ApiOperation("删除方案(软删除)") -+ @ApiOperation(value = "删除方案(软删除)", -+ notes = "软删除保险方案模板。已使用该方案创建的保险订单不受影响。\n\n**权限**:需管理员登录。") - @DeleteMapping("/{id}") - public Result deleteScheme( - @ApiParam("方案ID") @PathVariable("id") Long schemeId) { -@@ -77,7 +84,8 @@ public class AdminInsuranceSchemeController { - return Result.success(null); - } - -- @ApiOperation("预览应用方案(解析日期+估算保费)") -+ @ApiOperation(value = "预览应用方案(解析日期+估算保费)", -+ notes = "根据方案模板和行程日期预览投保效果:解析实际投保起止日期、计算每人保费和总保费。用于投保前确认费用。\n\n**权限**:需管理员登录。") - @PostMapping("/preview-apply") - public Result previewApply( - @ApiParam("预览请求") @Valid @RequestBody ApplySchemeRequest request) { -``` - -### `hl-insurance-service/src/main/java/com/hulalv/insurance/controller/InternalInsuranceController.java` (M) - -```diff -diff --git a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/InternalInsuranceController.java b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/InternalInsuranceController.java -index 828cc04..d77d99e 100644 ---- a/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/InternalInsuranceController.java -+++ b/hl-insurance-service/src/main/java/com/hulalv/insurance/controller/InternalInsuranceController.java -@@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "【内部接口】保险(Feign调用)") -+@Api(tags = "【内部接口】保险(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/insurance") - @RequiredArgsConstructor -@@ -26,19 +26,22 @@ public class InternalInsuranceController { - private final InsuranceProductSyncService syncService; - private final PolicyShareService policyShareService; - -- @ApiOperation("按旅行订单查询保险单(内部调用)") -+ @ApiOperation(value = "按旅行订单查询保险单(内部调用)", -+ notes = "内部服务间调用。根据旅行订单ID查询关联的所有保险订单,返回保险状态、保费、保障期间等信息。\n\n**关联字典**:\n- insurance_status:保险状态(返回字段)") - @GetMapping("/by-order/{orderId}") - public Result> getByOrder(@ApiParam("旅行订单ID") @PathVariable Long orderId) { - return Result.success(orderService.getByOrderId(orderId)); - } - -- @ApiOperation("按订单批量查询保险单(内部调用)") -+ @ApiOperation(value = "按订单批量查询保险单(内部调用)", -+ notes = "内部服务间调用。批量查询多个旅行订单的保险订单,返回Map结构(key=订单ID,value=保险单列表),用于订单列表页展示保险状态。") - @PostMapping("/by-orders") - public Result>> getByOrders(@RequestBody List orderIds) { - return Result.success(orderService.getByOrderIds(orderIds)); - } - -- @ApiOperation("检查保险是否全覆盖(内部调用)") -+ @ApiOperation(value = "检查保险是否全覆盖(内部调用)", -+ notes = "内部服务间调用。根据出行人数和行程天数计算所需的人日数,与已投保的有效保单覆盖人日数对比,判断保险是否已全覆盖。") - @GetMapping("/coverage-complete/{orderId}") - public Result isCoverageComplete( - @ApiParam("旅行订单ID") @PathVariable Long orderId, -@@ -57,7 +60,8 @@ public class InternalInsuranceController { - return Result.success(coveredPersonDays >= requiredPersonDays); - } - -- @ApiOperation("按订单批量退保(级联失效调用)") -+ @ApiOperation(value = "按订单批量退保(级联失效调用)", -+ notes = "内部服务间调用。旅行订单取消或退款时级联调用,将该订单下所有有效保险单批量退保(调用保游网退保API),记录退保原因。") - @PostMapping("/invalidate/{orderId}") - public Result invalidateInsurance( - @ApiParam("旅行订单ID") @PathVariable Long orderId, -@@ -66,19 +70,22 @@ public class InternalInsuranceController { - return Result.success(null); - } - -- @ApiOperation("分享保单PDF(内部调用,返回base64)") -+ @ApiOperation(value = "分享保单PDF(内部调用,返回base64)", -+ notes = "内部服务间调用。合并指定出行人的所有有效保单PDF为一个文件,上传至OSS后返回下载链接和Base64内容,用于小程序端分享保单。") - @PostMapping("/share-policy") - public Result sharePolicy(@RequestBody SharePolicyRequest request) { - return Result.success(policyShareService.sharePolicy(request)); - } - -- @ApiOperation("按订单获取所有保单PDF(内部调用,合并所有出行人)") -+ @ApiOperation(value = "按订单获取所有保单PDF(内部调用,合并所有出行人)", -+ notes = "内部服务间调用。将指定订单下所有出行人的有效保单PDF合并为一个文件,上传至OSS后返回下载链接,用于订单维度的保单查看。") - @GetMapping("/share-policy-by-order/{orderId}") - public Result sharePolicyByOrder(@PathVariable Long orderId) { - return Result.success(policyShareService.sharePolicyByOrder(orderId)); - } - -- @ApiOperation("触发保险产品同步(内部调用/定时任务)") -+ @ApiOperation(value = "触发保险产品同步(内部调用/定时任务)", -+ notes = "内部服务间调用。从保游网API拉取最新保险产品数据(含计划和费率),同步到本地数据库。返回同步的产品数量。") - @PostMapping("/sync-products") - public Result syncProducts() { - int count = syncService.syncAll(); -``` - -### `hl-material-service/src/main/java/com/hulalv/material/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/config/Knife4jConfig.java b/hl-material-service/src/main/java/com/hulalv/material/config/Knife4jConfig.java -index 93e40f0..c55eaa0 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/config/Knife4jConfig.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/config/Knife4jConfig.java -@@ -1,9 +1,9 @@ - package com.hulalv.material.config; - -+import com.google.common.base.Predicate; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import springfox.documentation.builders.ApiInfoBuilder; --import springfox.documentation.builders.PathSelectors; - import springfox.documentation.builders.RequestHandlerSelectors; - import springfox.documentation.spi.DocumentationType; - import springfox.documentation.spring.web.plugins.Docket; -@@ -11,6 +11,11 @@ import springfox.documentation.spring.web.plugins.Docket; - @Configuration - public class Knife4jConfig { - -+ /** 排除内部接口和回调接口路径 */ -+ private Predicate adminPaths() { -+ return input -> input != null && !input.contains("/internal/") && !input.contains("/callback/"); -+ } -+ - @Bean - public Docket materialApi() { - return new Docket(DocumentationType.SWAGGER_2) -@@ -22,7 +27,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.material.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/controller/InternalMaterialController.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/controller/InternalMaterialController.java b/hl-material-service/src/main/java/com/hulalv/material/controller/InternalMaterialController.java -index 08122a4..686a577 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/controller/InternalMaterialController.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/controller/InternalMaterialController.java -@@ -22,7 +22,7 @@ import java.util.List; - * Internal endpoints for Feign calls from other services (scenic, hotel, etc.). - * Not exposed through gateway. - */ --@Api(tags = "素材内部接口(Feign调用)") -+@Api(tags = "素材内部接口(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/material") - @RequiredArgsConstructor -@@ -31,7 +31,7 @@ public class InternalMaterialController { - private final MaterialRefService refService; - private final MaterialService materialService; - -- @ApiOperation("绑定引用") -+ @ApiOperation(value = "绑定引用", notes = "将素材与业务实体建立引用关系(如景区ID+封面图),记录引用类型(COVER/GALLERY/DETAIL等)") - @PostMapping("/ref/bind") - public Result bindRef( - @Valid @RequestBody RefBindRequest request, -@@ -40,7 +40,7 @@ public class InternalMaterialController { - return Result.success(); - } - -- @ApiOperation("批量绑定引用") -+ @ApiOperation(value = "批量绑定引用", notes = "批量建立素材与业务实体的引用关系,常用于保存包含多张图片的业务数据") - @PostMapping("/ref/batch-bind") - public Result batchBindRefs( - @Valid @RequestBody RefBatchBindRequest request, -@@ -49,7 +49,7 @@ public class InternalMaterialController { - return Result.success(); - } - -- @ApiOperation("解绑引用") -+ @ApiOperation(value = "解绑引用", notes = "删除单个素材与业务实体的引用关系") - @DeleteMapping("/ref/unbind") - public Result unbindRef(@Valid @RequestBody RefUnbindRequest request) { - refService.unbindRef(request.getMaterialId(), request.getBizType(), -@@ -57,14 +57,15 @@ public class InternalMaterialController { - return Result.success(); - } - -- @ApiOperation("批量解绑引用") -+ @ApiOperation(value = "批量解绑引用", notes = "批量删除素材引用关系,常用于业务实体更新时先清除旧引用再绑定新引用") - @DeleteMapping("/ref/batch-unbind") - public Result batchUnbindRefs(@Valid @RequestBody RefBatchUnbindRequest request) { - refService.batchUnbindRefs(request.getRefs()); - return Result.success(); - } - -- @ApiOperation("批量查询素材信息") -+ @ApiOperation(value = "批量查询素材信息", -+ notes = "内部服务间调用。根据素材ID列表批量查询素材信息,用于其他服务获取素材详情(如产品、景区等关联的素材数据)。") - @PostMapping("/by-ids") - public Result> getMaterialsByIds(@Valid @RequestBody BatchMaterialIdsRequest request) { - return Result.success(materialService.getMaterialsByIds(request.getMaterialIds())); -``` - -### `hl-material-service/src/main/java/com/hulalv/material/controller/MaterialCategoryPermissionController.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialCategoryPermissionController.java b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialCategoryPermissionController.java -index 03566eb..77fa5a6 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialCategoryPermissionController.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialCategoryPermissionController.java -@@ -23,7 +23,7 @@ public class MaterialCategoryPermissionController { - - private final MaterialCategoryPermissionService permissionService; - -- @ApiOperation("获取角色的分类权限") -+ @ApiOperation(value = "获取角色的分类权限", notes = "仅超级管理员可操作。返回指定角色可访问的素材分类编码列表") - @GetMapping("/{roleCode}") - public Result> getPermissions( - @ApiParam("角色编码") @PathVariable String roleCode, -@@ -32,7 +32,7 @@ public class MaterialCategoryPermissionController { - return Result.success(permissionService.getPermissionsByRoleCode(roleCode)); - } - -- @ApiOperation("更新角色的分类权限") -+ @ApiOperation(value = "更新角色的分类权限", notes = "仅超级管理员可操作。全量替换指定角色的素材分类访问权限,传入允许访问的分类编码列表") - @PutMapping("/{roleCode}") - public Result updatePermissions( - @ApiParam("角色编码") @PathVariable String roleCode, -``` - -### `hl-material-service/src/main/java/com/hulalv/material/controller/MaterialController.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialController.java b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialController.java -index 0fa7c7e..d79def9 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialController.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialController.java -@@ -47,7 +47,7 @@ public class MaterialController { - - // ==================== Upload ==================== - -- @ApiOperation("获取上传凭证") -+ @ApiOperation(value = "获取上传凭证", notes = "上传素材第一步:获取OSS预签名URL和凭证。前端使用凭证直传OSS后调用确认上传。支持基于角色的分类权限校验") - @PostMapping("/upload/token") - public Result requestUploadToken( - @ApiParam("上传凭证请求") @Valid @RequestBody MaterialUploadTokenRequest request, -@@ -57,7 +57,7 @@ public class MaterialController { - return Result.success(materialService.requestUploadToken(request, adminId, role)); - } - -- @ApiOperation("确认上传完成") -+ @ApiOperation(value = "确认上传完成", notes = "上传素材第二步:前端直传OSS完成后调用此接口创建素材记录,支持MD5去重\n\n**关联字典**:\n- material_tag:素材标签(上传时可选标签)") - @PostMapping("/upload/confirm") - public Result confirmUpload( - @ApiParam("确认上传请求") @Valid @RequestBody MaterialUploadConfirmRequest request, -@@ -66,7 +66,7 @@ public class MaterialController { - return Result.success(materialService.confirmUpload(request, adminId)); - } - -- @ApiOperation("文件夹上传初始化(创建分类+批量获取凭证)") -+ @ApiOperation(value = "文件夹上传初始化(创建分类+批量获取凭证)", notes = "支持整个文件夹上传:自动根据文件夹名创建子分类,为每个文件批量获取上传凭证,前端逐一上传后批量确认") - @PostMapping("/upload/folder") - public Result folderUploadInit( - @ApiParam("文件夹上传初始化请求") @Valid @RequestBody FolderUploadInitRequest request, -@@ -79,7 +79,8 @@ public class MaterialController { - - // ==================== Chunk Upload (分片上传) ==================== - -- @ApiOperation("分片上传-初始化") -+ @ApiOperation(value = "分片上传-初始化", -+ notes = "大文件上传第一步:初始化分片上传任务,返回uploadId和每个分片的预签名URL。前端按分片并发上传后调用完成合并接口。\n\n**权限**:需管理员登录,受角色分类权限限制。") - @PostMapping("/upload/chunk/init") - public Result chunkUploadInit( - @ApiParam("分片上传初始化请求") @Valid @RequestBody ChunkUploadInitRequest request, -@@ -89,7 +90,8 @@ public class MaterialController { - return Result.success(chunkUploadService.initChunkUpload(request, adminId, role)); - } - -- @ApiOperation("分片上传-上传分片") -+ @ApiOperation(value = "分片上传-上传分片", -+ notes = "大文件上传第二步:逐个上传分片数据,分片索引从0开始。支持断点续传,已上传的分片无需重传。") - @PostMapping("/upload/chunk") - public Result chunkUploadPart( - @ApiParam("上传ID") @RequestParam("uploadId") String uploadId, -@@ -99,7 +101,8 @@ public class MaterialController { - return Result.success(chunkUploadService.uploadChunk(uploadId, chunkIndex, chunk)); - } - -- @ApiOperation("分片上传-完成合并") -+ @ApiOperation(value = "分片上传-完成合并", -+ notes = "大文件上传第三步:所有分片上传完成后调用,OSS端合并分片为完整文件并创建素材记录。") - @PostMapping("/upload/chunk/complete") - public Result chunkUploadComplete( - @ApiParam("分片上传完成请求") @Valid @RequestBody ChunkUploadCompleteRequest request, -@@ -108,7 +111,8 @@ public class MaterialController { - return Result.success(chunkUploadService.completeChunkUpload(request.getUploadId(), adminId)); - } - -- @ApiOperation("分片上传-取消") -+ @ApiOperation(value = "分片上传-取消", -+ notes = "取消分片上传任务,清理已上传的分片数据和OSS临时文件。仅上传发起者可取消。") - @PostMapping("/upload/chunk/cancel") - public Result chunkUploadCancel( - @ApiParam("分片上传取消请求") @Valid @RequestBody ChunkUploadCancelRequest request, -@@ -120,7 +124,7 @@ public class MaterialController { - - // ==================== CRUD ==================== - -- @ApiOperation("素材列表") -+ @ApiOperation(value = "素材列表", notes = "分页查询素材,支持按分类、标签、文件类型、关键词筛选。返回结果受角色分类权限限制\n\n**关联字典**:\n- file_type:文件类型(列表筛选+显示)") - @GetMapping("/list") - public Result> listMaterials( - @ApiParam("素材查询条件") @Valid MaterialQueryRequest query, -@@ -131,7 +135,8 @@ public class MaterialController { - return Result.success(materialService.listMaterials(query, adminId, role, categoryMap)); - } - -- @ApiOperation("素材详情") -+ @ApiOperation(value = "素材详情", -+ notes = "返回素材完整信息,包含文件名、URL、分类、标签、文件大小、上传者等。受角色分类权限限制。\n\n**关联字典**:\n- file_type:文件类型(显示)") - @GetMapping("/{materialId}") - public Result getMaterial( - @ApiParam("素材ID") @PathVariable Long materialId, -@@ -141,7 +146,7 @@ public class MaterialController { - return Result.success(materialService.getMaterial(materialId, role, categoryMap)); - } - -- @ApiOperation("更新素材信息") -+ @ApiOperation(value = "更新素材信息", notes = "**关联字典**:\n- material_tag:素材标签(编辑时选择标签)") - @PutMapping("/{materialId}") - public Result updateMaterial( - @ApiParam("素材ID") @PathVariable Long materialId, -@@ -153,7 +158,7 @@ public class MaterialController { - return Result.success(materialService.updateMaterial(materialId, request, adminId, role, categoryMap)); - } - -- @ApiOperation("删除素材") -+ @ApiOperation(value = "删除素材", notes = "删除素材记录。如果素材存在引用关系(被景区、酒店等使用),则不允许删除") - @DeleteMapping("/{materialId}") - public Result deleteMaterial( - @ApiParam("素材ID") @PathVariable Long materialId, -@@ -164,7 +169,7 @@ public class MaterialController { - return Result.success(); - } - -- @ApiOperation("批量删除素材") -+ @ApiOperation(value = "批量删除素材", notes = "批量删除素材,返回删除结果(成功数/失败数/失败原因)。有引用关系的素材会跳过并记录失败原因") - @DeleteMapping("/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -@@ -179,7 +184,7 @@ public class MaterialController { - - // ==================== Tags on Materials ==================== - -- @ApiOperation("更新素材标签") -+ @ApiOperation(value = "更新素材标签", notes = "全量替换单个素材的标签,传入新的标签ID列表") - @PutMapping("/{materialId}/tags") - public Result updateMaterialTags( - @ApiParam("素材ID") @PathVariable Long materialId, -@@ -192,7 +197,7 @@ public class MaterialController { - return Result.success(); - } - -- @ApiOperation("批量更新标签") -+ @ApiOperation(value = "批量更新标签", notes = "对多个素材同时添加和/或移除标签,支持增量操作(addTagIds新增,removeTagIds移除)") - @PutMapping("/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签更新请求") @Valid @RequestBody BatchTagRequest request, -@@ -212,7 +217,7 @@ public class MaterialController { - - // ==================== References ==================== - -- @ApiOperation("查看素材引用记录") -+ @ApiOperation(value = "查看素材引用记录", notes = "查看素材被哪些业务实体引用(如景区封面、酒店轮播图等),用于判断素材是否可安全删除") - @GetMapping("/{materialId}/refs") - public Result> getMaterialRefs(@ApiParam("素材ID") @PathVariable Long materialId) { - return Result.success(refService.getRefsByMaterialId(materialId)); -@@ -220,7 +225,7 @@ public class MaterialController { - - // ==================== Categories ==================== - -- @ApiOperation("获取有权限的分类列表(含素材数量)") -+ @ApiOperation(value = "获取有权限的分类列表(含素材数量)", notes = "返回当前角色有权限查看的素材分类树,每个分类包含素材数量统计。超级管理员可见全部分类") - @GetMapping("/categories") - public Result> getCategories(HttpServletRequest httpRequest) { - String role = getRole(httpRequest); -@@ -230,7 +235,7 @@ public class MaterialController { - - // ==================== Sub-categories ==================== - -- @ApiOperation("创建子分类") -+ @ApiOperation(value = "创建子分类", notes = "在一级分类下创建子分类,分类编码自动生成。子分类用于更细粒度的素材归档") - @PostMapping("/category/sub") - public Result createSubCategory( - @ApiParam("子分类创建请求") @Valid @RequestBody SubCategoryCreateRequest request, -@@ -241,7 +246,8 @@ public class MaterialController { - return Result.success(categoryService.createSubCategory(request, adminId, role, categoryMap)); - } - -- @ApiOperation("更新子分类") -+ @ApiOperation(value = "更新子分类", -+ notes = "更新子分类的名称或排序值。仅有该分类权限的管理员可操作。") - @PutMapping("/category/sub/{categoryId}") - public Result updateSubCategory( - @ApiParam("子分类ID") @PathVariable Long categoryId, -@@ -252,7 +258,7 @@ public class MaterialController { - return Result.success(categoryService.updateSubCategory(categoryId, request, adminId, role)); - } - -- @ApiOperation("删除子分类") -+ @ApiOperation(value = "删除子分类", notes = "删除子分类前需确保分类下无素材,否则删除失败") - @DeleteMapping("/category/sub/{categoryId}") - public Result deleteSubCategory( - @ApiParam("子分类ID") @PathVariable Long categoryId, -``` - -### `hl-material-service/src/main/java/com/hulalv/material/controller/MaterialTagController.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialTagController.java b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialTagController.java -index a90884f..31d53b5 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialTagController.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/controller/MaterialTagController.java -@@ -23,19 +23,22 @@ public class MaterialTagController { - - private final MaterialTagService tagService; - -- @ApiOperation("获取管理标签(标签管理用)") -+ @ApiOperation(value = "获取管理标签(标签管理用)", -+ notes = "返回管理员创建的系统标签列表(不含用户自定义标签),用于标签管理页的CRUD操作。") - @GetMapping("/tags") - public Result> listManagedTags() { - return Result.success(tagService.listManagedTags()); - } - -- @ApiOperation("获取全部标签(选择器用,含自定义标签)") -+ @ApiOperation(value = "获取全部标签(选择器用,含自定义标签)", -+ notes = "返回所有标签(含系统标签和用户自定义标签),用于素材上传/编辑时的标签选择器。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建管理标签") -+ @ApiOperation(value = "创建管理标签", -+ notes = "创建系统级素材标签,标签名称不可重复。创建后可用于素材分类和筛选。\n\n**权限**:需管理员登录。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("创建标签请求") @Valid @RequestBody TagCreateRequest request, -@@ -44,7 +47,8 @@ public class MaterialTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签(按名称查找或创建)") -+ @ApiOperation(value = "解析自定义标签(按名称查找或创建)", -+ notes = "按标签名称查找已有标签,不存在则自动创建为用户自定义标签。用于素材上传时输入自由标签文本的场景。\n\n**权限**:需管理员登录。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("自定义标签请求") @RequestBody TagCreateRequest request, -@@ -53,7 +57,8 @@ public class MaterialTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("编辑标签") -+ @ApiOperation(value = "编辑标签", -+ notes = "更新标签名称。标签名称不可与其他已有标签重复。\n\n**权限**:需管理员登录。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -61,7 +66,8 @@ public class MaterialTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", -+ notes = "删除标签并自动解除与所有素材的关联关系。\n\n**权限**:需管理员登录。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); -``` - -### `hl-material-service/src/main/java/com/hulalv/material/controller/MpMaterialController.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/controller/MpMaterialController.java b/hl-material-service/src/main/java/com/hulalv/material/controller/MpMaterialController.java -index a595577..17f64ac 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/controller/MpMaterialController.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/controller/MpMaterialController.java -@@ -20,7 +20,7 @@ public class MpMaterialController { - - private final MaterialService materialService; - -- @ApiOperation("获取小程序分类下的全部素材") -+ @ApiOperation(value = "获取小程序分类下的全部素材", notes = "返回miniprogram分类下的所有素材,用于小程序端展示公共素材资源(如引导页图片、默认头像等)") - @GetMapping("/miniprogram") - public Result> listMiniprogramMaterials() { - return Result.success(materialService.listMaterialsByCategoryCode("miniprogram")); -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCancelRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCancelRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCancelRequest.java -index 7adbe0a..93a06f8 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCancelRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCancelRequest.java -@@ -1,9 +1,13 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("分片上传取消请求") - public class ChunkUploadCancelRequest { - -+ @ApiModelProperty("上传ID") - private String uploadId; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCompleteRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCompleteRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCompleteRequest.java -index 712c15c..d876fcc 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCompleteRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadCompleteRequest.java -@@ -1,9 +1,13 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("分片上传完成请求") - public class ChunkUploadCompleteRequest { - -+ @ApiModelProperty("上传ID") - private String uploadId; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadInitRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadInitRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadInitRequest.java -index 2d94f04..939a630 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadInitRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/ChunkUploadInitRequest.java -@@ -1,13 +1,25 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("分片上传初始化请求") - public class ChunkUploadInitRequest { - -+ @ApiModelProperty("文件名") - private String filename; -+ -+ @ApiModelProperty("文件大小(字节)") - private Long fileSize; -+ -+ @ApiModelProperty("文件MIME类型") - private String contentType; -+ -+ @ApiModelProperty("分组标识") - private String groupKey; -+ -+ @ApiModelProperty("文件哈希值") - private String fileHash; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileBatchIdsRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileBatchIdsRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileBatchIdsRequest.java -index 96c2499..449c3b4 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileBatchIdsRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileBatchIdsRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -9,7 +11,9 @@ import java.util.List; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("文件批量ID请求") - public class FileBatchIdsRequest { - -+ @ApiModelProperty("文件ID列表") - private List fileIds; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadConfirmRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadConfirmRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadConfirmRequest.java -index bb85acc..1b1d316 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadConfirmRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadConfirmRequest.java -@@ -1,9 +1,13 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("文件上传确认请求") - public class FileUploadConfirmRequest { - -+ @ApiModelProperty("文件ID") - private String fileId; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadTokenRequest.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadTokenRequest.java b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadTokenRequest.java -index 4d7a140..ee7cd4e 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadTokenRequest.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/dto/FileUploadTokenRequest.java -@@ -1,13 +1,25 @@ - package com.hulalv.material.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("文件上传令牌请求") - public class FileUploadTokenRequest { - -+ @ApiModelProperty("文件名") - private String fileName; -+ -+ @ApiModelProperty("文件大小(字节)") - private Long fileSize; -+ -+ @ApiModelProperty("文件哈希值") - private String fileHash; -+ -+ @ApiModelProperty("分组标识") - private String groupKey; -+ -+ @ApiModelProperty("是否强制使用预签名URL") - private boolean forcePresigned; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadInitVO.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadInitVO.java b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadInitVO.java -index 6cd60b6..9f38bc4 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadInitVO.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadInitVO.java -@@ -1,12 +1,22 @@ - package com.hulalv.material.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("分片上传初始化结果") - public class ChunkUploadInitVO { - -+ @ApiModelProperty("上传ID") - private String uploadId; -+ -+ @ApiModelProperty("分片大小(字节)") - private int chunkSize; -+ -+ @ApiModelProperty("文件ID") - private String fileId; -+ -+ @ApiModelProperty("OSS对象Key") - private String ossKey; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadPartVO.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadPartVO.java b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadPartVO.java -index 1628687..cc0df47 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadPartVO.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/ChunkUploadPartVO.java -@@ -1,9 +1,13 @@ - package com.hulalv.material.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("分片上传片段结果") - public class ChunkUploadPartVO { - -+ @ApiModelProperty("分片ETag标识") - private String etag; - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileUploadTokenVO.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileUploadTokenVO.java b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileUploadTokenVO.java -index 779f74d..07b2068 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileUploadTokenVO.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileUploadTokenVO.java -@@ -1,28 +1,58 @@ - package com.hulalv.material.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - import java.time.LocalDateTime; - - @Data -+@ApiModel("文件上传令牌结果") - public class FileUploadTokenVO { - -+ @ApiModelProperty("文件ID") - private String fileId; -+ -+ @ApiModelProperty("文件MIME类型") - private String contentType; -+ -+ @ApiModelProperty("上传模式") - private String uploadMode; -+ -+ @ApiModelProperty("预签名上传URL") - private String presignedUrl; -+ -+ @ApiModelProperty("OSS对象Key") - private String ossKey; -+ -+ @ApiModelProperty("过期时间") - private LocalDateTime expireAt; -+ -+ @ApiModelProperty("STS临时凭证") - private StsTokenInfo stsToken; -+ -+ @ApiModelProperty("OSS存储桶名称") - private String bucket; -+ -+ @ApiModelProperty("OSS区域") - private String region; -+ -+ @ApiModelProperty("文件信息(秒传时返回)") - private FileVO file; - - @Data -+ @ApiModel("STS临时凭证信息") - public static class StsTokenInfo { -+ @ApiModelProperty("访问密钥ID") - private String accessKeyId; -+ -+ @ApiModelProperty("访问密钥Secret") - private String accessKeySecret; -+ -+ @ApiModelProperty("安全令牌") - private String securityToken; -+ -+ @ApiModelProperty("过期时间") - private String expiration; - } - } -``` - -### `hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileVO.java` (M) - -```diff -diff --git a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileVO.java b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileVO.java -index a5e43b9..90612e6 100644 ---- a/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileVO.java -+++ b/hl-material-service/src/main/java/com/hulalv/material/feign/vo/FileVO.java -@@ -1,23 +1,51 @@ - package com.hulalv.material.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - import java.time.LocalDateTime; - - @Data -+@ApiModel("文件信息VO") - public class FileVO { - -+ @ApiModelProperty("文件ID") - private String fileId; -+ -+ @ApiModelProperty("文件名") - private String fileName; -+ -+ @ApiModelProperty("文件类型") - private String fileType; -+ -+ @ApiModelProperty("MIME类型") - private String mimeType; -+ -+ @ApiModelProperty("文件大小(字节)") - private Long fileSize; -+ -+ @ApiModelProperty("文件哈希值") - private String fileHash; -+ -+ @ApiModelProperty("OSS访问URL") - private String ossUrl; -+ -+ @ApiModelProperty("缩略图URL") - private String thumbnailUrl; -+ -+ @ApiModelProperty("预览URL") - private String previewUrl; -+ -+ @ApiModelProperty("分组标识") - private String groupKey; -+ -+ @ApiModelProperty("文件状态") - private String status; -+ -+ @ApiModelProperty("引用次数") - private Integer refCount; -+ -+ @ApiModelProperty("创建时间") - private LocalDateTime createdAt; - } -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/config/Knife4jConfig.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/config/Knife4jConfig.java -index 23786d4..4e0d06b 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/config/Knife4jConfig.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/config/Knife4jConfig.java -@@ -19,7 +19,8 @@ public class Knife4jConfig { - .apiInfo(apiInfo()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.monitor.controller")) -- .paths(PathSelectors.any()) -+ .paths(PathSelectors.ant("/internal/**").negate() -+ .and(PathSelectors.ant("/callback/**").negate())) - .build(); - } - -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ApprovalLogController.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ApprovalLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ApprovalLogController.java -index 6c26fc1..04d1ebd 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ApprovalLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ApprovalLogController.java -@@ -19,7 +19,7 @@ public class ApprovalLogController { - - private final ApprovalLogService approvalLogService; - -- @ApiOperation("审批日志分页查询") -+ @ApiOperation(value = "审批日志分页查询", notes = "查询企微OA审批流程记录,支持按审批状态(1-审批中/2-已通过/3-已驳回/4-已撤销)、申请人、模板名称筛选\n\n**关联字典**:\n- approval_sp_status:审批状态(列表筛选+显示)") - @GetMapping - public Result> list( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -32,7 +32,7 @@ public class ApprovalLogController { - return Result.success(approvalLogService.queryPage(page, pageSize, spStatus, applyUserName, spName, startTime, endTime)); - } - -- @ApiOperation("审批日志详情") -+ @ApiOperation(value = "审批日志详情", notes = "**关联字典**:\n- approval_sp_status:审批状态(显示)") - @GetMapping("/{id}") - public Result detail(@ApiParam("日志ID") @PathVariable Long id) { - ApprovalLog approvalLog = approvalLogService.getById(id); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/DataRetentionController.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/DataRetentionController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/DataRetentionController.java -index 43d56d8..12117da 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/DataRetentionController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/DataRetentionController.java -@@ -19,7 +19,7 @@ public class DataRetentionController { - - private final DataRetentionService dataRetentionService; - -- @ApiOperation("手动触发数据清理") -+ @ApiOperation(value = "手动触发数据清理", notes = "仅超级管理员可操作。按数据保留策略清理过期日志(操作日志/错误日志/通知日志等),返回各类型清理的记录数") - @PostMapping("/cleanup") - public Result> cleanup(HttpServletRequest request) { - requireSuperAdmin(request); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ErrorLogController.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ErrorLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ErrorLogController.java -index 77046be..06bbdf5 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ErrorLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ErrorLogController.java -@@ -19,7 +19,7 @@ public class ErrorLogController { - - private final ErrorLogService errorLogService; - -- @ApiOperation("错误日志分页查询") -+ @ApiOperation(value = "错误日志分页查询", notes = "查询各微服务的异常记录,支持按服务名称、异常类名、时间范围筛选。堆栈信息仅保留com.hulalv包内的调用帧") - @GetMapping - public Result> list( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -31,7 +31,8 @@ public class ErrorLogController { - return Result.success(errorLogService.queryPage(page, pageSize, serviceName, exceptionClass, startTime, endTime)); - } - -- @ApiOperation("错误日志详情") -+ @ApiOperation(value = "错误日志详情", -+ notes = "返回单条错误日志的完整信息,包含异常类名、错误消息、过滤后的堆栈信息(仅com.hulalv包内调用帧)、请求URL、请求参数等。") - @GetMapping("/{id}") - public Result detail(@ApiParam("日志ID") @PathVariable Long id) { - ErrorLog errorLog = errorLogService.getById(id); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/InternalLogController.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/InternalLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/InternalLogController.java -index 51e3999..44d463e 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/InternalLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/InternalLogController.java -@@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.*; - * Internal endpoints for receiving logs from other services. - * NOT exposed via gateway. - */ --@Api(tags = "【内部接口】日志接收(Feign调用)") -+@Api(tags = "【内部接口】日志接收(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/monitor") - @RequiredArgsConstructor -@@ -29,35 +29,35 @@ public class InternalLogController { - private final NotificationLogService notificationLogService; - private final ApprovalLogService approvalLogService; - -- @ApiOperation("Receive operation log") -+ @ApiOperation(value = "接收操作日志", notes = "各微服务通过AOP拦截@OperationLog注解的方法,异步发送操作日志到此接口存储") - @PostMapping("/operation-log") -- public Result receiveOperationLog(@RequestBody OperationLogDTO dto) { -+ public Result receiveOperationLog(@RequestBody OperationLogDTO dto) { - operationLogService.saveFromDTO(dto); - return Result.success(); - } - -- @ApiOperation("Receive error log") -+ @ApiOperation(value = "接收错误日志", notes = "各微服务的GlobalExceptionHandler捕获异常后,异步发送错误日志到此接口存储") - @PostMapping("/error-log") -- public Result receiveErrorLog(@RequestBody ErrorLogDTO dto) { -+ public Result receiveErrorLog(@RequestBody ErrorLogDTO dto) { - errorLogService.saveFromDTO(dto); - return Result.success(); - } - -- @ApiOperation("Receive notification log") -+ @ApiOperation(value = "接收通知日志", notes = "通知服务发送消息(短信/站内信/企微等)后,记录发送结果到此接口") - @PostMapping("/notification-log") -- public Result receiveNotificationLog(@RequestBody NotificationLogDTO dto) { -+ public Result receiveNotificationLog(@RequestBody NotificationLogDTO dto) { - notificationLogService.saveFromDTO(dto); - return Result.success(); - } - -- @ApiOperation("Receive approval log") -+ @ApiOperation(value = "接收审批日志", notes = "企微回调服务接收审批事件后,发送审批日志到此接口。同一审批单号会更新已有记录(按thirdNo去重)") - @PostMapping("/approval-log") -- public Result receiveApprovalLog(@RequestBody ApprovalLogDTO dto) { -+ public Result receiveApprovalLog(@RequestBody ApprovalLogDTO dto) { - approvalLogService.saveOrUpdateByThirdNo(dto); - return Result.success(); - } - -- @ApiOperation("Get customer stats for a user (add/loss counts)") -+ @ApiOperation(value = "获取用户客户统计", notes = "统计指定用户的客户增减数据(新增客户数/流失客户数),用于客户管理看板") - @GetMapping("/notification-log/customer-stats") - public Result> getCustomerStats( - @RequestParam("userId") String userId) { -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/LoginLogController.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/LoginLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/LoginLogController.java -index 52c9e86..bc58580 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/LoginLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/LoginLogController.java -@@ -19,7 +19,7 @@ public class LoginLogController { - - private final UserServiceClient userServiceClient; - -- @ApiOperation("登录日志分页查询") -+ @ApiOperation(value = "登录日志分页查询", notes = "查询管理员登录记录(代理到user-service),包含登录IP、设备信息、登录方式和登录结果\n\n**关联字典**:\n- login_status:登录状态(列表筛选+显示)") - @GetMapping - public Result list( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/MysqlMonitorController.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/MysqlMonitorController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/MysqlMonitorController.java -index 029e317..0d29b88 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/MysqlMonitorController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/MysqlMonitorController.java -@@ -21,20 +21,20 @@ public class MysqlMonitorController { - - private final MysqlMonitorService mysqlMonitorService; - -- @ApiOperation("MySQL实时监控数据") -+ @ApiOperation(value = "MySQL实时监控数据", notes = "返回MySQL实时状态:连接数、QPS、缓冲池命中率、线程状态、慢查询计数等核心指标") - @GetMapping - public Result> overview() { - return Result.success(mysqlMonitorService.getOverview()); - } - -- @ApiOperation("表空间列表") -+ @ApiOperation(value = "表空间列表", notes = "查询各数据库表的空间占用情况,包含数据大小、索引大小、行数等信息。可指定schema筛选,仅允许查询hl_前缀的数据库") - @GetMapping("/tables") - public Result>> tables( - @ApiParam("数据库名") @RequestParam(required = false) String schema) { - return Result.success(mysqlMonitorService.getTableSpaces(schema)); - } - -- @ApiOperation("慢SQL查询统计") -+ @ApiOperation(value = "慢SQL查询统计", notes = "仅超级管理员可操作。查询慢SQL统计信息,返回执行时间最长的SQL语句及其执行次数、平均耗时等") - @GetMapping("/slow-queries") - public Result>> slowQueries( - HttpServletRequest request, -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/NotificationLogController.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/NotificationLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/NotificationLogController.java -index 7e55cae..46d7b72 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/NotificationLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/NotificationLogController.java -@@ -19,7 +19,7 @@ public class NotificationLogController { - - private final NotificationLogService notificationLogService; - -- @ApiOperation("消息通知日志分页查询") -+ @ApiOperation(value = "消息通知日志分页查询", notes = "查询各渠道(短信/站内信/企微/公众号)的通知发送记录,支持按通知类型、用户、发送状态筛选\n\n**关联字典**:\n- notification_send_status:发送状态(列表筛选+显示,0=待发送/1=成功/2=失败)") - @GetMapping - public Result> list( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -32,7 +32,8 @@ public class NotificationLogController { - return Result.success(notificationLogService.queryPage(page, pageSize, notificationType, userName, sendStatus, startTime, endTime)); - } - -- @ApiOperation("消息通知日志详情") -+ @ApiOperation(value = "消息通知日志详情", -+ notes = "返回单条通知发送日志的完整信息,包含通知类型、接收用户、发送渠道、发送状态、失败原因(如有)、消息内容等。") - @GetMapping("/{id}") - public Result detail(@ApiParam("日志ID") @PathVariable Long id) { - NotificationLog notificationLog = notificationLogService.getById(id); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/OperationLogController.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/OperationLogController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/OperationLogController.java -index 43516e4..f620a50 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/OperationLogController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/OperationLogController.java -@@ -19,7 +19,7 @@ public class OperationLogController { - - private final OperationLogService operationLogService; - -- @ApiOperation("操作日志分页查询") -+ @ApiOperation(value = "操作日志分页查询", notes = "查询管理员的操作记录,支持按模块、管理员、状态、时间范围筛选。记录包含请求参数、响应结果和耗时信息\n\n**关联字典**:\n- operation_log_status:操作状态(列表筛选+显示,0=成功/1=失败)") - @GetMapping - public Result> list( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -32,7 +32,8 @@ public class OperationLogController { - return Result.success(operationLogService.queryPage(page, pageSize, module, adminId, status, startTime, endTime)); - } - -- @ApiOperation("操作日志详情") -+ @ApiOperation(value = "操作日志详情", -+ notes = "返回单条操作日志的完整信息,包含操作模块、操作描述、请求参数、响应结果、操作耗时、操作人信息、IP地址等。") - @GetMapping("/{id}") - public Result detail(@ApiParam("日志ID") @PathVariable Long id) { - OperationLog log = operationLogService.getById(id); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RedisMonitorController.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RedisMonitorController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RedisMonitorController.java -index e70ae11..ffc059f 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RedisMonitorController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RedisMonitorController.java -@@ -17,7 +17,7 @@ public class RedisMonitorController { - - private final RedisMonitorService redisMonitorService; - -- @ApiOperation("Redis实时监控数据") -+ @ApiOperation(value = "Redis实时监控数据", notes = "返回Redis实时状态:内存使用量、连接数、Key数量、命中率、每秒命令数等核心指标") - @GetMapping - public Result> overview() { - return Result.success(redisMonitorService.getOverview()); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RocketMqMonitorController.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RocketMqMonitorController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RocketMqMonitorController.java -index 5d642cb..9f32297 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RocketMqMonitorController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/RocketMqMonitorController.java -@@ -18,19 +18,19 @@ public class RocketMqMonitorController { - - private final RocketMqMonitorService rocketMqMonitorService; - -- @ApiOperation("RocketMQ概览") -+ @ApiOperation(value = "RocketMQ概览", notes = "返回RocketMQ集群状态:Broker状态、Topic数量、消息积压量、生产者/消费者连接数等核心指标") - @GetMapping - public Result> overview() { - return Result.success(rocketMqMonitorService.getOverview()); - } - -- @ApiOperation("Topic统计") -+ @ApiOperation(value = "Topic统计", notes = "返回各Topic的消息量、最新偏移量和消费进度等信息") - @GetMapping("/topics") - public Result>> topicStats() { - return Result.success(rocketMqMonitorService.getTopicStats()); - } - -- @ApiOperation("消费者组统计") -+ @ApiOperation(value = "消费者组统计", notes = "返回各消费者组的消费进度、积压量和在线消费者实例信息") - @GetMapping("/consumer-groups") - public Result>> consumerGroupStats() { - return Result.success(rocketMqMonitorService.getConsumerGroupStats()); -``` - -### `hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ServiceMonitorController.java` (M) - -```diff -diff --git a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ServiceMonitorController.java b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ServiceMonitorController.java -index 63d09ef..11e5509 100644 ---- a/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ServiceMonitorController.java -+++ b/hl-monitor-service/src/main/java/com/hulalv/monitor/controller/ServiceMonitorController.java -@@ -18,7 +18,7 @@ public class ServiceMonitorController { - - private final ServiceMonitorService serviceMonitorService; - -- @ApiOperation("微服务列表和健康状态") -+ @ApiOperation(value = "微服务列表和健康状态", notes = "从Nacos注册中心获取所有微服务的实例列表和健康状态,包含IP、端口、注册时间和健康检查结果") - @GetMapping - public Result>> list() { - return Result.success(serviceMonitorService.getServiceList()); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpActivityController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpActivityController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpActivityController.java -index f7f787c..da96036 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpActivityController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpActivityController.java -@@ -22,7 +22,8 @@ public class MpActivityController { - private final MpResourceFeignClient resourceFeignClient; - private final ResourceMapService resourceMapService; - -- @ApiOperation("活动列表") -+ @ApiOperation(value = "活动列表", -+ notes = "分页查询已上架的活动列表,支持关键词和分类筛选。聚合层透传resource-service的活动数据给小程序前端。") - @GetMapping("/list") - public Result>> listActivities( - @ApiParam("关键词") @RequestParam(required = false) String keyword, -@@ -37,7 +38,8 @@ public class MpActivityController { - return resourceFeignClient.listActivities(query); - } - -- @ApiOperation("活动详情") -+ @ApiOperation(value = "活动详情", -+ notes = "获取活动完整信息(含图文详情、价格等),自动注入静态地图图片URL用于详情页地图展示。") - @GetMapping("/{activityId}") - public Result> getActivityDetail(@ApiParam("活动ID") @PathVariable Long activityId) { - Result> result = resourceFeignClient.getActivityDetail(activityId); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBadgeController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBadgeController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBadgeController.java -index 9023792..61ad359 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBadgeController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBadgeController.java -@@ -18,7 +18,7 @@ public class MpBadgeController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("获取徽章数据") -+ @ApiOperation(value = "获取徽章数据", notes = "返回用户的徽章统计(未读消息数、待办事项数等),用于「我的」页面角标展示") - @GetMapping - public Result> getBadges(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBannerController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBannerController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBannerController.java -index 6089f32..df4d3dd 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBannerController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpBannerController.java -@@ -23,7 +23,8 @@ public class MpBannerController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("获取当前生效的轮播图列表") -+ @ApiOperation(value = "获取当前生效的轮播图列表", -+ notes = "返回当前处于有效期内的轮播图,按排序值排列。用于小程序首页顶部轮播展示,透传自user-service。") - @GetMapping("/active") - public Result>> listActiveBanners() { - return userFeignClient.listActiveBanners(); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpConfigController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpConfigController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpConfigController.java -index be29a79..84ec777 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpConfigController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpConfigController.java -@@ -22,13 +22,15 @@ public class MpConfigController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("获取所有非敏感前端配置") -+ @ApiOperation(value = "获取所有非敏感前端配置", -+ notes = "返回所有非SECRET类型的前端配置项(如主题色、客服电话、版本号等)。不含敏感配置,可安全传输给小程序端。") - @GetMapping - public Result>> listPublicConfigs() { - return userFeignClient.listAllFrontendConfigs(); - } - -- @ApiOperation("按分组获取非敏感前端配置") -+ @ApiOperation(value = "按分组获取非敏感前端配置", -+ notes = "按配置分组获取前端配置项,如UI分组、功能开关分组等。用于小程序按需加载特定分组的配置。") - @GetMapping("/group/{group}") - public Result>> listPublicConfigsByGroup( - @ApiParam("配置分组") @PathVariable String group) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpContractController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpContractController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpContractController.java -index 4e34f66..c5b60cb 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpContractController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpContractController.java -@@ -20,7 +20,7 @@ public class MpContractController { - - private final MpContractFeignClient contractFeignClient; - -- @ApiOperation("合同列表") -+ @ApiOperation(value = "合同列表", notes = "**关联字典(BFF透传)**:\n- contract_status:合同状态(列表筛选+显示)") - @GetMapping("/list") - public Result>> listContracts( - HttpServletRequest request, -@@ -31,7 +31,7 @@ public class MpContractController { - return contractFeignClient.listContracts(userId, status, page, pageSize); - } - -- @ApiOperation(value = "合同详情", notes = "返回合同基本信息、签署状态、出行人签署详情及合同文件下载链接") -+ @ApiOperation(value = "合同详情", notes = "返回合同基本信息、签署状态、出行人签署详情及合同文件下载链接\n\n**关联字典(BFF透传)**:\n- contract_status:合同状态(显示)") - @GetMapping("/{id}") - public Result> getContractDetail( - HttpServletRequest request, -@@ -40,7 +40,7 @@ public class MpContractController { - return contractFeignClient.getContractDetail(id, userId); - } - -- @ApiOperation(value = "按订单查合同", notes = "返回订单关联的最新有效合同(非作废)") -+ @ApiOperation(value = "按订单查合同", notes = "返回订单关联的最新有效合同(非作废)\n\n**关联字典(BFF透传)**:\n- contract_status:合同状态(显示)") - @GetMapping("/by-order/{orderId}") - public Result> getContractByOrder( - HttpServletRequest request, -@@ -49,7 +49,7 @@ public class MpContractController { - return contractFeignClient.getContractByOrder(orderId, userId); - } - -- @ApiOperation(value = "按订单查所有合同", notes = "返回订单关联的所有有效合同(TOUR+INSURANCE各一条)") -+ @ApiOperation(value = "按订单查所有合同", notes = "返回订单关联的所有有效合同(TOUR+INSURANCE各一条)\n\n**关联字典(BFF透传)**:\n- contract_status:合同状态(显示)") - @GetMapping("/by-order/{orderId}/all") - public Result>> getContractsByOrder( - HttpServletRequest request, -@@ -58,7 +58,8 @@ public class MpContractController { - return contractFeignClient.getContractsByOrder(orderId, userId); - } - -- @ApiOperation("重新发送合同签署短信") -+ @ApiOperation(value = "重新发送合同签署短信", -+ notes = "重新向出行人发送合同签署短信通知,适用于出行人未收到短信或短信过期的场景。\n\n**权限**:需登录。") - @PostMapping("/{contractId}/resend-sms") - public Result resendContractSms( - @ApiParam("合同ID") @PathVariable Long contractId, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDesignerController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDesignerController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDesignerController.java -index ae62fb8..01d0115 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDesignerController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDesignerController.java -@@ -22,7 +22,8 @@ public class MpDesignerController { - private final MpUserFeignClient userFeignClient; - private final DesignerAggregationService designerAggregationService; - -- @ApiOperation("定制师列表(含真实产品数和评分,综合排序)") -+ @ApiOperation(value = "定制师列表(含真实产品数和评分,综合排序)", -+ notes = "获取定制师列表,聚合层会补充每个定制师的真实产品数量和评价评分。按综合排序(评分>路线数>咨询人数),用于小程序定制师推荐页。") - @SuppressWarnings("unchecked") - @GetMapping - public Result>> listDesigners( -@@ -37,7 +38,8 @@ public class MpDesignerController { - return result; - } - -- @ApiOperation("推荐定制师(综合排序第一名)") -+ @ApiOperation(value = "推荐定制师(综合排序第一名)", -+ notes = "获取综合排序排名第一的定制师信息(含产品数和评分),用于首页推荐定制师卡片展示。") - @GetMapping("/featured") - public Result> getFeaturedDesigner() { - // Fetch all designers, enrich and sort, return top one -@@ -74,7 +76,8 @@ public class MpDesignerController { - try { return Integer.parseInt(obj.toString()); } catch (NumberFormatException e) { return 0; } - } - -- @ApiOperation("定制师详情(含产品数量和评分)") -+ @ApiOperation(value = "定制师详情(含产品数量和评分)", -+ notes = "获取定制师完整个人信息,聚合层会补充该定制师的已发布产品数量和综合评分,用于定制师个人主页展示。") - @GetMapping("/{id}") - public Result> getDesignerDetail(@ApiParam("定制师ID") @PathVariable Long id) { - Map data = designerAggregationService.getDesignerDetailWithStats(id); -@@ -84,7 +87,7 @@ public class MpDesignerController { - return Result.success(data); - } - -- @ApiOperation("定制师已发布产品列表") -+ @ApiOperation(value = "定制师已发布产品列表", notes = "**关联字典(BFF透传)**:\n- product_type:产品类型(显示)") - @GetMapping("/{id}/products") - public Result>> getDesignerProducts( - @ApiParam("定制师ID") @PathVariable Long id, -@@ -93,7 +96,7 @@ public class MpDesignerController { - return designerAggregationService.getDesignerProducts(id, page, pageSize); - } - -- @ApiOperation("定制师产品评价列表") -+ @ApiOperation(value = "定制师产品评价列表", notes = "**关联字典(BFF透传)**:\n- rating_level:评价等级(显示)") - @GetMapping("/{id}/reviews") - public Result>> getDesignerReviews( - @ApiParam("定制师ID") @PathVariable Long id, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDictController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDictController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDictController.java -index b57cfd7..e689361 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDictController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpDictController.java -@@ -23,7 +23,7 @@ public class MpDictController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("获取所有字典数据") -+ @ApiOperation(value = "获取所有字典数据", notes = "获取系统全部字典数据(按字典类型分组),用于小程序端的下拉选项、枚举映射等。建议前端缓存此数据") - @GetMapping("/all") - public Result>> getAllDict() { - return userFeignClient.getAllDict(); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpExploreController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpExploreController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpExploreController.java -index ba1fcaa..5aa4cfc 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpExploreController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpExploreController.java -@@ -9,6 +9,7 @@ import lombok.RequiredArgsConstructor; - import org.springframework.web.bind.annotation.*; - - import javax.servlet.http.HttpServletRequest; -+import java.util.Map; - - @Api(tags = "C端 - 探索接口") - @RestController -@@ -18,9 +19,10 @@ public class MpExploreController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("探索列表") -+ @ApiOperation(value = "探索列表", -+ notes = "获取已启用的探索分类列表(图文攻略内容),支持综合/最新/最热排序,分页返回。用于小程序探索频道首页瀑布流展示。") - @GetMapping("/list") -- public Result list( -+ public Result> list( - @ApiParam("排序方式:comprehensive/newest/hottest") @RequestParam(defaultValue = "comprehensive") String sortType, - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, - @ApiParam("每页条数") @RequestParam(defaultValue = "20") int pageSize) { -@@ -29,7 +31,7 @@ public class MpExploreController { - - @ApiOperation(value = "探索详情", notes = "自动增加浏览量,已登录时返回点赞/收藏状态") - @GetMapping("/{id}") -- public Result detail(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { -+ public Result> detail(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { - // optional auth: userId may be null if not logged in - Long userId = null; - String userIdHeader = request.getHeader("X-User-Id"); -@@ -42,22 +44,25 @@ public class MpExploreController { - return userFeignClient.getExploreCategoryDetail(id, userId); - } - -- @ApiOperation("浏览+1") -+ @ApiOperation(value = "浏览+1", -+ notes = "增加探索内容的浏览计数。前端进入探索详情页时调用,无需登录。") - @PostMapping("/{id}/view") -- public Result view(@ApiParam("探索分类ID") @PathVariable Long id) { -+ public Result view(@ApiParam("探索分类ID") @PathVariable Long id) { - return userFeignClient.incrementExploreViewCount(id); - } - -- @ApiOperation("切换点赞") -+ @ApiOperation(value = "切换点赞", -+ notes = "对探索内容点赞/取消点赞,返回当前点赞状态(true=已点赞)。\n\n**权限**:需登录。") - @PostMapping("/{id}/like") -- public Result toggleLike(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { -+ public Result toggleLike(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.toggleExploreLike(id, userId); - } - -- @ApiOperation("切换收藏") -+ @ApiOperation(value = "切换收藏", -+ notes = "对探索内容收藏/取消收藏,返回当前收藏状态(true=已收藏)。收藏后可在'我的收藏'中查看。\n\n**权限**:需登录。") - @PostMapping("/{id}/favorite") -- public Result toggleFavorite(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { -+ public Result toggleFavorite(@ApiParam("探索分类ID") @PathVariable Long id, HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.toggleExploreFavorite(id, userId); - } -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFavoriteController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFavoriteController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFavoriteController.java -index 94c53e4..d596692 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFavoriteController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFavoriteController.java -@@ -27,7 +27,7 @@ public class MpFavoriteController { - private final MpUserFeignClient userFeignClient; - private final FavoriteAggregationService favoriteAggregationService; - -- @ApiOperation("添加收藏") -+ @ApiOperation(value = "添加收藏", notes = "将产品/景区/餐厅/活动加入收藏。同一目标重复收藏会返回已有收藏记录") - @PostMapping - public Result> addFavorite(HttpServletRequest request, - @Valid @RequestBody MpFavoriteRequest body) { -@@ -38,7 +38,8 @@ public class MpFavoriteController { - return userFeignClient.addFavorite(userId, map); - } - -- @ApiOperation("收藏列表(含资源摘要)") -+ @ApiOperation(value = "收藏列表(含资源摘要)", -+ notes = "分页查询收藏列表,聚合层会补充每个收藏项对应资源的摘要信息(名称、封面图、价格等)。支持按目标类型筛选。\n\n**权限**:需登录。\n\n**关联字典**:\n- favorite_resource_type:收藏资源类型(PRODUCT/SCENIC/RESTAURANT/ACTIVITY)") - @GetMapping - public Result> listFavorites(HttpServletRequest request, - @ApiParam("目标类型筛选(字典:favorite_resource_type):PRODUCT/SCENIC/RESTAURANT/ACTIVITY") -@@ -49,7 +50,8 @@ public class MpFavoriteController { - return Result.success(favoriteAggregationService.listFavorites(userId, targetType, page, pageSize)); - } - -- @ApiOperation("检查是否已收藏") -+ @ApiOperation(value = "检查是否已收藏", -+ notes = "检查当前用户是否已收藏指定资源,用于详情页收藏按钮状态显示。\n\n**权限**:需登录。") - @GetMapping("/check") - public Result checkFavorite(HttpServletRequest request, - @ApiParam("目标类型(字典:favorite_resource_type)") @RequestParam String targetType, -@@ -58,7 +60,8 @@ public class MpFavoriteController { - return userFeignClient.checkFavorite(userId, targetType, targetId); - } - -- @ApiOperation("批量删除收藏") -+ @ApiOperation(value = "批量删除收藏", -+ notes = "批量删除多条收藏记录,传入收藏记录ID列表。用于收藏管理页面的批量操作。\n\n**权限**:需登录,仅能删除自己的收藏。") - @DeleteMapping("/batch") - public Result batchDeleteFavorites(HttpServletRequest request, - @ApiParam("收藏ID列表") @RequestBody List ids) { -@@ -66,7 +69,8 @@ public class MpFavoriteController { - return userFeignClient.batchDeleteFavorites(userId, ids); - } - -- @ApiOperation("按目标取消收藏") -+ @ApiOperation(value = "按目标取消收藏", -+ notes = "通过目标类型+目标ID取消收藏,适用于详情页点击取消收藏的场景(不需要知道收藏记录ID)。\n\n**权限**:需登录。") - @DeleteMapping("/by-target") - public Result deleteFavoriteByTarget(HttpServletRequest request, - @ApiParam("目标类型") @RequestParam String targetType, -@@ -75,7 +79,8 @@ public class MpFavoriteController { - return userFeignClient.deleteFavoriteByTarget(userId, targetType, targetId); - } - -- @ApiOperation("取消收藏") -+ @ApiOperation(value = "取消收藏", -+ notes = "通过收藏记录ID取消收藏,适用于收藏列表页的删除操作。\n\n**权限**:需登录,仅能删除自己的收藏。") - @DeleteMapping("/{id}") - public Result deleteFavorite(HttpServletRequest request, - @ApiParam("收藏记录ID") @PathVariable Long id) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFootprintController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFootprintController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFootprintController.java -index c25ed9b..ab02f01 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFootprintController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpFootprintController.java -@@ -26,7 +26,7 @@ public class MpFootprintController { - private final MpUserFeignClient userFeignClient; - private final FootprintAggregationService footprintAggregationService; - -- @ApiOperation("记录足迹") -+ @ApiOperation(value = "记录足迹", notes = "记录用户浏览资源的足迹,同一资源重复浏览会更新浏览时间而非新增记录") - @PostMapping - public Result> addFootprint(HttpServletRequest request, - @RequestBody MpFootprintAddRequest body) { -@@ -37,7 +37,8 @@ public class MpFootprintController { - return userFeignClient.addFootprint(userId, map); - } - -- @ApiOperation("足迹列表(含资源摘要)") -+ @ApiOperation(value = "足迹列表(含资源摘要)", -+ notes = "分页查询浏览足迹列表,聚合层会补充每条足迹对应资源的摘要信息(名称、封面图等)。支持按资源类型筛选,按浏览时间倒序。\n\n**权限**:需登录。") - @GetMapping - public Result> listFootprints(HttpServletRequest request, - @ApiParam("资源类型筛选:PRODUCT/SCENIC/RESTAURANT/ACTIVITY") @RequestParam(required = false) String resourceType, -@@ -47,14 +48,16 @@ public class MpFootprintController { - return Result.success(footprintAggregationService.listFootprints(userId, resourceType, page, pageSize)); - } - -- @ApiOperation("删除足迹") -+ @ApiOperation(value = "删除足迹", -+ notes = "删除单条浏览足迹记录。\n\n**权限**:需登录,仅能删除自己的足迹。") - @DeleteMapping("/{id}") - public Result deleteFootprint(HttpServletRequest request, @ApiParam("足迹ID") @PathVariable Long id) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.deleteFootprint(userId, id); - } - -- @ApiOperation("批量删除足迹") -+ @ApiOperation(value = "批量删除足迹", -+ notes = "批量删除多条浏览足迹记录,传入足迹ID列表。用于足迹管理页面的批量清理。\n\n**权限**:需登录,仅能删除自己的足迹。") - @DeleteMapping("/batch") - public Result batchDeleteFootprints(HttpServletRequest request, - @ApiParam("足迹ID列表") @RequestBody List ids) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHomeController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHomeController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHomeController.java -index 8e7cdc5..0c6487f 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHomeController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHomeController.java -@@ -18,7 +18,7 @@ public class MpHomeController { - - private final HomeAggregationService homeAggregationService; - -- @ApiOperation(value = "首页数据", notes = "聚合流程:并行获取推荐产品列表+产品线列表+轮播图 → Redis缓存5分钟 → 返回聚合数据") -+ @ApiOperation(value = "首页数据", notes = "聚合流程:并行获取推荐产品列表+产品线列表+轮播图 → Redis缓存5分钟 → 返回聚合数据\n\n**关联字典(BFF透传)**:\n- product_type:产品类型(产品卡片显示)\n- product_status:产品状态(透传自product-service)") - @GetMapping - public Result getHomeData() { - return Result.success(homeAggregationService.getHomeData()); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHotelController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHotelController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHotelController.java -index d820bba..2d649e1 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHotelController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpHotelController.java -@@ -22,7 +22,8 @@ public class MpHotelController { - private final MpResourceFeignClient resourceFeignClient; - private final ResourceMapService resourceMapService; - -- @ApiOperation("酒店列表") -+ @ApiOperation(value = "酒店列表", -+ notes = "分页查询已上架的酒店列表,支持按关键词、城市、星级筛选。聚合层透传resource-service的酒店数据。") - @GetMapping("/list") - public Result>> listHotels( - @ApiParam("关键词") @RequestParam(required = false) String keyword, -@@ -39,7 +40,8 @@ public class MpHotelController { - return resourceFeignClient.listHotels(query); - } - -- @ApiOperation("酒店详情") -+ @ApiOperation(value = "酒店详情", -+ notes = "获取酒店完整信息(含房型列表、图文详情、价格等),自动注入静态地图图片URL用于详情页地图展示。") - @GetMapping("/{hotelId}") - public Result> getHotelDetail(@ApiParam("酒店ID") @PathVariable Long hotelId) { - Result> result = resourceFeignClient.getHotelDetail(hotelId); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInsuranceController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInsuranceController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInsuranceController.java -index 3941bc4..d1403a0 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInsuranceController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInsuranceController.java -@@ -18,7 +18,7 @@ public class MpInsuranceController { - - private final MpInsuranceFeignClient insuranceFeignClient; - -- @ApiOperation(value = "获取订单所有保单PDF", notes = "合并所有出行人的有效保单为一个PDF,返回base64") -+ @ApiOperation(value = "获取订单所有保单PDF", notes = "合并所有出行人的有效保单为一个PDF,返回base64\n\n**关联字典(BFF透传)**:\n- insurance_status:保险状态(返回字段)") - @GetMapping("/policy-pdf/{orderId}") - public Result> getPolicyPdf( - @ApiParam("订单ID") @PathVariable Long orderId) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInvoiceController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInvoiceController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInvoiceController.java -index bda90ad..a42a662 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInvoiceController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpInvoiceController.java -@@ -31,7 +31,7 @@ public class MpInvoiceController { - return orderFeignClient.applyInvoice(userId, body); - } - -- @ApiOperation("发票详情") -+ @ApiOperation(value = "发票详情", notes = "获取发票的完整信息,包含开票状态、发票抬头、税号、金额、电子发票文件链接等") - @GetMapping("/{id}") - public Result> getInvoiceDetail(@ApiParam("发票ID") @PathVariable Long id, - HttpServletRequest request) { -@@ -39,7 +39,7 @@ public class MpInvoiceController { - return orderFeignClient.getInvoiceDetail(id, userId); - } - -- @ApiOperation("通过订单ID查询发票") -+ @ApiOperation(value = "通过订单ID查询发票", notes = "查询指定订单的发票信息,如果订单未开票则返回null") - @GetMapping("/order/{orderId}") - public Result> getInvoiceByOrderId(@ApiParam("订单ID") @PathVariable Long orderId, - HttpServletRequest request) { -@@ -47,7 +47,7 @@ public class MpInvoiceController { - return orderFeignClient.getInvoiceByOrderId(orderId, userId); - } - -- @ApiOperation("发票换开") -+ @ApiOperation(value = "发票换开", notes = "对已开发票申请换开(修改抬头/税号等),原发票作废后重新开具新发票") - @PostMapping("/{invoiceId}/reissue") - public Result> reissueInvoice( - @ApiParam("发票ID") @PathVariable Long invoiceId, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpLikeController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpLikeController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpLikeController.java -index d60be9e..c8d50b5 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpLikeController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpLikeController.java -@@ -57,7 +57,8 @@ public class MpLikeController { - return result; - } - -- @ApiOperation("检查是否已点赞") -+ @ApiOperation(value = "检查是否已点赞", -+ notes = "检查当前用户是否已对指定目标点赞,用于前端点赞按钮状态展示。\n\n**权限**:需登录。") - @GetMapping("/{targetType}/{targetId}/check") - public Result checkLike( - @ApiParam("目标类型") @PathVariable String targetType, -@@ -67,7 +68,8 @@ public class MpLikeController { - return userFeignClient.checkLikeStatus(targetType.toUpperCase(), targetId, userId); - } - -- @ApiOperation("批量检查点赞状态") -+ @ApiOperation(value = "批量检查点赞状态", -+ notes = "批量检查当前用户是否已对多个目标点赞,返回已点赞的目标ID列表。用于列表页批量展示点赞状态。\n\n**权限**:需登录。") - @PostMapping("/{targetType}/batch-check") - public Result> batchCheckLiked( - @ApiParam("目标类型") @PathVariable String targetType, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpOrderController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpOrderController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpOrderController.java -index bc4abe0..e1f7fa6 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpOrderController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpOrderController.java -@@ -37,7 +37,7 @@ public class MpOrderController { - return orderFeignClient.createOrder(userId, body); - } - -- @ApiOperation("订单列表") -+ @ApiOperation(value = "订单列表", notes = "分页查询当前用户的订单列表,支持按状态筛选。返回订单摘要信息(不含详细出行人信息)\n\n**关联字典(BFF透传)**:\n- order_status:订单状态(列表筛选+显示)\n- product_type:产品类型(订单卡片显示)") - @GetMapping("/list") - public Result> listOrders(HttpServletRequest request, - @ApiParam("状态") @RequestParam(required = false) String status, -@@ -51,7 +51,7 @@ public class MpOrderController { - return orderFeignClient.listOrders(userId, query); - } - -- @ApiOperation("订单详情") -+ @ApiOperation(value = "订单详情", notes = "获取订单完整信息,包含产品快照、出行人列表、支付信息、合同状态等\n\n**关联字典(BFF透传)**:\n- order_status:订单状态(显示)\n- product_type:产品类型(显示)\n- contract_status:合同状态(显示)") - @GetMapping("/{orderId}") - public Result getOrder(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId) { -@@ -86,9 +86,10 @@ public class MpOrderController { - return orderFeignClient.cancelOrder(userId, orderId, body != null ? body : new MpCancelOrderRequest()); - } - -- @ApiOperation("通过联系人手机号+姓名查找订单(无需登录)") -+ @ApiOperation(value = "通过联系人手机号+姓名查找订单(无需登录)", -+ notes = "无需登录即可查询。用于管理员代下单场景:管理员创建订单后,用户通过联系人手机号+姓名查找订单并绑定到自己账号。仅返回尚未绑定用户(userId=NULL)的订单。") - @GetMapping("/lookup") -- public Result lookupByContact(@ApiParam("联系人手机号") @RequestParam String contactPhone, -+ public Result>> lookupByContact(@ApiParam("联系人手机号") @RequestParam String contactPhone, - @ApiParam("联系人姓名") @RequestParam String contactName) { - return orderFeignClient.lookupByContact(contactPhone, contactName); - } -@@ -101,7 +102,7 @@ public class MpOrderController { - return orderFeignClient.bindByContact(userId, body); - } - -- @ApiOperation("同意解锁订单") -+ @ApiOperation(value = "同意解锁订单", notes = "用户同意管理员的修改请求,解除订单锁定状态,允许管理员继续修改订单") - @PostMapping("/{orderId}/approve-unlock") - public Result approveUnlock(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId) { -@@ -116,7 +117,7 @@ public class MpOrderController { - return orderFeignClient.getUpcomingDepartures(userId); - } - -- @ApiOperation("各状态订单数量") -+ @ApiOperation(value = "各状态订单数量", notes = "统计当前用户各状态的订单数量,用于「我的」页面的订单状态角标展示\n\n**关联字典(BFF透传)**:\n- order_status:订单状态(状态分类统计)") - @GetMapping("/count") - public Result> countByStatus(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpPaymentController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpPaymentController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpPaymentController.java -index 6ddf62a..274102d 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpPaymentController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpPaymentController.java -@@ -21,7 +21,7 @@ public class MpPaymentController { - private final MpPaymentFeignClient paymentFeignClient; - - @PostMapping("/prepay") -- @ApiOperation(value = "发起支付", notes = "支付流程:选择支付方式(JSAPI/H5) → 调用微信支付API → 返回支付参数 → 前端调起微信支付") -+ @ApiOperation(value = "发起支付", notes = "支付流程:选择支付方式(JSAPI/H5) → 调用微信支付API → 返回支付参数 → 前端调起微信支付\n\n**关联字典(BFF透传)**:\n- payment_status:支付状态(返回字段)") - public Result> prepay( - HttpServletRequest httpRequest, - @ApiParam("支付请求体") @RequestBody MpPaymentPrepayRequest request) { -@@ -30,7 +30,7 @@ public class MpPaymentController { - } - - @GetMapping("/status/{orderId}") -- @ApiOperation("查询支付状态") -+ @ApiOperation(value = "查询支付状态", notes = "**关联字典(BFF透传)**:\n- payment_status:支付状态(显示)") - public Result> getStatus(@ApiParam("订单ID") @PathVariable Long orderId, - HttpServletRequest httpRequest) { - Long userId = (Long) httpRequest.getAttribute("userId"); -@@ -38,8 +38,8 @@ public class MpPaymentController { - } - - @GetMapping("/transactions/{orderId}") -- @ApiOperation("订单交易记录列表") -- public Result listTransactions(@ApiParam("订单ID") @PathVariable Long orderId, -+ @ApiOperation(value = "订单交易记录列表", notes = "**关联字典(BFF透传)**:\n- payment_status:支付状态(显示)") -+ public Result>> listTransactions(@ApiParam("订单ID") @PathVariable Long orderId, - HttpServletRequest httpRequest) { - Long userId = (Long) httpRequest.getAttribute("userId"); - return paymentFeignClient.listTransactions(userId, orderId); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpProductController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpProductController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpProductController.java -index 6aa9542..1aa236f 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpProductController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpProductController.java -@@ -34,7 +34,7 @@ public class MpProductController { - private final MpOrderFeignClient orderFeignClient; - private final ProductAggregationService productAggregationService; - -- @ApiOperation("产品列表") -+ @ApiOperation(value = "产品列表", notes = "分页查询已上架产品,支持按关键词、产品类型(CORE/ROUTE/CUSTOM/GROUP)、季节、天数、目的地、产品线筛选和排序\n\n**关联字典(BFF透传)**:\n- product_type:产品类型(列表筛选+显示)\n- product_status:产品状态(透传自product-service)") - @GetMapping("/list") - public Result>> listProducts( - @ApiParam("搜索关键词") @RequestParam(required = false) String keyword, -@@ -63,7 +63,7 @@ public class MpProductController { - return productFeignClient.listProducts(query); - } - -- @ApiOperation(value = "产品详情(聚合收藏状态)", notes = "聚合流程:获取产品详情 → 并行查询收藏状态 → 异步记录足迹 → 返回聚合数据。支持未登录访问(不返回收藏状态)") -+ @ApiOperation(value = "产品详情(聚合收藏状态)", notes = "聚合流程:获取产品详情 → 并行查询收藏状态 → 异步记录足迹 → 返回聚合数据。支持未登录访问(不返回收藏状态)\n\n**关联字典(BFF透传)**:\n- product_type:产品类型(显示)\n- product_status:产品状态(透传自product-service)") - @GetMapping("/{productId}") - public Result getProduct(HttpServletRequest request, - @ApiParam("产品ID") @PathVariable Long productId) { -@@ -256,7 +256,7 @@ public class MpProductController { - } - } - -- @ApiOperation("产品线列表") -+ @ApiOperation(value = "产品线列表", notes = "返回所有已启用的产品线,用于小程序首页或筛选栏展示") - @GetMapping("/lines") - public Result>> listLines() { - return productFeignClient.listActiveLines(); -@@ -284,7 +284,7 @@ public class MpProductController { - return productFeignClient.listBatchCombos(batchId); - } - -- @ApiOperation("价格日历") -+ @ApiOperation(value = "价格日历", notes = "返回产品指定日期范围内的每日价格,用于日历组件展示。不传日期时默认返回未来一个月") - @GetMapping("/{productId}/price-calendar") - public Result>> getPriceCalendar( - @ApiParam("产品ID") @PathVariable Long productId, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRefundController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRefundController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRefundController.java -index 5a72099..71890d6 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRefundController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRefundController.java -@@ -32,7 +32,7 @@ public class MpRefundController { - return orderFeignClient.refundPreview(userId, orderId); - } - -- @ApiOperation("退款原因列表") -+ @ApiOperation(value = "退款原因列表", notes = "返回系统预设的退款原因选项,用于退款申请页面的原因选择") - @GetMapping("/refund-reasons") - public Result> listRefundReasons() { - return orderFeignClient.listRefundReasons(); -@@ -48,7 +48,7 @@ public class MpRefundController { - return orderFeignClient.applyRefund(userId, userName, orderId, body); - } - -- @ApiOperation("退款申请详情") -+ @ApiOperation(value = "退款申请详情", notes = "获取退款申请的完整信息,包含审核状态、退款金额、退款进度和操作记录\n\n**关联字典(BFF透传)**:\n- order_status:订单状态(显示)\n- payment_status:支付/退款状态(显示)") - @GetMapping("/refund/{applicationId}") - public Result getRefundDetail(@ApiParam("退款申请ID") @PathVariable Long applicationId, - HttpServletRequest request) { -@@ -56,7 +56,7 @@ public class MpRefundController { - return orderFeignClient.getRefundDetail(userId, applicationId); - } - -- @ApiOperation("根据订单ID获取最新退款详情") -+ @ApiOperation(value = "根据订单ID获取最新退款详情", notes = "查询订单关联的最新一条退款申请详情,无退款记录时返回null\n\n**关联字典(BFF透传)**:\n- order_status:订单状态(显示)\n- payment_status:支付/退款状态(显示)") - @GetMapping("/{orderId}/refund-detail") - public Result getRefundDetailByOrder(@ApiParam("订单ID") @PathVariable String orderId, - HttpServletRequest request) { -@@ -84,7 +84,7 @@ public class MpRefundController { - return orderFeignClient.refundAppeal(userId, applicationId, body); - } - -- @ApiOperation("撤回退款申请") -+ @ApiOperation(value = "撤回退款申请", notes = "仅PENDING状态的退款申请可撤回,撤回后订单恢复到原状态") - @PostMapping("/refund/{applicationId}/cancel") - public Result cancelRefund(@ApiParam("退款申请ID") @PathVariable Long applicationId, - HttpServletRequest request) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRestaurantController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRestaurantController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRestaurantController.java -index 4b75e9b..38fa21b 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRestaurantController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpRestaurantController.java -@@ -22,7 +22,8 @@ public class MpRestaurantController { - private final MpResourceFeignClient resourceFeignClient; - private final ResourceMapService resourceMapService; - -- @ApiOperation("餐厅列表") -+ @ApiOperation(value = "餐厅列表", -+ notes = "分页查询已上架的餐厅列表,支持按关键词和城市筛选。聚合层透传resource-service的餐厅数据。") - @GetMapping("/list") - public Result>> listRestaurants( - @ApiParam("关键词") @RequestParam(required = false) String keyword, -@@ -37,7 +38,8 @@ public class MpRestaurantController { - return resourceFeignClient.listRestaurants(query); - } - -- @ApiOperation("餐厅详情") -+ @ApiOperation(value = "餐厅详情", -+ notes = "获取餐厅完整信息(含菜品、图文详情等),自动注入静态地图图片URL用于详情页地图展示。") - @GetMapping("/{restaurantId}") - public Result> getRestaurantDetail(@ApiParam("餐厅ID") @PathVariable Long restaurantId) { - Result> result = resourceFeignClient.getRestaurantDetail(restaurantId); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpReviewController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpReviewController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpReviewController.java -index 1f44df4..1cf55b2 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpReviewController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpReviewController.java -@@ -55,7 +55,7 @@ public class MpReviewController { - return Result.success(categories); - } - -- @ApiOperation(value = "创建评价", notes = "评价流程:订单完成后 → 查询可评价目标列表 → 对每个目标(酒店/景区/活动等)提交评价 → 自动内容审核 → 审核通过后公开展示") -+ @ApiOperation(value = "创建评价", notes = "评价流程:订单完成后 → 查询可评价目标列表 → 对每个目标(酒店/景区/活动等)提交评价 → 自动内容审核 → 审核通过后公开展示\n\n**关联字典(BFF透传)**:\n- review_status:评价审核状态(返回字段)\n- rating_level:评价等级(返回字段)") - @PostMapping("/create") - public Result> createReview(@ApiParam("评价请求体") @RequestBody MpReviewCreateRequest body, - HttpServletRequest request) { -@@ -65,7 +65,7 @@ public class MpReviewController { - return reviewFeignClient.createReview(body, userId); - } - -- @ApiOperation("我的评价列表") -+ @ApiOperation(value = "我的评价列表", notes = "**关联字典(BFF透传)**:\n- review_status:评价审核状态(显示)\n- rating_level:评价等级(显示)") - @GetMapping("/my") - public Result>> getMyReviews( - @ApiParam("页码") @RequestParam(defaultValue = "1") Integer page, -@@ -75,7 +75,7 @@ public class MpReviewController { - return reviewFeignClient.getMyReviews(page, pageSize, userId); - } - -- @ApiOperation(value = "关键词搜索评价(公开)", notes = "按关键词搜索已通过的评价内容,支持按目标类型和目标ID筛选") -+ @ApiOperation(value = "关键词搜索评价(公开)", notes = "按关键词搜索已通过的评价内容,支持按目标类型和目标ID筛选\n\n**关联字典(BFF透传)**:\n- rating_level:评价等级(显示)") - @GetMapping("/search") - public Result>> searchReviews( - @ApiParam(value = "搜索关键词", required = true) @RequestParam String keyword, -@@ -86,7 +86,7 @@ public class MpReviewController { - return reviewFeignClient.searchReviews(keyword, targetType, targetId, page, pageSize); - } - -- @ApiOperation("某目标的已通过评价(公开)") -+ @ApiOperation(value = "某目标的已通过评价(公开)", notes = "**关联字典(BFF透传)**:\n- rating_level:评价等级(筛选+显示)") - @GetMapping("/target") - public Result>> getTargetReviews( - @ApiParam("目标类型") @RequestParam String targetType, -@@ -102,7 +102,7 @@ public class MpReviewController { - return reviewFeignClient.getTargetReviews(targetType, targetId, ratingLevel, hasImage, hasVideo, page, pageSize); - } - -- @ApiOperation(value = "按产品ID查看评价列表", notes = "返回评价列表+统计数据,支持好中差评/有图/有视频筛选") -+ @ApiOperation(value = "按产品ID查看评价列表", notes = "返回评价列表+统计数据,支持好中差评/有图/有视频筛选\n\n**关联字典(BFF透传)**:\n- rating_level:评价等级(筛选+显示)") - @GetMapping("/product/{productId}") - public Result> getProductReviews( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -144,7 +144,8 @@ public class MpReviewController { - return reviewFeignClient.getProductHighlights(productId); - } - -- @ApiOperation("评价统计(平均分、数量)") -+ @ApiOperation(value = "评价统计(平均分、数量)", -+ notes = "获取指定目标的评价统计数据(平均评分、总评价数等),用于详情页评价区域展示。产品showReview关闭时返回空统计。") - @GetMapping("/stats") - public Result> getTargetStats( - @ApiParam("目标类型") @RequestParam String targetType, -@@ -174,21 +175,23 @@ public class MpReviewController { - return true; // 查询失败时默认显示 - } - -- @ApiOperation(value = "精选评价列表(公开)", notes = "无需登录,返回精选评价数组,用于评价浏览页") -+ @ApiOperation(value = "精选评价列表(公开)", notes = "无需登录,返回精选评价数组,用于评价浏览页\n\n**关联字典(BFF透传)**:\n- rating_level:评价等级(显示)") - @GetMapping("/featured") - public Result>> getFeaturedReviews( - @ApiParam("数量限制") @RequestParam(defaultValue = "50") Integer limit) { - return reviewFeignClient.getFeaturedReviews(limit); - } - -- @ApiOperation("检查订单是否已评价") -+ @ApiOperation(value = "检查订单是否已评价", -+ notes = "检查指定订单是否已提交评价,用于订单详情页决定是否显示'去评价'按钮。") - @GetMapping("/order/{orderId}/reviewed") - public Result isOrderReviewed( - @ApiParam("订单ID") @PathVariable Long orderId) { - return reviewFeignClient.isOrderReviewed(orderId); - } - -- @ApiOperation("订单可评价目标列表") -+ @ApiOperation(value = "订单可评价目标列表", -+ notes = "返回订单中可评价的资源目标列表(景区/酒店/活动等),用于评价页面展示可评价项。已评价的目标不会重复出现。\n\n**权限**:需登录。") - @GetMapping("/order/{orderId}/reviewable-targets") - public Result>> getReviewableTargets( - @ApiParam("订单ID") @PathVariable Long orderId, HttpServletRequest request) { -@@ -196,7 +199,8 @@ public class MpReviewController { - return reviewFeignClient.getReviewableTargets(orderId, userId); - } - -- @ApiOperation("点赞/取消点赞评价") -+ @ApiOperation(value = "点赞/取消点赞评价", -+ notes = "对评价进行点赞或取消点赞操作,返回当前点赞状态和点赞总数。\n\n**权限**:需登录。") - @PostMapping("/{reviewId}/like") - public Result> toggleLike( - @ApiParam("评价ID") @PathVariable Long reviewId, HttpServletRequest request) { -@@ -204,7 +208,8 @@ public class MpReviewController { - return reviewFeignClient.toggleLike(reviewId, userId); - } - -- @ApiOperation("检查是否已点赞") -+ @ApiOperation(value = "检查是否已点赞", -+ notes = "检查当前用户是否已点赞指定评价,用于评价列表/详情的点赞按钮状态展示。\n\n**权限**:需登录。") - @GetMapping("/{reviewId}/like/check") - public Result checkLiked( - @ApiParam("评价ID") @PathVariable Long reviewId, HttpServletRequest request) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpScenicController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpScenicController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpScenicController.java -index 96a4529..8f59647 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpScenicController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpScenicController.java -@@ -27,7 +27,8 @@ public class MpScenicController { - private final MpUserFeignClient userFeignClient; - private final ResourceMapService resourceMapService; - -- @ApiOperation("景区列表") -+ @ApiOperation(value = "景区列表", -+ notes = "分页查询已上架的景区列表,支持按关键词和城市筛选。聚合层透传resource-service的景区数据。") - @GetMapping("/list") - public Result>> listScenic( - @ApiParam("关键词") @RequestParam(required = false) String keyword, -@@ -42,7 +43,8 @@ public class MpScenicController { - return resourceFeignClient.listScenic(query); - } - -- @ApiOperation("景区详情") -+ @ApiOperation(value = "景区详情", -+ notes = "获取景区完整信息(含季节素材、图文详情、价格等),自动注入静态地图图片URL用于详情页地图展示。") - @GetMapping("/{scenicId}") - public Result> getScenicDetail(@ApiParam("景区ID") @PathVariable Long scenicId) { - Result> result = resourceFeignClient.getScenicDetail(scenicId); -@@ -52,7 +54,8 @@ public class MpScenicController { - return result; - } - -- @ApiOperation("附近景区(地理+探索分类聚合)") -+ @ApiOperation(value = "附近景区(地理+探索分类聚合)", -+ notes = "聚合两个数据源:1.基于经纬度的地理位置附近景区(resource-service);2.探索分类关联的景区(user-service)。去重合并后返回,用于景区详情页底部'附近推荐'展示。") - @GetMapping("/{scenicId}/nearby") - public Result>> getNearbyScenic( - @ApiParam("景区ID") @PathVariable Long scenicId, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpSearchController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpSearchController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpSearchController.java -index 7a2362a..689c544 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpSearchController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpSearchController.java -@@ -20,7 +20,7 @@ public class MpSearchController { - - private final MpProductFeignClient productFeignClient; - -- @ApiOperation("搜索产品") -+ @ApiOperation(value = "搜索产品", notes = "按关键词搜索已上架产品(匹配产品名称和描述),支持按产品类型进一步筛选\n\n**关联字典(BFF透传)**:\n- product_type:产品类型(筛选+显示)") - @GetMapping - public Result>> search( - @ApiParam("搜索关键词") @RequestParam String keyword, -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTravelerController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTravelerController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTravelerController.java -index 8831fd0..4f8f4d9 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTravelerController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTravelerController.java -@@ -22,7 +22,7 @@ public class MpTravelerController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("添加出行人") -+ @ApiOperation(value = "添加出行人", notes = "添加常用出行人信息(姓名/证件/联系方式等),下单时可快速选择。单个用户最多50个出行人") - @PostMapping - public Result> addTraveler(HttpServletRequest request, - @RequestBody MpTravelerRequest body) { -@@ -31,21 +31,23 @@ public class MpTravelerController { - return userFeignClient.addTraveler(userId, map); - } - -- @ApiOperation("出行人列表") -+ @ApiOperation(value = "出行人列表", notes = "返回当前用户的所有出行人列表。如果用户已完善实名信息,列表中会自动包含一条「本人」虚拟记录(travelerId=0)") - @GetMapping - public Result>> listTravelers(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.listTravelers(userId); - } - -- @ApiOperation("出行人详情") -+ @ApiOperation(value = "出行人详情", -+ notes = "获取单个出行人的完整信息(姓名、证件信息、联系方式等)。\n\n**权限**:需登录,仅能查看自己的出行人。") - @GetMapping("/{id}") - public Result> getTraveler(HttpServletRequest request, @ApiParam("出行人ID") @PathVariable Long id) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.getTraveler(userId, id); - } - -- @ApiOperation("更新出行人") -+ @ApiOperation(value = "更新出行人", -+ notes = "修改出行人信息,支持部分更新(只传需要修改的字段)。已关联订单的出行人修改不影响历史订单记录。\n\n**权限**:需登录。") - @PutMapping("/{id}") - public Result> updateTraveler(HttpServletRequest request, - @ApiParam("出行人ID") @PathVariable Long id, -@@ -55,14 +57,15 @@ public class MpTravelerController { - return userFeignClient.updateTraveler(userId, id, map); - } - -- @ApiOperation("删除出行人") -+ @ApiOperation(value = "删除出行人", -+ notes = "删除常用出行人记录。默认出行人不可删除,需先取消默认后再删除。\n\n**权限**:需登录。") - @DeleteMapping("/{id}") - public Result deleteTraveler(HttpServletRequest request, @ApiParam("出行人ID") @PathVariable Long id) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.deleteTraveler(userId, id); - } - -- @ApiOperation("设为默认出行人") -+ @ApiOperation(value = "设为默认出行人", notes = "设为默认出行人后,下单时自动作为第一个出行人。每个用户只能有一个默认出行人") - @PutMapping("/{id}/default") - public Result setDefaultTraveler(HttpServletRequest request, @ApiParam("出行人ID") @PathVariable Long id) { - Long userId = (Long) request.getAttribute("userId"); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTripController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTripController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTripController.java -index 5247c6f..9870345 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTripController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpTripController.java -@@ -22,14 +22,14 @@ public class MpTripController { - private final MpOrderFeignClient orderFeignClient; - private final WeatherService weatherService; - -- @ApiOperation(value = "行程列表", notes = "获取当前登录用户的行程列表(已确认及进行中的订单对应的行程)") -+ @ApiOperation(value = "行程列表", notes = "获取当前登录用户的行程列表(已确认及进行中的订单对应的行程)\n\n**关联字典(BFF透传)**:\n- order_status:订单/行程状态(显示)") - @GetMapping("/list") - public Result>> getTripList(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return orderFeignClient.getTripList(userId); - } - -- @ApiOperation(value = "行程详情", notes = "获取订单对应的行程详情,含每日行程节点信息(景点/酒店/餐厅等)") -+ @ApiOperation(value = "行程详情", notes = "获取订单对应的行程详情,含每日行程节点信息(景点/酒店/餐厅等)\n\n**关联字典(BFF透传)**:\n- order_status:订单/行程状态(显示)") - @GetMapping("/{orderId}") - public Result> getTripDetail(HttpServletRequest request, - @ApiParam(value = "订单ID", required = true) @PathVariable Long orderId) { -@@ -37,7 +37,7 @@ public class MpTripController { - return orderFeignClient.getTripDetail(userId, orderId); - } - -- @ApiOperation(value = "今日行程", notes = "获取今日行程(如果有正在进行中的行程),无行程时data为null") -+ @ApiOperation(value = "今日行程", notes = "获取今日行程(如果有正在进行中的行程),无行程时data为null\n\n**关联字典(BFF透传)**:\n- order_status:订单/行程状态(显示)") - @GetMapping("/today") - public Result> getTodayTrip(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpUserController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpUserController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpUserController.java -index 26146f8..249591a 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpUserController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpUserController.java -@@ -20,7 +20,7 @@ public class MpUserController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("发送短信验证码") -+ @ApiOperation(value = "发送短信验证码", notes = "向指定手机号发送登录验证码,有效期5分钟,60秒内不可重复发送") - @PostMapping("/sms/send") - public Result sendSmsCode(@RequestBody MpSmsSendRequest request) { - Map map = new java.util.HashMap<>(); -@@ -45,14 +45,14 @@ public class MpUserController { - return userFeignClient.login(map); - } - -- @ApiOperation("获取用户信息") -+ @ApiOperation(value = "获取用户信息", notes = "获取当前登录用户的个人资料,包含头像、昵称、手机号、实名信息等") - @GetMapping("/profile") - public Result> getProfile(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.getProfile(userId); - } - -- @ApiOperation("更新用户信息") -+ @ApiOperation(value = "更新用户信息", notes = "更新当前用户的个人资料,支持部分更新(只传需要修改的字段)。首次完善资料时realName为必填") - @PutMapping("/profile") - public Result> updateProfile(HttpServletRequest request, - @RequestBody MpUserProfileUpdateRequest body) { -@@ -69,7 +69,8 @@ public class MpUserController { - return userFeignClient.updateProfile(userId, map); - } - -- @ApiOperation("用户登出") -+ @ApiOperation(value = "用户登出", -+ notes = "清除用户登录状态和服务端缓存的令牌信息。登出后需重新登录获取新令牌。\n\n**权限**:需登录。") - @PostMapping("/logout") - public Result logout(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWeatherController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWeatherController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWeatherController.java -index 9341450..592fba5 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWeatherController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWeatherController.java -@@ -19,21 +19,21 @@ public class MpWeatherController { - - private final MpOrderFeignClient orderFeignClient; - -- @ApiOperation("获取订单行程天气") -+ @ApiOperation(value = "获取订单行程天气", notes = "根据订单行程中的目的地城市,批量查询每日天气信息,用于行程详情页展示") - @GetMapping("/itinerary/{orderId}") - public Result>> getItineraryWeather( - @ApiParam("订单ID") @PathVariable Long orderId) { - return orderFeignClient.getItineraryWeather(orderId); - } - -- @ApiOperation("获取指定城市实况天气") -+ @ApiOperation(value = "获取指定城市实况天气", notes = "通过高德天气API查询指定城市的实时天气(温度、湿度、风向等)") - @GetMapping("/live") - public Result> getLiveWeather( - @ApiParam("城市名称") @RequestParam String city) { - return orderFeignClient.getLiveWeather(city); - } - -- @ApiOperation("获取指定城市天气预报") -+ @ApiOperation(value = "获取指定城市天气预报", notes = "通过高德天气API查询指定城市未来3天的天气预报信息") - @GetMapping("/forecast") - public Result> getForecastWeather( - @ApiParam("城市名称") @RequestParam String city) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWikiController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWikiController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWikiController.java -index 26fe4ac..c70bd36 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWikiController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWikiController.java -@@ -20,13 +20,15 @@ public class MpWikiController { - - private final MpWikiFeignClient wikiFeignClient; - -- @ApiOperation("攻略分类列表") -+ @ApiOperation(value = "攻略分类列表", -+ notes = "获取所有已启用的攻略分类,按排序值排列。用于小程序攻略频道的分类导航展示。") - @GetMapping("/categories") - public Result>> listCategories() { - return wikiFeignClient.listEnabledCategories(); - } - -- @ApiOperation("分类文章列表") -+ @ApiOperation(value = "分类文章列表", -+ notes = "分页查询指定攻略分类下已发布的文章列表,按发布时间倒序排列。用于攻略分类详情页。") - @GetMapping("/category/{categoryId}/articles") - public Result>> listCategoryArticles( - @ApiParam("攻略分类ID") @PathVariable Long categoryId, -@@ -35,13 +37,14 @@ public class MpWikiController { - return wikiFeignClient.listCategoryArticles(categoryId, page, pageSize); - } - -- @ApiOperation("文章详情") -+ @ApiOperation(value = "文章详情", notes = "**关联字典(BFF透传)**:\n- wiki_status:文章状态(返回字段)") - @GetMapping("/article/{articleId}") - public Result> getArticle(@ApiParam("文章ID") @PathVariable Long articleId) { - return wikiFeignClient.getArticle(articleId); - } - -- @ApiOperation("推荐文章列表") -+ @ApiOperation(value = "推荐文章列表", -+ notes = "获取编辑推荐的攻略文章列表(按推荐权重排序),用于首页或攻略频道的推荐位展示。") - @GetMapping("/recommend-articles") - public Result>> listRecommendArticles( - @ApiParam("返回条数") @RequestParam(defaultValue = "10") Integer limit) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWishController.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWishController.java b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWishController.java -index f9abab8..d9d2416 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWishController.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/controller/MpWishController.java -@@ -21,14 +21,14 @@ public class MpWishController { - - private final MpUserFeignClient userFeignClient; - -- @ApiOperation("心愿单列表") -+ @ApiOperation(value = "心愿单列表", notes = "返回当前用户的心愿单列表,按创建时间倒序排列") - @GetMapping - public Result>> listWishes(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); - return userFeignClient.listWishes(userId); - } - -- @ApiOperation("创建心愿") -+ @ApiOperation(value = "创建心愿", notes = "创建旅行心愿,描述想去的地方和时间偏好,定制师可据此推荐产品") - @PostMapping - public Result> createWish(@ApiParam("心愿请求体") @RequestBody MpWishCreateRequest body, - HttpServletRequest request) { -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/feign/MpPaymentFeignClient.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpPaymentFeignClient.java b/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpPaymentFeignClient.java -index b722dd7..d30f577 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpPaymentFeignClient.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpPaymentFeignClient.java -@@ -19,6 +19,6 @@ public interface MpPaymentFeignClient { - @PathVariable("orderId") Long orderId); - - @GetMapping("/internal/payment/transactions/{orderId}") -- Result listTransactions(@RequestParam("userId") Long userId, -+ Result>> listTransactions(@RequestParam("userId") Long userId, - @PathVariable("orderId") Long orderId); - } -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/feign/MpPaymentFeignFallbackFactory.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpPaymentFeignFallbackFactory.java b/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpPaymentFeignFallbackFactory.java -index 48fc044..28c303b 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpPaymentFeignFallbackFactory.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpPaymentFeignFallbackFactory.java -@@ -27,7 +27,7 @@ public class MpPaymentFeignFallbackFactory implements FallbackFactory listTransactions(Long userId, Long orderId) { -+ public Result>> listTransactions(Long userId, Long orderId) { - return Result.error("支付服务不可用,请稍后重试"); - } - }; -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/feign/MpUserFeignClient.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpUserFeignClient.java b/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpUserFeignClient.java -index 3ccc5b3..9927e9a 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpUserFeignClient.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpUserFeignClient.java -@@ -189,36 +189,36 @@ public interface MpUserFeignClient { - // ==================== Explore ==================== - - @GetMapping("/internal/mp/explore/active") -- Result listActiveExploreCategories( -+ Result> listActiveExploreCategories( - @RequestParam(defaultValue = "comprehensive") String sortType, - @RequestParam(defaultValue = "1") int page, - @RequestParam(defaultValue = "20") int pageSize); - - @GetMapping("/internal/mp/explore/{id}") -- Result getExploreCategoryDetail( -+ Result> getExploreCategoryDetail( - @PathVariable("id") Long id, - @RequestHeader(value = "X-User-Id", required = false) Long userId); - - @PostMapping("/internal/mp/explore/{id}/view") -- Result incrementExploreViewCount(@PathVariable("id") Long id); -+ Result incrementExploreViewCount(@PathVariable("id") Long id); - - @PostMapping("/internal/mp/explore/{id}/like") -- Result toggleExploreLike( -+ Result toggleExploreLike( - @PathVariable("id") Long id, - @RequestHeader("X-User-Id") Long userId); - - @GetMapping("/internal/mp/explore/{id}/like/check") -- Result checkExploreLike( -+ Result checkExploreLike( - @PathVariable("id") Long id, - @RequestHeader("X-User-Id") Long userId); - - @PostMapping("/internal/mp/explore/{id}/favorite") -- Result toggleExploreFavorite( -+ Result toggleExploreFavorite( - @PathVariable("id") Long id, - @RequestHeader("X-User-Id") Long userId); - - @GetMapping("/internal/mp/explore/{id}/favorite/check") -- Result checkExploreFavorite( -+ Result checkExploreFavorite( - @PathVariable("id") Long id, - @RequestHeader("X-User-Id") Long userId); - -``` - -### `hl-mp-service/src/main/java/com/hulalv/mp/feign/MpUserFeignFallbackFactory.java` (M) - -```diff -diff --git a/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpUserFeignFallbackFactory.java b/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpUserFeignFallbackFactory.java -index c9b9a72..517c974 100644 ---- a/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpUserFeignFallbackFactory.java -+++ b/hl-mp-service/src/main/java/com/hulalv/mp/feign/MpUserFeignFallbackFactory.java -@@ -215,37 +215,37 @@ public class MpUserFeignFallbackFactory implements FallbackFactory listActiveExploreCategories(String sortType, int page, int pageSize) { -+ public Result> listActiveExploreCategories(String sortType, int page, int pageSize) { - return Result.error("用户服务不可用,请稍后重试"); - } - - @Override -- public Result getExploreCategoryDetail(Long id, Long userId) { -+ public Result> getExploreCategoryDetail(Long id, Long userId) { - return Result.error("用户服务不可用,请稍后重试"); - } - - @Override -- public Result incrementExploreViewCount(Long id) { -+ public Result incrementExploreViewCount(Long id) { - return Result.error("用户服务不可用,请稍后重试"); - } - - @Override -- public Result toggleExploreLike(Long id, Long userId) { -+ public Result toggleExploreLike(Long id, Long userId) { - return Result.error("用户服务不可用,请稍后重试"); - } - - @Override -- public Result checkExploreLike(Long id, Long userId) { -+ public Result checkExploreLike(Long id, Long userId) { - return Result.error("用户服务不可用,请稍后重试"); - } - - @Override -- public Result toggleExploreFavorite(Long id, Long userId) { -+ public Result toggleExploreFavorite(Long id, Long userId) { - return Result.error("用户服务不可用,请稍后重试"); - } - - @Override -- public Result checkExploreFavorite(Long id, Long userId) { -+ public Result checkExploreFavorite(Long id, Long userId) { - return Result.error("用户服务不可用,请稍后重试"); - } - -``` - -### `hl-order-service/src/main/java/com/hulalv/order/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/config/Knife4jConfig.java b/hl-order-service/src/main/java/com/hulalv/order/config/Knife4jConfig.java -index 6e9ee90..1e90666 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/config/Knife4jConfig.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/config/Knife4jConfig.java -@@ -39,17 +39,6 @@ public class Knife4jConfig { - .build(); - } - -- @Bean -- public Docket internalApi() { -- return new Docket(DocumentationType.SWAGGER_2) -- .groupName("3.3 内部接口(Feign)") -- .apiInfo(apiInfo()) -- .select() -- .apis(RequestHandlerSelectors.basePackage(BASE_PACKAGE)) -- .paths(PathSelectors.ant("/internal/**")) -- .build(); -- } -- - private ApiInfo apiInfo() { - return new ApiInfoBuilder() - .title("呼籁旅行 - 订单服务 API") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminAlbumController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminAlbumController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminAlbumController.java -index 9b8e419..dce7686 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminAlbumController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminAlbumController.java -@@ -28,7 +28,7 @@ public class AdminAlbumController { - - // ==================== 文件夹管理 ==================== - -- @ApiOperation("创建相册文件夹") -+ @ApiOperation(value = "创建相册文件夹", notes = "为订单创建旅行相册文件夹(如'第一天风景'、'合影'等),用于组织旅途照片/视频") - @PostMapping("/{orderId}/album/folder") - public Result createFolder( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -38,7 +38,7 @@ public class AdminAlbumController { - return Result.success(albumService.createFolder(orderId, request, adminId)); - } - -- @ApiOperation("编辑相册文件夹") -+ @ApiOperation(value = "编辑相册文件夹", notes = "修改文件夹名称或描述。仅创建者或超级管理员可操作") - @PutMapping("/album/folder/{folderId}") - public Result updateFolder( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -49,7 +49,7 @@ public class AdminAlbumController { - return Result.success(albumService.updateFolder(folderId, request, adminId, roleKey)); - } - -- @ApiOperation("删除相册文件夹") -+ @ApiOperation(value = "删除相册文件夹", notes = "删除文件夹及其下所有文件。仅创建者或超级管理员可操作。删除后C端用户不再可见") - @DeleteMapping("/album/folder/{folderId}") - public Result deleteFolder( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -60,7 +60,8 @@ public class AdminAlbumController { - return Result.success(null); - } - -- @ApiOperation("查询订单的文件夹列表") -+ @ApiOperation(value = "查询订单的文件夹列表", -+ notes = "获取指定订单的所有相册文件夹,含文件夹名称、描述、封面图、文件数量等信息。") - @GetMapping("/{orderId}/album/folders") - public Result> listFolders( - @ApiParam("订单ID") @PathVariable Long orderId) { -@@ -69,7 +70,11 @@ public class AdminAlbumController { - - // ==================== 文件管理 ==================== - -- @ApiOperation("批量添加文件到文件夹") -+ @ApiOperation(value = "批量添加文件到文件夹", notes = "一次添加多个照片/视频到指定文件夹。文件需先通过文件服务上传获取OSS URL\n\n" + -+ "**关联字典**:\n" + -+ "- album_file_type(文件类型,返回字段fileType):IMAGE=图片, VIDEO=视频\n" + -+ "- album_location_type(地点类型,返回字段locationType):RESOURCE=关联资源, CUSTOM=自定义地点\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PostMapping("/album/folder/{folderId}/files") - public Result> addFiles( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -80,7 +85,10 @@ public class AdminAlbumController { - return Result.success(albumService.addFiles(folderId, request, adminId, roleKey)); - } - -- @ApiOperation("编辑文件信息") -+ @ApiOperation(value = "编辑文件信息", notes = "**关联字典**:\n" + -+ "- album_file_type(文件类型,返回字段fileType):IMAGE=图片, VIDEO=视频\n" + -+ "- album_location_type(地点类型,返回字段locationType):RESOURCE=关联资源, CUSTOM=自定义地点\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PutMapping("/album/file/{albumFileId}") - public Result updateFile( - @ApiParam("相册文件ID") @PathVariable Long albumFileId, -@@ -91,7 +99,8 @@ public class AdminAlbumController { - return Result.success(albumService.updateFile(albumFileId, request, adminId, roleKey)); - } - -- @ApiOperation("删除文件") -+ @ApiOperation(value = "删除文件", -+ notes = "删除相册中的单个文件(照片/视频)。仅上传者或超级管理员可操作,删除后C端用户不再可见。") - @DeleteMapping("/album/file/{albumFileId}") - public Result deleteFile( - @ApiParam("相册文件ID") @PathVariable Long albumFileId, -@@ -102,7 +111,10 @@ public class AdminAlbumController { - return Result.success(null); - } - -- @ApiOperation("查询文件夹下的文件列表") -+ @ApiOperation(value = "查询文件夹下的文件列表", notes = "**关联字典**:\n" + -+ "- album_file_type(文件类型,返回字段fileType):IMAGE=图片, VIDEO=视频\n" + -+ "- album_location_type(地点类型,返回字段locationType):RESOURCE=关联资源, CUSTOM=自定义地点\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @GetMapping("/album/folder/{folderId}/files") - public Result> listFiles( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -111,7 +123,8 @@ public class AdminAlbumController { - return Result.success(albumService.listFiles(folderId, page, size)); - } - -- @ApiOperation("设置文件夹封面") -+ @ApiOperation(value = "设置文件夹封面", -+ notes = "将文件夹中的指定文件设为封面图,封面图会在文件夹列表中展示。仅上传者或超级管理员可操作。") - @PutMapping("/album/folder/{folderId}/cover") - public Result setCover( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -123,7 +136,11 @@ public class AdminAlbumController { - return Result.success(null); - } - -- @ApiOperation("我的上传(当前管理员上传的所有相册文件)") -+ @ApiOperation(value = "我的上传", notes = "查询当前管理员上传的所有相册文件(跨订单),方便管理自己上传的内容\n\n" + -+ "**关联字典**:\n" + -+ "- album_file_type(文件类型,返回字段fileType):IMAGE=图片, VIDEO=视频\n" + -+ "- album_location_type(地点类型,返回字段locationType):RESOURCE=关联资源, CUSTOM=自定义地点\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @GetMapping("/album/my-uploads") - public Result> listMyUploads( - HttpServletRequest httpRequest, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminEarlyBirdController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminEarlyBirdController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminEarlyBirdController.java -index 261c457..85b97c1 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminEarlyBirdController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminEarlyBirdController.java -@@ -31,7 +31,7 @@ public class AdminEarlyBirdController { - } - } - -- @ApiOperation("早鸟优惠计划列表") -+ @ApiOperation(value = "早鸟优惠计划列表", notes = "分页查询所有早鸟优惠计划。权限:仅超级管理员(SUPER_ADMIN)") - @GetMapping("/list") - public Result> list(HttpServletRequest request, - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -41,7 +41,7 @@ public class AdminEarlyBirdController { - return Result.success(result); - } - -- @ApiOperation("早鸟优惠计划详情") -+ @ApiOperation(value = "早鸟优惠计划详情", notes = "权限:仅超级管理员(SUPER_ADMIN)") - @GetMapping("/{planId}") - public Result detail(HttpServletRequest request, - @ApiParam("早鸟计划ID") @PathVariable Long planId) { -@@ -50,7 +50,8 @@ public class AdminEarlyBirdController { - return Result.success(vo); - } - -- @ApiOperation("创建早鸟优惠计划") -+ @ApiOperation(value = "创建早鸟优惠计划", notes = "创建一个早鸟优惠计划,在指定日期范围内下单且满足最低人数条件的订单可享受优惠。\n" + -+ "下单时系统自动匹配最优的早鸟计划。权限:仅超级管理员(SUPER_ADMIN)") - @PostMapping - public Result create(HttpServletRequest request, - @ApiParam("创建早鸟计划请求") @Valid @RequestBody EarlyBirdPlanRequest planRequest) { -@@ -61,7 +62,7 @@ public class AdminEarlyBirdController { - return Result.success(vo); - } - -- @ApiOperation("修改早鸟优惠计划") -+ @ApiOperation(value = "修改早鸟优惠计划", notes = "权限:仅超级管理员(SUPER_ADMIN)。修改不影响已下单的订单优惠") - @PutMapping("/{planId}") - public Result update(HttpServletRequest request, - @ApiParam("早鸟计划ID") @PathVariable Long planId, -@@ -71,7 +72,7 @@ public class AdminEarlyBirdController { - return Result.success(); - } - -- @ApiOperation("删除早鸟优惠计划") -+ @ApiOperation(value = "删除早鸟优惠计划", notes = "权限:仅超级管理员(SUPER_ADMIN)。删除不影响已下单的订单优惠") - @DeleteMapping("/{planId}") - public Result delete(HttpServletRequest request, - @ApiParam("早鸟计划ID") @PathVariable Long planId) { -@@ -80,7 +81,7 @@ public class AdminEarlyBirdController { - return Result.success(); - } - -- @ApiOperation("启用/禁用早鸟优惠计划") -+ @ApiOperation(value = "启用/禁用早鸟优惠计划", notes = "禁用后该计划不再参与自动匹配。权限:仅超级管理员(SUPER_ADMIN)") - @PutMapping("/{planId}/toggle") - public Result toggle(HttpServletRequest request, - @ApiParam("早鸟计划ID") @PathVariable Long planId, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderConfigController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderConfigController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderConfigController.java -index de26a0f..d79934d 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderConfigController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderConfigController.java -@@ -27,7 +27,8 @@ public class AdminOrderConfigController { - @Value("${order.expiry.redis-key:order:config:expiry-minutes}") - private String expiryRedisKey; - -- @ApiOperation("获取订单过期配置") -+ @ApiOperation(value = "获取订单过期配置", notes = "获取当前的订单未支付自动过期时间(分钟)。\n" + -+ "返回当前值、默认值和配置来源(redis=已自定义, default=使用默认值)") - @GetMapping("/expiry-minutes") - public Result> getExpiryMinutes() { - String val = stringRedisTemplate.opsForValue().get(expiryRedisKey); -@@ -45,7 +46,8 @@ public class AdminOrderConfigController { - )); - } - -- @ApiOperation("设置订单过期时间(分钟)") -+ @ApiOperation(value = "设置订单过期时间(分钟)", notes = "修改订单未支付自动取消的等待时间。存储在Redis中,即时生效。\n" + -+ "仅影响新创建的订单,已有订单的过期时间不变") - @PutMapping("/expiry-minutes") - public Result setExpiryMinutes(@ApiParam("修改订单过期时间请求") @Valid @RequestBody UpdateExpiryMinutesRequest expiryRequest) { - stringRedisTemplate.opsForValue().set(expiryRedisKey, String.valueOf(expiryRequest.getMinutes())); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderController.java -index e7f09ce..72bdfc8 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderController.java -@@ -47,7 +47,18 @@ public class AdminOrderController { - private static final String ORDER_CREATE_DEDUP = "order:admin:create:dedup:"; - - @ApiOperation(value = "创建订单(定制师代下单)", notes = "创建订单流程:选择产品 → 填写联系人和出行人 → 系统计算报价 → 生成订单(PENDING_PAY状态)\n\n" + -- "权限:CUSTOM产品仅创建者可下单,CORE/ROUTE产品所有管理员可下单") -+ "权限:CUSTOM产品仅创建者可下单,CORE/ROUTE产品所有管理员可下单\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 productType → 字典:product_type(产品类型)\n" + -+ "- 请求参数 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 请求参数 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 请求参数 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)\n" + -+ "- 返回字段 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 返回字段 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 返回字段 travelers[].gender → 字典:gender(性别)") - @PostMapping("/create") - public Result createOrder(HttpServletRequest request, - @ApiParam("创建订单请求") @Valid @RequestBody AdminCreateOrderRequest createRequest) { -@@ -69,21 +80,41 @@ public class AdminOrderController { - } - } - -- @ApiOperation("报价预览") -+ @ApiOperation(value = "报价预览", notes = "根据产品、出发日期、人数组合实时计算报价。\n" + -+ "返回各资源明细价格和合计金额,前端据此展示报价清单。\n\n" + -+ "注意:报价仅供参考,最终价格以创建订单时为准(价格日历可能变动)") - @PostMapping("/quote") - public Result> quotePreview(@ApiParam("报价预览请求") @Valid @RequestBody QuotePreviewRequest quoteRequest) { - Map result = orderService.quotePreview(quoteRequest); - return Result.success(result); - } - -- @ApiOperation("订单列表") -+ @ApiOperation(value = "订单列表", notes = "支持按关键词(订单号/联系人/产品名)、状态、内部流程状态、产品类型筛选。\n" + -+ "支持按创建时间/出发日期/总价排序。\n\n" + -+ "返回分页结果,包含订单基本信息、状态、支付信息和产品封面\n\n" + -+ "【关联字典】\n" + -+ "- 筛选参数 status → 字典:order_status(订单状态)\n" + -+ "- 筛选参数 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 筛选参数 productType → 字典:product_type(产品类型)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/list") - public Result> listOrders(@ApiParam("订单查询请求") AdminOrderQueryRequest request) { - PageResult result = orderService.listAdminOrders(request); - return Result.success(result); - } - -- @ApiOperation("订单详情") -+ @ApiOperation(value = "订单详情", notes = "返回订单完整信息,包括:基本信息、产品快照、联系人、出行人列表、支付记录、优惠明细、时间线、内部流程状态等\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)\n" + -+ "- 返回字段 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 返回字段 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 返回字段 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 timeline[].action → 字典:order_timeline_action(订单操作类型)\n" + -+ "- 返回字段 todos[].todoType → 字典:order_todo_type(订单待办类型)") - @GetMapping("/{orderId}") - public Result getOrder(@ApiParam("订单ID") @PathVariable Long orderId) { - OrderDetailVO detail = orderService.getAdminOrderDetail(orderId); -@@ -111,7 +142,9 @@ public class AdminOrderController { - "- 旅行中 → 已完成\n" + - "- 已完成 → 售后中\n" + - "- 售后中 → 退款中\n" + -- "- 退款中 → 已退款") -+ "- 退款中 → 已退款\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 status → 字典:order_status(订单状态)") - @PutMapping("/{orderId}/status") - public Result updateStatus(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -134,7 +167,7 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("添加备注") -+ @ApiOperation(value = "添加备注", notes = "向订单时间线添加一条管理员备注。备注会记录操作人和时间,可用于内部沟通和订单跟踪") - @PostMapping("/{orderId}/remark") - public Result addRemark(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -145,7 +178,8 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("修改定金金额") -+ @ApiOperation(value = "修改定金金额", notes = "修改订单的定金金额。仅待支付(PENDING_PAY)状态可修改。\n\n" + -+ "定金金额不能超过订单总价,修改后影响用户支付页面显示的应付金额") - @PutMapping("/{orderId}/deposit") - public Result updateDeposit(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -156,7 +190,14 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("编辑订单") -+ @ApiOperation(value = "编辑订单", notes = "修改订单的联系人、人数、出发日期、售价、成本、备注等信息。\n" + -+ "仅传入需要修改的字段,未传入的字段不会被修改。\n\n" + -+ "如果提供了出行人列表(travelers),将替换订单的全部出行人。\n" + -+ "已锁定的订单需先调用'申请修改'接口解锁后才能编辑\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 请求参数 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 请求参数 travelers[].gender → 字典:gender(性别)") - @PutMapping("/{orderId}") - public Result editOrder(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -167,7 +208,8 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("更新房间信息(仅房务管理员/超级管理员)") -+ @ApiOperation(value = "更新房间信息(仅房务管理员/超级管理员)", -+ notes = "更新订单的房间分配信息(房型、房间号、入住安排等)。\n\n**权限**:仅ROOM_MANAGER(房务管理员)或SUPER_ADMIN(超级管理员)可操作。") - @PutMapping("/{orderId}/room-info") - public Result updateRoomInfo(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -183,7 +225,8 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("更新车辆信息(仅车务管理员/超级管理员)") -+ @ApiOperation(value = "更新车辆信息(仅车务管理员/超级管理员)", -+ notes = "更新订单的车辆分配信息(车型、车牌号、司机等)。\n\n**权限**:仅VEHICLE_MANAGER(车务管理员)或SUPER_ADMIN(超级管理员)可操作。") - @PutMapping("/{orderId}/vehicle-info") - public Result updateVehicleInfo(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -210,7 +253,9 @@ public class AdminOrderController { - } - - @ApiOperation(value = "推进内部流程", notes = "内部流程推进顺序:待配房(PENDING_ROOM) → 待配车(PENDING_VEHICLE) → 待核算(PENDING_FINANCE) → 就绪(READY)\n\n" + -- "仅在订单状态为已确认(CONFIRMED)时有效,每次调用自动推进到下一步") -+ "仅在订单状态为已确认(CONFIRMED)时有效,每次调用自动推进到下一步\n\n" + -+ "【关联字典】\n" + -+ "- 涉及字段 processStatus → 字典:order_process_status(订单内部流程状态)") - @PutMapping("/{orderId}/process-status") - public Result advanceProcessStatus(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId) { -@@ -220,7 +265,8 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("添加优惠项") -+ @ApiOperation(value = "添加优惠项", notes = "为订单添加手动优惠(如会员折扣、老客优惠等)。\n" + -+ "添加后系统自动重算订单应付金额。一个订单可添加多个优惠项") - @PostMapping("/{orderId}/discount") - public Result addDiscount(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -231,7 +277,7 @@ public class AdminOrderController { - return Result.success(discount); - } - -- @ApiOperation("修改优惠项") -+ @ApiOperation(value = "修改优惠项", notes = "修改已添加的优惠项名称或金额,修改后自动重算订单应付金额") - @PutMapping("/{orderId}/discount/{discountId}") - public Result updateDiscount(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -243,7 +289,7 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("删除优惠项") -+ @ApiOperation(value = "删除优惠项", notes = "删除已添加的优惠项,删除后自动重算订单应付金额") - @DeleteMapping("/{orderId}/discount/{discountId}") - public Result removeDiscount(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -296,7 +342,8 @@ public class AdminOrderController { - return Result.success(diff); - } - -- @ApiOperation("分配车辆信息") -+ @ApiOperation(value = "分配车辆信息", notes = "为订单分配具体的车辆和司机信息(车型、品牌、车牌号、司机姓名和电话)。\n" + -+ "分配后信息将展示在订单详情和C端行程中") - @PutMapping("/{orderId}/vehicle-assignment") - public Result assignVehicle(@ApiParam("订单ID") @PathVariable Long orderId, - @RequestBody @Valid VehicleAssignmentRequest request) { -@@ -304,7 +351,8 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("分配酒店信息") -+ @ApiOperation(value = "分配酒店信息", notes = "按家庭为订单分配具体的酒店房间(酒店名称、房型、入住/退房日期)。\n" + -+ "每个家庭对应一条分配记录,分配后信息将展示在订单详情和C端行程中") - @PutMapping("/{orderId}/hotel-assignment") - public Result assignHotel(@ApiParam("订单ID") @PathVariable Long orderId, - @RequestBody @Valid HotelAssignmentRequest request) { -@@ -312,7 +360,7 @@ public class AdminOrderController { - return Result.success(); - } - -- @ApiOperation("设置尾款支付方式") -+ @ApiOperation(value = "设置尾款支付方式", notes = "设置订单尾款的支付方式。ONLINE=线上微信支付,OFFLINE=线下转账(需管理员手动记录尾款到账)") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderItineraryController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderItineraryController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderItineraryController.java -index 83ae39c..9ab5d5e 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderItineraryController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderItineraryController.java -@@ -31,7 +31,11 @@ public class AdminOrderItineraryController { - private final OrderItineraryEditService itineraryEditService; - private final OrderPriceDiffService priceDiffService; - -- @ApiOperation(value = "跳过节点", notes = "将行程中的某个节点标记为跳过(客户不去)") -+ @ApiOperation(value = "跳过节点", notes = "将行程中的某个节点标记为跳过(客户不去)\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PostMapping("/skip") - public Result skipNode( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -43,7 +47,10 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.skipNode(orderId, request, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "恢复跳过的节点", notes = "取消跳过,恢复为正常状态") -+ @ApiOperation(value = "恢复跳过的节点", notes = "取消跳过,恢复为正常状态\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @DeleteMapping("/skip/{editId}") - public Result unskipNode( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -58,7 +65,11 @@ public class AdminOrderItineraryController { - return Result.success(); - } - -- @ApiOperation(value = "新增节点", notes = "在某一天的行程中新增一个节点") -+ @ApiOperation(value = "新增节点", notes = "在某一天的行程中新增一个节点\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PostMapping("/add") - public Result addNode( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -76,7 +87,10 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.addNode(orderId, request, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "删除新增的节点", notes = "删除通过编辑新增的节点") -+ @ApiOperation(value = "删除新增的节点", notes = "删除通过编辑新增的节点\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @DeleteMapping("/add/{editId}") - public Result removeAddedNode( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -91,7 +105,10 @@ public class AdminOrderItineraryController { - return Result.success(); - } - -- @ApiOperation("获取合并后的行程(原始+编辑)") -+ @ApiOperation(value = "获取合并后的行程(原始+编辑)", notes = "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @GetMapping("/merged") - public Result>> getMergedItinerary( - @ApiParam("订单ID") @PathVariable Long orderId) { -@@ -105,14 +122,19 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.getBalanceAdjustmentSummary(orderId)); - } - -- @ApiOperation("获取行程编辑记录列表") -+ @ApiOperation(value = "获取行程编辑记录列表", notes = "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @GetMapping("/edits") - public Result> getEditList( - @ApiParam("订单ID") @PathVariable Long orderId) { - return Result.success(itineraryEditService.getEditList(orderId)); - } - -- @ApiOperation(value = "房型切换差价预览", notes = "预览房型切换的差价,不创建记录") -+ @ApiOperation(value = "房型切换差价预览", notes = "预览房型切换的差价,不创建记录\n\n" + -+ "**关联字典**:\n" + -+ "- resource_type(资源类型,返回字段resourceType):HOTEL=酒店") - @PostMapping("/room-type-change/preview") - public Result previewRoomTypeChange( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -120,7 +142,11 @@ public class AdminOrderItineraryController { - return Result.success(priceDiffService.previewRoomTypeDiff(orderId, request)); - } - -- @ApiOperation(value = "房型切换", notes = "执行房型切换,自动计算差价,创建待确认记录") -+ @ApiOperation(value = "房型切换", notes = "执行房型切换,自动计算差价,创建待确认记录\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):ROOM_CHANGE=房型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):HOTEL=酒店") - @PostMapping("/room-type-change") - public Result roomTypeChange( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -132,7 +158,9 @@ public class AdminOrderItineraryController { - return Result.success(priceDiffService.executeRoomTypeChange(orderId, request, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "车型切换差价预览", notes = "预览车型切换的差价,不创建记录") -+ @ApiOperation(value = "车型切换差价预览", notes = "预览车型切换的差价,不创建记录\n\n" + -+ "**关联字典**:\n" + -+ "- resource_type(资源类型,返回字段resourceType):VEHICLE=车辆") - @PostMapping("/vehicle-type-change/preview") - public Result previewVehicleTypeChange( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -140,7 +168,11 @@ public class AdminOrderItineraryController { - return Result.success(priceDiffService.previewVehicleTypeDiff(orderId, request)); - } - -- @ApiOperation(value = "车型切换", notes = "执行车型切换,自动计算差价,创建待确认记录") -+ @ApiOperation(value = "车型切换", notes = "执行车型切换,自动计算差价,创建待确认记录\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):VEHICLE=车辆") - @PostMapping("/vehicle-type-change") - public Result vehicleTypeChange( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -152,7 +184,11 @@ public class AdminOrderItineraryController { - return Result.success(priceDiffService.executeVehicleTypeChange(orderId, request, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "新增整天行程", notes = "在订单行程中新增一整天(含多个节点)") -+ @ApiOperation(value = "新增整天行程", notes = "在订单行程中新增一整天(含多个节点)\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):ADD_DAY=新增整天\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PostMapping("/add-day") - public Result> addDay( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -164,7 +200,9 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.addDay(orderId, request, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "删除新增的整天行程", notes = "删除通过新增操作添加的整天行程及其所有子节点,已确认的天不允许删除") -+ @ApiOperation(value = "删除新增的整天行程", notes = "删除通过新增操作添加的整天行程及其所有子节点,已确认的天不允许删除\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @DeleteMapping("/day/{editId}") - public Result removeDay( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -179,7 +217,11 @@ public class AdminOrderItineraryController { - return Result.success(); - } - -- @ApiOperation(value = "修改编辑记录", notes = "修改待确认状态的编辑记录(如调整价格、名称等)") -+ @ApiOperation(value = "修改编辑记录", notes = "修改待确认状态的编辑记录(如调整价格、名称等)\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_edit_action(操作类型,返回字段action):SKIP=跳过, ADD=新增节点, ADD_DAY=新增整天, ROOM_CHANGE=房型切换, VEHICLE_CHANGE=车型切换\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @PutMapping("/edit/{editId}") - public Result updateEdit( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -192,7 +234,9 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.updateEdit(orderId, editId, updates, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "确认单条修改", notes = "确认一条待确认的行程编辑") -+ @ApiOperation(value = "确认单条修改", notes = "确认一条待确认的行程编辑\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @PostMapping("/confirm/{editId}") - public Result confirmEdit( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -205,7 +249,9 @@ public class AdminOrderItineraryController { - return Result.success(); - } - -- @ApiOperation(value = "批量确认所有待确认修改", notes = "确认该订单所有待确认的行程编辑") -+ @ApiOperation(value = "批量确认所有待确认修改", notes = "确认该订单所有待确认的行程编辑\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @PostMapping("/confirm-all") - public Result confirmAllPending( - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -216,7 +262,9 @@ public class AdminOrderItineraryController { - return Result.success(itineraryEditService.confirmAllPending(orderId, adminId, adminName, roleKey)); - } - -- @ApiOperation(value = "撤回待确认的修改", notes = "软删除一条待确认的编辑记录") -+ @ApiOperation(value = "撤回待确认的修改", notes = "软删除一条待确认的编辑记录\n\n" + -+ "**关联字典**:\n" + -+ "- itinerary_confirm_status(确认状态,返回字段confirmStatus):PENDING_CONFIRM=待确认, CONFIRMED=已确认") - @DeleteMapping("/pending/{editId}") - public Result withdrawPendingEdit( - @ApiParam("订单ID") @PathVariable Long orderId, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderTodoController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderTodoController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderTodoController.java -index d7339d2..f708a7f 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderTodoController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminOrderTodoController.java -@@ -29,14 +29,21 @@ public class AdminOrderTodoController { - private final OrderService orderService; - private final UserFeignClient userFeignClient; - -- @ApiOperation("获取订单待办列表") -+ @ApiOperation(value = "获取订单待办列表", notes = "返回指定订单的所有待办项(含已完成和未完成)。\n" + -+ "待办类型包括:配房、配车、签合同、购保险、核算等,随内部流程自动生成\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 todoType → 字典:order_todo_type(订单待办类型)") - @GetMapping("/{orderId}/todos") - public Result> getOrderTodos(@ApiParam("订单ID") @PathVariable Long orderId) { - List todos = orderTodoService.listByOrderId(orderId); - return Result.success(todos); - } - -- @ApiOperation("完成待办") -+ @ApiOperation(value = "完成待办", notes = "将指定待办标记为已完成。\n" + -+ "需要对应角色权限:如配房待办需ROOM_MANAGER角色,配车待办需VEHICLE_MANAGER角色。\n\n" + -+ "完成后系统自动检查是否所有必要待办已完成,若是则推进内部流程\n\n" + -+ "【关联字典】\n" + -+ "- 涉及字段 todoType → 字典:order_todo_type(订单待办类型)") - @PutMapping("/todo/{todoId}/complete") - public Result completeTodo(HttpServletRequest request, - @ApiParam("待办ID") @PathVariable Long todoId) { -@@ -47,7 +54,11 @@ public class AdminOrderTodoController { - return Result.success(); - } - -- @ApiOperation("我的待办列表") -+ @ApiOperation(value = "我的待办列表", notes = "根据当前管理员ID和角色,查询分配给自己的未完成待办。\n" + -+ "超级管理员可看到所有待办,其他角色只能看到对应类型的待办\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 todoType → 字典:order_todo_type(订单待办类型)\n" + -+ "- 返回字段 orderStatus → 字典:order_status(订单状态)") - @GetMapping("/todo/my-list") - public Result> getMyTodos(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -56,7 +67,7 @@ public class AdminOrderTodoController { - return Result.success(todos); - } - -- @ApiOperation("我的待办数量") -+ @ApiOperation(value = "我的待办数量", notes = "返回当前管理员未完成的待办总数,用于首页角标/红点提醒") - @GetMapping("/todo/my-count") - public Result getMyTodosCount(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -65,7 +76,7 @@ public class AdminOrderTodoController { - return Result.success(count); - } - -- @ApiOperation("定制师列表") -+ @ApiOperation(value = "定制师列表", notes = "获取所有定制师(CUSTOMIZER角色)的列表,用于更换定制师时选择目标定制师") - @GetMapping("/todo/customizer-list") - public Result> getCustomizerList() { - try { -@@ -79,7 +90,7 @@ public class AdminOrderTodoController { - return Result.success(Collections.emptyList()); - } - -- @ApiOperation("更换定制师") -+ @ApiOperation(value = "更换定制师", notes = "将订单转派给另一位定制师。更换后原定制师的待办自动转移,订单时间线会记录此操作") - @PutMapping("/{orderId}/customizer") - public Result changeCustomizer(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId, -@@ -90,7 +101,11 @@ public class AdminOrderTodoController { - return Result.success(); - } - -- @ApiOperation("可签合同订单列表(保险已完成)") -+ @ApiOperation(value = "可签合同订单列表(保险已完成)", notes = "查询保险待办已完成、可以进入签合同环节的订单列表。\n" + -+ "用于合同管理页面展示待签合同的订单\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 todoType → 字典:order_todo_type(订单待办类型)\n" + -+ "- 返回字段 orderStatus → 字典:order_status(订单状态)") - @GetMapping("/todo/contract-eligible") - public Result> getContractEligibleOrders(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundController.java -index fddef53..eb92d44 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundController.java -@@ -31,7 +31,11 @@ public class AdminRefundController { - - // ==================== Refund Applications ==================== - -- @ApiOperation("退款申请列表") -+ @ApiOperation(value = "退款申请列表", notes = "分页查询退款申请,支持按状态筛选。\n" + -+ "状态包括:PENDING(待审批)、APPROVED(已通过)、REJECTED(已拒绝)、REFUNDING(退款中)、REFUNDED(已退款)、CANCELLED(已撤回)、APPEAL(申诉中)\n\n" + -+ "【关联字典】\n" + -+ "- 筛选参数 status → 字典:refund_status(退款状态)\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @GetMapping("/list") - public Result> listApplications( - @ApiParam("状态") @RequestParam(required = false) String status, -@@ -40,14 +44,18 @@ public class AdminRefundController { - return Result.success(refundApplicationService.listApplications(status, page, pageSize)); - } - -- @ApiOperation("退款申请详情") -+ @ApiOperation(value = "退款申请详情", notes = "返回退款申请的完整信息,包括退款原因、申请金额、实退金额、审批记录、申诉信息等\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @GetMapping("/{applicationId}") - public Result getDetail(@ApiParam("退款申请ID") @PathVariable Long applicationId) { - return Result.success(refundApplicationService.getDetail(applicationId)); - } - - @ApiOperation(value = "审批退款申请", notes = "退款审批流程:查看退款申请 → 决定通过/拒绝 → 通过时填写实退金额 → 系统自动调起微信退款\n\n" + -- "拒绝后用户可发起申诉") -+ "拒绝后用户可发起申诉\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @PutMapping("/{applicationId}/review") - public Result review(HttpServletRequest request, - @ApiParam("退款申请ID") @PathVariable Long applicationId, -@@ -79,20 +87,26 @@ public class AdminRefundController { - - // ==================== Refund Reasons ==================== - -- @ApiOperation("退款原因列表") -+ @ApiOperation(value = "退款原因列表", notes = "获取所有退款原因选项(含禁用的),用于退款原因管理页面\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 category → 字典:refund_reason_category(退款原因分类)") - @GetMapping("/reason/list") - public Result> listReasons() { - return Result.success(refundReasonService.listReasons(false)); - } - -- @ApiOperation("创建退款原因") -+ @ApiOperation(value = "创建退款原因", notes = "新增退款原因选项,C端用户申请退款时可选择。按sortOrder排序展示\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 category → 字典:refund_reason_category(退款原因分类)") - @PostMapping("/reason") - public Result createReason(@ApiParam("创建退款原因请求") @Valid @RequestBody CreateRefundReasonRequest createRequest) { - return Result.success(refundReasonService.createReason( - createRequest.getReasonText(), createRequest.getCategory(), createRequest.getSortOrder())); - } - -- @ApiOperation("修改退款原因") -+ @ApiOperation(value = "修改退款原因", notes = "修改退款原因的文本、分类或排序,不影响已使用该原因的历史退款申请\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 category → 字典:refund_reason_category(退款原因分类)") - @PutMapping("/reason/{reasonId}") - public Result updateReason(@ApiParam("退款原因ID") @PathVariable Long reasonId, - @ApiParam("修改退款原因请求") @Valid @RequestBody UpdateRefundReasonRequest updateRequest) { -@@ -100,7 +114,7 @@ public class AdminRefundController { - reasonId, updateRequest.getReasonText(), updateRequest.getCategory(), updateRequest.getSortOrder())); - } - -- @ApiOperation("删除退款原因") -+ @ApiOperation(value = "删除退款原因", notes = "软删除退款原因,删除后C端不再展示。不影响已使用该原因的历史退款申请") - @DeleteMapping("/reason/{reasonId}") - public Result deleteReason(@ApiParam("退款原因ID") @PathVariable Long reasonId) { - refundReasonService.deleteReason(reasonId); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundPolicyController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundPolicyController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundPolicyController.java -index 9ff5005..e1bc0c8 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundPolicyController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminRefundPolicyController.java -@@ -22,13 +22,17 @@ public class AdminRefundPolicyController { - - private final RefundPolicyService refundPolicyService; - -- @ApiOperation("退款政策列表") -+ @ApiOperation(value = "退款政策列表", notes = "【关联字典】\n" + -+ "- 返回字段 refundType → 字典:refund_type(退款类型)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/list") - public Result> list() { - return Result.success(refundPolicyService.listPolicies()); - } - -- @ApiOperation("退款政策详情") -+ @ApiOperation(value = "退款政策详情", notes = "【关联字典】\n" + -+ "- 返回字段 refundType → 字典:refund_type(退款类型)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/{policyId}") - public Result detail(@ApiParam("退款政策ID") @PathVariable Long policyId) { - return Result.success(refundPolicyService.getDetail(policyId)); -@@ -36,7 +40,10 @@ public class AdminRefundPolicyController { - - @ApiOperation(value = "创建退款政策", notes = "退款政策定义按产品类型和距出发天数的退款比例阶梯\n\n" + - "例如:出发前30天退90%,前15天退70%,前7天退50%,7天内不可退\n\n" + -- "每种产品类型可配置独立的退款政策,用户申请退款时系统自动匹配") -+ "每种产品类型可配置独立的退款政策,用户申请退款时系统自动匹配\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 refundType → 字典:refund_type(退款类型)\n" + -+ "- 请求参数 productType → 字典:product_type(产品类型)") - @PostMapping - public Result create(HttpServletRequest request, - @ApiParam("创建退款政策请求") @Valid @RequestBody RefundPolicyRequest policyRequest) { -@@ -44,14 +51,17 @@ public class AdminRefundPolicyController { - return Result.success(refundPolicyService.createPolicy(policyRequest, adminId)); - } - -- @ApiOperation("修改退款政策") -+ @ApiOperation(value = "修改退款政策", notes = "【关联字典】\n" + -+ "- 请求参数 refundType → 字典:refund_type(退款类型)\n" + -+ "- 请求参数 productType → 字典:product_type(产品类型)") - @PutMapping("/{policyId}") - public Result update(@ApiParam("退款政策ID") @PathVariable Long policyId, - @ApiParam("修改退款政策请求") @Valid @RequestBody RefundPolicyRequest policyRequest) { - return Result.success(refundPolicyService.updatePolicy(policyId, policyRequest)); - } - -- @ApiOperation("删除退款政策") -+ @ApiOperation(value = "删除退款政策", -+ notes = "软删除退款政策。删除后该产品类型将使用默认退款规则。不影响已使用该政策处理的历史退款申请。") - @DeleteMapping("/{policyId}") - public Result delete(@ApiParam("退款政策ID") @PathVariable Long policyId) { - refundPolicyService.deletePolicy(policyId); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/AdminWorkOrderController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminWorkOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminWorkOrderController.java -index 949f142..faf973b 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/AdminWorkOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/AdminWorkOrderController.java -@@ -25,7 +25,15 @@ public class AdminWorkOrderController { - - private final WorkOrderService workOrderService; - -- @ApiOperation("工单列表") -+ @ApiOperation(value = "工单列表", notes = "分页查询工单,支持按状态/类型/优先级/订单编号/处理人筛选。\n" + -+ "工单用于处理旅行中的突发变更需求(如换房、换车、加景点等)\n\n" + -+ "【关联字典】\n" + -+ "- 筛选参数 status → 字典:work_order_status(工单状态)\n" + -+ "- 筛选参数 type → 字典:work_order_type(工单类型)\n" + -+ "- 筛选参数 priority → 字典:work_order_priority(工单优先级)\n" + -+ "- 返回字段 status → 字典:work_order_status(工单状态)\n" + -+ "- 返回字段 type → 字典:work_order_type(工单类型)\n" + -+ "- 返回字段 priority → 字典:work_order_priority(工单优先级)") - @GetMapping("/list") - public Result> list( - @ApiParam("状态: PENDING/PROCESSING/RESOLVED/REJECTED") @RequestParam(required = false) String status, -@@ -38,19 +46,32 @@ public class AdminWorkOrderController { - return Result.success(workOrderService.listWorkOrders(status, type, priority, orderNo, assigneeAdminId, page, pageSize)); - } - -- @ApiOperation("工单详情") -+ @ApiOperation(value = "工单详情", notes = "返回工单完整信息,包括关联订单、资源详情、处理记录和备注列表\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:work_order_status(工单状态)\n" + -+ "- 返回字段 type → 字典:work_order_type(工单类型)\n" + -+ "- 返回字段 priority → 字典:work_order_priority(工单优先级)") - @GetMapping("/{workOrderId}") - public Result getDetail(@ApiParam("工单ID") @PathVariable Long workOrderId) { - return Result.success(workOrderService.getDetail(workOrderId)); - } - -- @ApiOperation("工单统计(待处理数等)") -+ @ApiOperation(value = "工单统计", notes = "返回各状态的工单数量和紧急工单数,用于工单管理页面顶部统计卡片\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段中的状态key → 字典:work_order_status(工单状态)") - @GetMapping("/stats") - public Result> getStats() { - return Result.success(workOrderService.getStats()); - } - -- @ApiOperation("创建工单") -+ @ApiOperation(value = "创建工单", notes = "创建旅途中的变更工单,需关联订单ID。\n" + -+ "可指定处理人,未指定则进入待分配状态。可附带差价信息和资源详情JSON\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 type → 字典:work_order_type(工单类型)\n" + -+ "- 请求参数 priority → 字典:work_order_priority(工单优先级)\n" + -+ "- 返回字段 status → 字典:work_order_status(工单状态)\n" + -+ "- 返回字段 type → 字典:work_order_type(工单类型)\n" + -+ "- 返回字段 priority → 字典:work_order_priority(工单优先级)") - @PostMapping - public Result create(HttpServletRequest request, - @Valid @RequestBody CreateWorkOrderRequest body) { -@@ -59,7 +80,10 @@ public class AdminWorkOrderController { - return Result.success(workOrderService.createWorkOrder(adminId, adminName, body)); - } - -- @ApiOperation("处理工单(解决/驳回)") -+ @ApiOperation(value = "处理工单(解决/驳回)", notes = "解决时需填写处理结果(resolution),驳回时需填写驳回原因(rejectReason)。\n" + -+ "可调整差价(costDifference),正数表示加价,负数表示退费\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:work_order_status(工单状态)") - @PutMapping("/{workOrderId}/process") - public Result process(HttpServletRequest request, - @ApiParam("工单ID") @PathVariable Long workOrderId, -@@ -69,7 +93,7 @@ public class AdminWorkOrderController { - return Result.success(workOrderService.processWorkOrder(workOrderId, adminId, adminName, body)); - } - -- @ApiOperation("指派工单") -+ @ApiOperation(value = "指派工单", notes = "将工单分配给指定管理员处理。被指派人将在待办列表中看到该工单") - @PutMapping("/{workOrderId}/assign") - public Result assign(HttpServletRequest request, - @ApiParam("工单ID") @PathVariable Long workOrderId, -@@ -80,7 +104,7 @@ public class AdminWorkOrderController { - return Result.success(workOrderService.assignWorkOrder(workOrderId, adminId, adminName, assigneeId, assigneeName)); - } - -- @ApiOperation("添加备注") -+ @ApiOperation(value = "添加工单备注", notes = "在工单中追加备注信息,用于内部沟通和处理过程记录") - @PostMapping("/{workOrderId}/comment") - public Result addComment(HttpServletRequest request, - @ApiParam("工单ID") @PathVariable Long workOrderId, -@@ -94,7 +118,7 @@ public class AdminWorkOrderController { - return Result.success(workOrderService.addComment(workOrderId, adminId, adminName, content)); - } - -- @ApiOperation("按订单查工单数量") -+ @ApiOperation(value = "按订单查工单数量", notes = "返回指定订单关联的工单总数,用于订单详情页展示工单角标") - @GetMapping("/count-by-order/{orderId}") - public Result countByOrder(@ApiParam("订单ID") @PathVariable Long orderId) { - return Result.success(workOrderService.countByOrderId(orderId)); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalAlbumController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalAlbumController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalAlbumController.java -index 0d65e46..e8684ef 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalAlbumController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalAlbumController.java -@@ -16,7 +16,7 @@ import java.util.List; - /** - * 相册内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - */ --@Api(tags = "【内部接口】小程序相册(Feign调用)") -+@Api(tags = "【内部接口】小程序相册(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/album") - @RequiredArgsConstructor -@@ -24,13 +24,14 @@ public class InternalAlbumController { - - private final AlbumService albumService; - -- @ApiOperation("用户有相册的订单列表") -+ @ApiOperation(value = "用户有相册的订单列表", notes = "返回用户所有有相册文件夹的订单(含订单基本信息和相册封面),用于C端'我的相册'入口") - @GetMapping("/orders") - public Result> listAlbumOrders(@RequestParam Long userId) { - return Result.success(albumService.listUserAlbumOrders(userId)); - } - -- @ApiOperation("订单的文件夹列表") -+ @ApiOperation(value = "订单的文件夹列表", -+ notes = "内部服务间调用。返回指定用户指定订单下的相册文件夹列表,会校验订单归属权限。") - @GetMapping("/order/{orderId}/folders") - public Result> listFolders( - @RequestParam Long userId, -@@ -38,7 +39,10 @@ public class InternalAlbumController { - return Result.success(albumService.listUserFolders(userId, orderId)); - } - -- @ApiOperation("文件夹下的文件列表") -+ @ApiOperation(value = "文件夹下的文件列表", notes = "**关联字典**:\n" + -+ "- album_file_type(文件类型,返回字段fileType):IMAGE=图片, VIDEO=视频\n" + -+ "- album_location_type(地点类型,返回字段locationType):RESOURCE=关联资源, CUSTOM=自定义地点\n" + -+ "- resource_type(资源类型,返回字段resourceType):SCENIC_SPOT=景区, ACTIVITY=活动, RESTAURANT=餐厅, HOTEL=酒店, VEHICLE=车辆") - @GetMapping("/folder/{folderId}/files") - public Result> listFiles( - @RequestParam Long userId, -@@ -48,7 +52,7 @@ public class InternalAlbumController { - return Result.success(albumService.listUserFiles(userId, folderId, page, size)); - } - -- @ApiOperation("获取文件下载链接") -+ @ApiOperation(value = "获取文件下载链接", notes = "生成带签名的临时下载URL(有效期1小时),用于C端用户下载原图/视频") - @GetMapping("/file/{albumFileId}/download-url") - public Result getDownloadUrl( - @RequestParam Long userId, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalDashboardController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDashboardController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDashboardController.java -index 0fd0c6a..110daf9 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDashboardController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDashboardController.java -@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "【内部接口】工作台统计(Feign调用)") -+@Api(tags = "【内部接口】工作台统计(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/order/dashboard") - @RequiredArgsConstructor -@@ -19,7 +19,9 @@ public class InternalDashboardController { - - private final DashboardStatsService dashboardStatsService; - -- @ApiOperation("概览统计(支持定制师/全局,支持今日/本周/本月)") -+ @ApiOperation(value = "概览统计", notes = "返回订单量、成交金额、待处理订单数等概览数据。\n" + -+ "传customizerId则返回该定制师的数据,不传则返回全局数据。\n" + -+ "period支持: today(今日)、week(本周)、month(本月)") - @GetMapping("/overview-stats") - public Result> getOverviewStats( - @ApiParam("定制师ID,不传则为全局") @RequestParam(required = false) Long customizerId, -@@ -27,7 +29,9 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getOverviewStats(customizerId, period)); - } - -- @ApiOperation("待办分类汇总") -+ @ApiOperation(value = "待办分类汇总", notes = "按待办类型分组统计当前管理员的未完成待办数量,用于工作台待办卡片展示\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段中的待办类型key → 字典:order_todo_type(订单待办类型)") - @GetMapping("/todo-summary") - public Result> getTodoSummary( - @ApiParam("管理员ID") @RequestParam Long adminId, -@@ -35,7 +39,7 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getTodoSummary(adminId, roleKey)); - } - -- @ApiOperation("数据趋势(按天聚合)") -+ @ApiOperation(value = "数据趋势", notes = "按天聚合的订单量和金额趋势数据,用于折线图展示。支持最近7天或30天") - @GetMapping("/trend") - public Result>> getTrend( - @ApiParam("定制师ID,不传则为全局") @RequestParam(required = false) Long customizerId, -@@ -46,7 +50,9 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getTrend(customizerId, days)); - } - -- @ApiOperation("转化漏斗") -+ @ApiOperation(value = "转化漏斗", notes = "展示订单从创建→支付→确认→完成的转化率漏斗数据\n\n" + -+ "【关联字典】\n" + -+ "- 涉及字段 订单状态 → 字典:order_status(订单状态)") - @GetMapping("/funnel") - public Result> getFunnel( - @ApiParam("定制师ID,不传则为全局") @RequestParam(required = false) Long customizerId, -@@ -54,7 +60,10 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getFunnel(customizerId, period)); - } - -- @ApiOperation("即将出行列表") -+ @ApiOperation(value = "即将出行列表", notes = "返回最近即将出发的订单列表,按出发日期升序。用于工作台提醒关注即将出行的客户\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/upcoming-trips") - public Result>> getUpcomingTrips( - @ApiParam("定制师ID,不传则为全局") @RequestParam(required = false) Long customizerId, -@@ -62,14 +71,14 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getUpcomingTrips(customizerId, limit)); - } - -- @ApiOperation("业绩排行(本月定制师排名)") -+ @ApiOperation(value = "业绩排行", notes = "按定制师维度统计成交金额排名,支持本周/本月周期。用于工作台排行榜展示") - @GetMapping("/ranking") - public Result>> getRanking( - @ApiParam("时间范围: month/week") @RequestParam(defaultValue = "month") String period) { - return Result.success(dashboardStatsService.getRanking(period)); - } - -- @ApiOperation("日历事件") -+ @ApiOperation(value = "日历事件", notes = "返回指定月份的出发日期事件列表,用于工作台日历组件展示。每个事件包含订单基本信息") - @GetMapping("/calendar-events") - public Result>> getCalendarEvents( - @ApiParam("定制师ID") @RequestParam(required = false) Long customizerId, -@@ -78,14 +87,14 @@ public class InternalDashboardController { - return Result.success(dashboardStatsService.getCalendarEvents(customizerId, year, month)); - } - -- @ApiOperation("财务统计") -+ @ApiOperation(value = "财务统计", notes = "返回收入、成本、利润等财务汇总数据,支持按时间周期统计") - @GetMapping("/finance-stats") - public Result> getFinanceStats( - @ApiParam("时间范围") @RequestParam(defaultValue = "today") String period) { - return Result.success(dashboardStatsService.getFinanceStats(period)); - } - -- @ApiOperation("退款汇总") -+ @ApiOperation(value = "退款汇总", notes = "返回退款总额、退款笔数、退款率等汇总信息。传customizerId可查看单个定制师的退款数据") - @GetMapping("/refund-summary") - public Result> getRefundSummary( - @ApiParam("定制师ID") @RequestParam(required = false) Long customizerId) { -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalDesignerOrderController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDesignerOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDesignerOrderController.java -index bb7a01e..cd52e45 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDesignerOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalDesignerOrderController.java -@@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.*; - - import java.util.Map; - --@Api(tags = "【内部接口】定制师订单(Feign调用)") -+@Api(tags = "【内部接口】定制师订单(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/order") - @RequiredArgsConstructor -@@ -20,20 +20,29 @@ public class InternalDesignerOrderController { - - private final OrderService orderService; - -- @ApiOperation("获取定制师订单统计") -+ @ApiOperation(value = "获取定制师订单统计", notes = "返回指定定制师的订单统计数据(各状态数量、总金额等),用于定制师工作台概览\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段中的状态key → 字典:order_status(订单状态)") - @GetMapping("/designer-stats") - public Result> getDesignerOrderStats( - @ApiParam("定制师管理员ID") @RequestParam Long customizerId) { - return Result.success(orderService.getDesignerOrderStats(customizerId)); - } - -- @ApiOperation("获取全局订单统计") -+ @ApiOperation(value = "获取全局订单统计", notes = "返回全平台的订单统计数据(各状态数量、总金额等),用于管理层工作台概览\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段中的状态key → 字典:order_status(订单状态)") - @GetMapping("/global-stats") - public Result> getGlobalOrderStats() { - return Result.success(orderService.getGlobalOrderStats()); - } - -- @ApiOperation("定制师订单列表") -+ @ApiOperation(value = "定制师订单列表", notes = "分页查询指定定制师负责的订单,支持按状态和关键词筛选\n\n" + -+ "【关联字典】\n" + -+ "- 筛选参数 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/designer-list") - public Result> listDesignerOrders( - @ApiParam("定制师管理员ID") @RequestParam Long customizerId, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalEarlyBirdController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalEarlyBirdController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalEarlyBirdController.java -index 97b3871..b1bf9e7 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalEarlyBirdController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalEarlyBirdController.java -@@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.RestController; - import java.math.BigDecimal; - import java.util.List; - --@Api(tags = "【内部接口】早鸟优惠(Feign调用)") -+@Api(tags = "【内部接口】早鸟优惠(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/early-bird") - @RequiredArgsConstructor -@@ -23,14 +23,17 @@ public class InternalEarlyBirdController { - - private final EarlyBirdPlanService earlyBirdPlanService; - -- @ApiOperation("获取当前有效的早鸟优惠计划列表") -+ @ApiOperation(value = "获取当前有效的早鸟优惠计划列表", notes = "返回当前日期处于生效期内且已启用的早鸟计划,C端下单时展示可用优惠") - @GetMapping("/active") - public Result> listActivePlans() { - List plans = earlyBirdPlanService.listActivePlans(); - return Result.success(plans); - } - -- @ApiOperation("匹配最优早鸟优惠计划") -+ @ApiOperation(value = "匹配最优早鸟优惠计划", notes = "根据产品类型、出行人数、订单总价匹配优惠金额最大的早鸟计划。\n" + -+ "无匹配返回null。供下单时自动匹配调用\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 productType → 字典:product_type(产品类型)") - @GetMapping("/match") - public Result matchPlan( - @RequestParam String productType, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalInvoiceController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalInvoiceController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalInvoiceController.java -index e84a0e6..310b627 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalInvoiceController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalInvoiceController.java -@@ -15,7 +15,7 @@ import javax.validation.Valid; - * C端发票内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "【内部接口】小程序发票(Feign调用)") -+@Api(tags = "【内部接口】小程序发票(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/invoice") - @RequiredArgsConstructor -@@ -23,21 +23,33 @@ public class InternalInvoiceController { - - private final InvoiceService invoiceService; - -- @ApiOperation("申请开票") -+ @ApiOperation(value = "申请开票", notes = "用户对已支付订单申请开具电子发票。支持个人和企业抬头。\n" + -+ "同一订单只能开一次发票(可换开)\n\n" + -+ "**关联字典**:\n" + -+ "- invoice_title_type(抬头类型,请求/返回字段titleType):PERSONAL=个人, COMPANY=企业\n" + -+ "- invoice_type(发票类型,返回字段invoiceType):NORMAL=普通发票, SPECIAL=专用发票\n" + -+ "- invoice_status(发票状态,返回字段status):PENDING=待开票, ISSUED=已开票, FAILED=开票失败, CANCELLED=已作废") - @PostMapping("/apply") - public Result applyInvoice(@RequestParam Long userId, - @Valid @RequestBody InvoiceApplyRequest request) { - return Result.success(invoiceService.applyInvoice(userId, request)); - } - -- @ApiOperation("发票详情") -+ @ApiOperation(value = "发票详情", notes = "**关联字典**:\n" + -+ "- invoice_title_type(抬头类型,返回字段titleType):PERSONAL=个人, COMPANY=企业\n" + -+ "- invoice_type(发票类型,返回字段invoiceType):NORMAL=普通发票, SPECIAL=专用发票\n" + -+ "- invoice_status(发票状态,返回字段status):PENDING=待开票, ISSUED=已开票, FAILED=开票失败, CANCELLED=已作废") - @GetMapping("/{id}") - public Result getInvoiceDetail(@RequestParam Long userId, - @PathVariable Long id) { - return Result.success(invoiceService.getInvoiceDetail(userId, id)); - } - -- @ApiOperation("通过订单ID查询发票") -+ @ApiOperation(value = "通过订单ID查询发票", notes = "查询订单关联的发票信息。未开票时返回null\n\n" + -+ "**关联字典**:\n" + -+ "- invoice_title_type(抬头类型,返回字段titleType):PERSONAL=个人, COMPANY=企业\n" + -+ "- invoice_type(发票类型,返回字段invoiceType):NORMAL=普通发票, SPECIAL=专用发票\n" + -+ "- invoice_status(发票状态,返回字段status):PENDING=待开票, ISSUED=已开票, FAILED=开票失败, CANCELLED=已作废") - @GetMapping("/order/{orderId}") - public Result getInvoiceByOrderId(@RequestParam Long userId, - @PathVariable Long orderId) { -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpOrderController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpOrderController.java -index c27da3a..ec5f305 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpOrderController.java -@@ -24,7 +24,7 @@ import java.util.Map; - * C端订单内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "【内部接口】小程序订单(Feign调用)") -+@Api(tags = "【内部接口】小程序订单(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/order") - @RequiredArgsConstructor -@@ -32,7 +32,13 @@ public class InternalMpOrderController { - - private final OrderService orderService; - -- @ApiOperation("创建订单") -+ @ApiOperation(value = "创建订单", notes = "供BFF层调用的C端下单接口。创建后返回订单详情(含支付信息),前端可直接跳转支付\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 请求参数 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 请求参数 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @PostMapping("/create") - public Result createOrder(@RequestParam Long userId, - @Valid @RequestBody CreateOrderRequest request) { -@@ -41,21 +47,32 @@ public class InternalMpOrderController { - return Result.success(detail); - } - -- @ApiOperation("订单列表") -+ @ApiOperation(value = "订单列表", notes = "【关联字典】\n" + -+ "- 筛选参数 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/list") - public Result> listOrders(@RequestParam Long userId, - MpOrderQueryRequest query) { - return Result.success(orderService.listUserOrders(userId, query)); - } - -- @ApiOperation("订单详情") -+ @ApiOperation(value = "订单详情", notes = "【关联字典】\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)\n" + -+ "- 返回字段 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 返回字段 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 返回字段 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 timeline[].action → 字典:order_timeline_action(订单操作类型)") - @GetMapping("/{orderId}") - public Result getOrder(@RequestParam Long userId, - @PathVariable Long orderId) { - return Result.success(orderService.getUserOrderDetail(userId, orderId)); - } - -- @ApiOperation("取消订单") -+ @ApiOperation(value = "取消订单", -+ notes = "内部服务间调用,供BFF层调用的用户取消订单接口。仅允许取消待支付/已付定金状态的订单。") - @PostMapping("/{orderId}/cancel") - public Result cancelOrder(@RequestParam Long userId, - @PathVariable Long orderId, -@@ -65,7 +82,8 @@ public class InternalMpOrderController { - return Result.success(); - } - -- @ApiOperation("订单资源详情(按分类)") -+ @ApiOperation(value = "订单资源详情(按分类)", -+ notes = "内部服务间调用。解析订单的产品快照JSON,按资源类型分类提取资源详情(景区/酒店/活动/餐厅等),返回Map结构。") - @GetMapping("/{orderId}/resources") - public Result>>> getOrderResources( - @RequestParam Long userId, -@@ -73,7 +91,7 @@ public class InternalMpOrderController { - return Result.success(orderService.getOrderSnapshotResources(userId, orderId)); - } - -- @ApiOperation("通过联系人手机号+姓名查找订单(无需登录)") -+ @ApiOperation(value = "通过联系人手机号+姓名查找订单", notes = "无需登录。用于管理员代下单场景:管理员创建订单后用户通过手机号+姓名查找并绑定订单") - @GetMapping("/lookup") - public Result> lookupByContact( - @RequestParam String contactPhone, -@@ -81,7 +99,8 @@ public class InternalMpOrderController { - return Result.success(orderService.lookupByContact(contactPhone, contactName)); - } - -- @ApiOperation("绑定未绑定的订单(通过联系人手机号+姓名)") -+ @ApiOperation(value = "绑定未绑定的订单", notes = "将userId=NULL且联系人手机号+姓名匹配的订单绑定到当前用户。\n" + -+ "用于管理员代下单后用户登录自动关联订单。返回绑定的订单数量") - @PostMapping("/bind-by-contact") - public Result bindByContact(@RequestParam Long userId, - @Valid @RequestBody BindByContactRequest request) { -@@ -89,7 +108,7 @@ public class InternalMpOrderController { - return Result.success(bindCount); - } - -- @ApiOperation("客户同意解锁订单") -+ @ApiOperation(value = "客户同意解锁订单", notes = "管理员申请修改锁定订单后,C端用户确认同意解锁。解锁后管理员可重新编辑订单") - @PostMapping("/{orderId}/approve-unlock") - public Result approveUnlock(@RequestParam Long userId, - @PathVariable Long orderId) { -@@ -103,13 +122,16 @@ public class InternalMpOrderController { - return Result.success(orderService.getUpcomingDepartures(userId)); - } - -- @ApiOperation("各状态订单数量") -+ @ApiOperation(value = "各状态订单数量", notes = "返回用户各状态的订单数量Map,用于小程序订单页Tab角标显示\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段中的状态key → 字典:order_status(订单状态)") - @GetMapping("/count") - public Result> countByStatus(@RequestParam Long userId) { - return Result.success(orderService.countByStatusForUser(userId)); - } - -- @ApiOperation("标记订单已评价(评价服务回调)") -+ @ApiOperation(value = "标记订单已评价", notes = "评价服务(review-service)在用户发布评价后回调此接口,将订单标记为已评价。\n" + -+ "标记后订单详情不再显示'去评价'按钮") - @PutMapping("/{orderId}/mark-reviewed") - public Result markReviewed(@PathVariable Long orderId) { - orderService.markReviewed(orderId); -@@ -118,7 +140,13 @@ public class InternalMpOrderController { - - @ApiOperation(value = "用户修改订单", notes = "用户可修改出发日期和出行人,修改后重走内部流程(级联检测+价格重算)。" + - "仅待支付/已付定金/已支付/已确认/待付尾款/待出发状态可修改。" + -- "内部流程已启动的订单修改后会通知定制师,返回message中包含提示") -+ "内部流程已启动的订单修改后会通知定制师,返回message中包含提示\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 请求参数 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 请求参数 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @PutMapping("/{orderId}/edit") - public Result userEditOrder(@RequestParam Long userId, - @PathVariable Long orderId, -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpTripController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpTripController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpTripController.java -index db0d1cc..8e4b990 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpTripController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalMpTripController.java -@@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "【内部接口】小程序行程(Feign调用)") -+@Api(tags = "【内部接口】小程序行程(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/trip") - @RequiredArgsConstructor -@@ -18,20 +18,29 @@ public class InternalMpTripController { - - private final TripService tripService; - -- @ApiOperation("行程列表") -+ @ApiOperation(value = "行程列表", notes = "返回用户所有有效订单的行程概要列表(已确认/待出发/出行中/已完成),按出发日期排序\n\n" + -+ "**关联字典**:\n" + -+ "- order_status(订单状态,返回字段status):CONFIRMED=已确认, PENDING_DEPARTURE=待出发, TRAVELLING=出行中, COMPLETED=已完成\n" + -+ "- trip_phase(行程阶段,返回字段tripPhase):BEFORE_START=出发前, IN_PROGRESS=出行中, ENDED=已结束") - @GetMapping("/list") - public Result>> getTripList(@RequestParam Long userId) { - return Result.success(tripService.getTripList(userId)); - } - -- @ApiOperation("行程详情") -+ @ApiOperation(value = "行程详情", notes = "返回订单的完整行程信息,包括每日行程节点、酒店安排、车辆安排、天气预报等\n\n" + -+ "**关联字典**:\n" + -+ "- order_status(订单状态,返回字段status):CONFIRMED=已确认, PENDING_DEPARTURE=待出发, TRAVELLING=出行中, COMPLETED=已完成\n" + -+ "- trip_phase(行程阶段,返回字段tripPhase):BEFORE_START=出发前, IN_PROGRESS=出行中, ENDED=已结束") - @GetMapping("/{orderId}") - public Result> getTripDetail(@RequestParam Long userId, - @PathVariable Long orderId) { - return Result.success(tripService.getTripDetail(userId, orderId)); - } - -- @ApiOperation("今日行程") -+ @ApiOperation(value = "今日行程", notes = "返回用户今天的行程安排。如果今天有正在出行的订单,返回当天的行程节点和安排;否则返回null\n\n" + -+ "**关联字典**:\n" + -+ "- order_status(订单状态,返回字段status):CONFIRMED=已确认, PENDING_DEPARTURE=待出发, TRAVELLING=出行中, COMPLETED=已完成\n" + -+ "- trip_phase(行程阶段,返回字段tripPhase):BEFORE_START=出发前, IN_PROGRESS=出行中, ENDED=已结束") - @GetMapping("/today") - public Result> getTodayTrip(@RequestParam Long userId) { - Map trip = tripService.getTodayTrip(userId); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderStatsController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderStatsController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderStatsController.java -index 887cf27..38d3022 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderStatsController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderStatsController.java -@@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.*; - - import javax.validation.Valid; - --@Api(tags = "内部-订单统计") -+@Api(tags = "内部-订单统计", hidden = true) - @RestController - @RequestMapping("/internal/mp/order") - @RequiredArgsConstructor -@@ -21,19 +21,24 @@ public class InternalOrderStatsController { - private final OrderService orderService; - private final InvoiceService invoiceService; - -- @ApiOperation("获取产品已购出行人总数") -+ @ApiOperation(value = "获取产品已购出行人总数", notes = "统计指定产品的有效订单(非取消/非退款)出行人总数,用于产品详情页显示'已报名X人'") - @GetMapping("/product-sold-count") - public Result getProductSoldCount(@RequestParam Long productId) { - return Result.success(orderService.getProductSoldCount(productId)); - } - -- @ApiOperation("获取产品参与家庭数") -+ @ApiOperation(value = "获取产品参与家庭数", notes = "统计指定产品的有效订单数(一个订单视为一个家庭),用于产品详情页显示'已有X个家庭参与'") - @GetMapping("/participant-family-count") - public Result getParticipantFamilyCount(@RequestParam Long productId) { - return Result.success(orderService.getParticipantFamilyCount(productId)); - } - -- @ApiOperation("发票换开") -+ @ApiOperation(value = "发票换开", notes = "已开发票更换抬头信息(如个人改企业、更换公司名称等)。\n" + -+ "原发票作废,重新生成新发票\n\n" + -+ "**关联字典**:\n" + -+ "- invoice_title_type(抬头类型,请求/返回字段titleType):PERSONAL=个人, COMPANY=企业\n" + -+ "- invoice_type(发票类型,返回字段invoiceType):NORMAL=普通发票, SPECIAL=专用发票\n" + -+ "- invoice_status(发票状态,返回字段status):PENDING=待开票, ISSUED=已开票, FAILED=开票失败, CANCELLED=已作废") - @PostMapping("/invoice/reissue") - public Result reissueInvoice(@RequestBody @Valid InvoiceReissueRequest request) { - return Result.success(invoiceService.reissueInvoice(request)); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderTravelerController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderTravelerController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderTravelerController.java -index 2b39654..656382a 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderTravelerController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalOrderTravelerController.java -@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.*; - /** - * Internal API for payment service - 出行人验证 - */ --@Api(tags = "【内部接口】订单出行人(Feign调用)") -+@Api(tags = "【内部接口】订单出行人(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/order/traveler") - @RequiredArgsConstructor -@@ -19,7 +19,11 @@ public class InternalOrderTravelerController { - - private final OrderTravelerService orderTravelerService; - -- @ApiOperation("验证订单出行人信息(供支付服务调用)") -+ @ApiOperation(value = "验证订单出行人信息", notes = "供支付服务在发起支付前调用。验证出行人数量是否满足订单要求、证件信息是否完整。\n" + -+ "返回验证结果,包含是否通过和具体错误信息列表\n\n" + -+ "【关联字典】\n" + -+ "- 涉及字段 出行人证件类型 → 字典:id_card_type(证件类型)\n" + -+ "- 涉及字段 出行人类型 → 字典:traveler_type(出行人类型)") - @GetMapping("/validate/{orderId}") - public Result validateTravelers(@PathVariable Long orderId) { - TravelerValidationDTO validation = orderTravelerService.validateTravelers(orderId); -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalPaymentOrderController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalPaymentOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalPaymentOrderController.java -index b708e85..be4a57c 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalPaymentOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalPaymentOrderController.java -@@ -21,7 +21,7 @@ import java.util.stream.Collectors; - * Internal endpoints for payment-service to call via Feign. - * Not exposed through gateway, no authentication interceptor. - */ --@Api(tags = "【内部接口】订单-支付/合同/保险(Feign调用)") -+@Api(tags = "【内部接口】订单-支付/合同/保险(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/order") - @RequiredArgsConstructor -@@ -30,13 +30,16 @@ public class InternalPaymentOrderController { - private final OrderService orderService; - private final OrderTodoService orderTodoService; - -- @ApiOperation("获取订单支付信息") -+ @ApiOperation(value = "获取订单支付信息", notes = "供支付服务调用。返回订单号、应付金额、定金金额、已付金额等支付所需信息") - @GetMapping("/{orderId}/pay-info") - public Result getPayInfo(@PathVariable Long orderId) { - return Result.success(orderService.getPayInfo(orderId)); - } - -- @ApiOperation("通知支付成功") -+ @ApiOperation(value = "通知支付成功", notes = "支付服务收到微信支付回调后调用。更新订单状态(PENDING_PAY→DEPOSIT_PAID/PAID)和已付金额。\n" + -+ "幂等处理:重复调用不会重复更新\n\n" + -+ "【关联字典】\n" + -+ "- 涉及字段 订单status → 字典:order_status(订单状态)") - @PostMapping("/payment-result") - public Result notifyPaymentResult(@RequestBody PaymentResultDTO dto) { - orderService.handlePaymentSuccess(dto.getOrderId(), dto.getPayType(), -@@ -44,14 +47,16 @@ public class InternalPaymentOrderController { - return Result.success(); - } - -- @ApiOperation("通知退款成功") -+ @ApiOperation(value = "通知退款成功", notes = "支付服务收到微信退款回调后调用。更新订单已退金额,若全额退款则将订单状态改为已退款(REFUNDED)") - @PostMapping("/refund-result") - public Result notifyRefundResult(@RequestBody RefundResultDTO dto) { - orderService.handleRefundSuccess(dto.getOrderId(), dto.getRefundAmount()); - return Result.success(); - } - -- @ApiOperation("获取订单基本信息(供合同服务调用)") -+ @ApiOperation(value = "获取订单基本信息(供合同服务调用)", notes = "【关联字典】\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/{orderId}/basic") - public Result> getOrderBasic(@PathVariable Long orderId) { - OrderInfo order = orderService.getById(orderId); -@@ -80,7 +85,8 @@ public class InternalPaymentOrderController { - return Result.success(data); - } - -- @ApiOperation("获取用户订单ID列表(供合同服务调用)") -+ @ApiOperation(value = "获取用户订单ID列表(供合同服务调用)", -+ notes = "内部服务间调用。返回指定用户的所有订单ID列表,供合同服务查询用户关联合同时使用。") - @GetMapping("/ids-by-user") - public Result> getOrderIdsByUser(@RequestParam Long userId) { - List orders = orderService.list( -@@ -94,7 +100,8 @@ public class InternalPaymentOrderController { - return Result.success(ids); - } - -- @ApiOperation("完成待办项(供合同/保险服务调用)") -+ @ApiOperation(value = "完成待办项(供合同/保险服务调用)", -+ notes = "内部服务间调用。合同服务签约完成或保险服务投保完成后调用此接口,将对应待办标记为已完成。系统自动检查是否所有必要待办已完成并推进内部流程。") - @PostMapping("/{orderId}/complete-todo/{todoType}") - public Result completeTodoByType(@PathVariable Long orderId, - @PathVariable String todoType) { -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/InternalRefundController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalRefundController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalRefundController.java -index 2464f08..f7c334f 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/InternalRefundController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/InternalRefundController.java -@@ -17,7 +17,7 @@ import org.springframework.web.bind.annotation.*; - import javax.validation.Valid; - import java.util.List; - --@Api(tags = "【内部接口】退款(Feign调用)") -+@Api(tags = "【内部接口】退款(Feign调用)", hidden = true) - @RestController - @RequiredArgsConstructor - public class InternalRefundController { -@@ -27,20 +27,26 @@ public class InternalRefundController { - - // ==================== C-end (BFF → order-service) ==================== - -- @ApiOperation(value = "退款金额预览", notes = "退款预览:根据退款政策和距出发天数,计算可退金额和退款比例") -+ @ApiOperation(value = "退款金额预览", notes = "退款预览:根据退款政策和距出发天数,计算可退金额和退款比例\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 refundType → 字典:refund_type(退款类型)") - @GetMapping("/internal/mp/order/{orderId}/refund-preview") - public Result preview(@RequestParam("userId") Long userId, - @PathVariable Long orderId) { - return Result.success(refundApplicationService.previewRefund(orderId, userId)); - } - -- @ApiOperation("退款原因列表") -+ @ApiOperation(value = "退款原因列表(C端)", notes = "返回启用中的退款原因选项,供C端用户申请退款时选择\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 category → 字典:refund_reason_category(退款原因分类)") - @GetMapping("/internal/mp/order/refund-reasons") - public Result> listReasons() { - return Result.success(refundReasonService.listReasons(true)); - } - -- @ApiOperation(value = "提交退款申请", notes = "退款申请流程:用户选择退款原因 → 填写退款说明 → 系统根据退款政策计算可退金额 → 生成退款申请(PENDING状态) → 等待管理员审批") -+ @ApiOperation(value = "提交退款申请", notes = "退款申请流程:用户选择退款原因 → 填写退款说明 → 系统根据退款政策计算可退金额 → 生成退款申请(PENDING状态) → 等待管理员审批\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @PostMapping("/internal/mp/order/{orderId}/refund") - public Result apply(@RequestParam("userId") Long userId, - @RequestParam(value = "userName", required = false) String userName, -@@ -49,14 +55,18 @@ public class InternalRefundController { - return Result.success(refundApplicationService.apply(orderId, userId, userName, request)); - } - -- @ApiOperation("退款申请详情") -+ @ApiOperation(value = "退款申请详情(C端)", notes = "返回退款申请信息,仅允许查看自己的退款申请\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @GetMapping("/internal/mp/order/refund/{applicationId}") - public Result getDetail(@RequestParam("userId") Long userId, - @PathVariable Long applicationId) { - return Result.success(refundApplicationService.getDetailForUser(applicationId, userId)); - } - -- @ApiOperation("根据订单ID获取最新退款申请详情") -+ @ApiOperation(value = "根据订单ID获取最新退款申请", notes = "返回订单关联的最新一条退款申请,用于订单详情页展示退款进度。无退款申请时返回null\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:refund_status(退款状态)") - @GetMapping("/internal/mp/order/{orderId}/refund-detail") - public Result getDetailByOrder(@RequestParam("userId") Long userId, - @PathVariable Long orderId) { -@@ -72,7 +82,7 @@ public class InternalRefundController { - return Result.success(refundApplicationService.appeal(applicationId, userId, request)); - } - -- @ApiOperation("撤回退款申请") -+ @ApiOperation(value = "撤回退款申请", notes = "用户主动撤回退款申请。仅在待审批(PENDING)状态下可撤回。撤回后订单恢复原状态") - @PostMapping("/internal/mp/order/refund/{applicationId}/cancel") - public Result cancel(@RequestParam("userId") Long userId, - @PathVariable Long applicationId) { -@@ -82,16 +92,18 @@ public class InternalRefundController { - - // ==================== Approval callback ==================== - -- @ApiOperation("企微退款申诉审批结果回调") -+ @ApiOperation(value = "企微退款申诉审批结果回调", notes = "企微OA审批完成后由callback-service调用。\n" + -+ "审批通过则退款申请状态变为APPEAL_APPROVED,等待管理员确认实退金额后执行退款") - @PostMapping("/internal/order/refund-appeal-result") -- public Result handleRefundAppealResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleRefundAppealResult(@RequestBody ApprovalResultDTO dto) { - refundApplicationService.handleAppealResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); - } - -- @ApiOperation("企微退款申请审批结果回调") -+ @ApiOperation(value = "企微退款申请审批结果回调", notes = "企微OA审批完成后由callback-service调用。\n" + -+ "审批通过则自动执行微信退款,审批拒绝则退款申请状态变为REJECTED") - @PostMapping("/internal/order/refund-application-result") -- public Result handleRefundApplicationResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleRefundApplicationResult(@RequestBody ApprovalResultDTO dto) { - refundApplicationService.handleApplicationApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); - } -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/MpOrderController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/MpOrderController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/MpOrderController.java -index f29e8f9..9b3806e 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/MpOrderController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/MpOrderController.java -@@ -35,7 +35,13 @@ public class MpOrderController { - private static final String ORDER_CREATE_DEDUP = "order:create:dedup:"; - - @ApiOperation(value = "创建订单", notes = "C端下单流程:选择产品 → 填写联系人信息和出行人 → 系统报价 → 生成订单(PENDING_PAY状态)\n\n" + -- "联系人和出行人是独立概念,联系人不必是出行人之一") -+ "联系人和出行人是独立概念,联系人不必是出行人之一\n\n" + -+ "【关联字典】\n" + -+ "- 请求参数 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 请求参数 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 请求参数 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @PostMapping("/create") - public Result createOrder(HttpServletRequest request, - @ApiParam("创建订单请求") @Valid @RequestBody CreateOrderRequest createRequest) { -@@ -55,7 +61,12 @@ public class MpOrderController { - } - } - -- @ApiOperation("我的订单列表") -+ @ApiOperation(value = "我的订单列表", notes = "查询当前用户的订单列表,支持按状态筛选。\n" + -+ "用户需先完善个人资料(realName)后才能看到订单\n\n" + -+ "【关联字典】\n" + -+ "- 筛选参数 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)") - @GetMapping("/list") - public Result> listOrders(HttpServletRequest request, - @ApiParam("订单查询请求") MpOrderQueryRequest queryRequest) { -@@ -64,7 +75,15 @@ public class MpOrderController { - return Result.success(result); - } - -- @ApiOperation("订单详情") -+ @ApiOperation(value = "订单详情", notes = "获取订单完整信息。仅能查看自己的订单,查看他人订单会返回权限错误\n\n" + -+ "【关联字典】\n" + -+ "- 返回字段 status → 字典:order_status(订单状态)\n" + -+ "- 返回字段 processStatus → 字典:order_process_status(订单内部流程状态)\n" + -+ "- 返回字段 productType → 字典:product_type(产品类型)\n" + -+ "- 返回字段 travelers[].travelerType → 字典:traveler_type(出行人类型)\n" + -+ "- 返回字段 travelers[].idCardType → 字典:id_card_type(证件类型)\n" + -+ "- 返回字段 travelers[].gender → 字典:gender(性别)\n" + -+ "- 返回字段 timeline[].action → 字典:order_timeline_action(订单操作类型)") - @GetMapping("/{orderId}") - public Result getOrder(HttpServletRequest request, - @ApiParam("订单ID") @PathVariable Long orderId) { -``` - -### `hl-order-service/src/main/java/com/hulalv/order/controller/MpWeatherController.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/controller/MpWeatherController.java b/hl-order-service/src/main/java/com/hulalv/order/controller/MpWeatherController.java -index 9e92157..1df079f 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/controller/MpWeatherController.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/controller/MpWeatherController.java -@@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "内部天气接口(Feign)") -+@Api(tags = "内部天气接口(Feign)", hidden = true) - @RestController - @RequestMapping("/internal/mp/weather") - @RequiredArgsConstructor -@@ -20,21 +20,21 @@ public class MpWeatherController { - - private final WeatherService weatherService; - -- @ApiOperation("获取订单行程天气") -+ @ApiOperation(value = "获取订单行程天气", notes = "根据订单行程中的城市和日期,批量查询天气信息。返回每天每个城市的天气数据列表") - @GetMapping("/itinerary/{orderId}") - public Result>> getItineraryWeather( - @ApiParam("订单ID") @PathVariable Long orderId) { - return Result.success(weatherService.getItineraryWeather(orderId)); - } - -- @ApiOperation("获取指定城市实况天气") -+ @ApiOperation(value = "获取指定城市实况天气", notes = "调用高德天气API查询城市实时天气(温度、湿度、风向等),结果缓存30分钟") - @GetMapping("/live") - public Result getLiveWeather( - @ApiParam("城市名称") @RequestParam String city) { - return Result.success(weatherService.getLiveWeather(city)); - } - -- @ApiOperation("获取指定城市天气预报") -+ @ApiOperation(value = "获取指定城市天气预报", notes = "调用高德天气API查询城市未来3天天气预报,结果缓存2小时") - @GetMapping("/forecast") - public Result getForecastWeather( - @ApiParam("城市名称") @RequestParam String city) { -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/AdminCreateOrderRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminCreateOrderRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminCreateOrderRequest.java -index 8fb0223..48d0a18 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminCreateOrderRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminCreateOrderRequest.java -@@ -35,7 +35,7 @@ public class AdminCreateOrderRequest { - @Min(value = 0) - private int babyCount = 0; - -- @ApiModelProperty(value = "儿童是否需要床位", example = "false") -+ @ApiModelProperty(value = "儿童是否需要床位(影响房间分配和报价计算)", example = "false") - private Boolean childNeedBed = false; - - @ApiModelProperty(value = "团期ID(GROUP产品必填)") -@@ -59,14 +59,14 @@ public class AdminCreateOrderRequest { - @Size(max = 500, message = "备注不能超过500个字符") - private String remark; - -- @ApiModelProperty(value = "用户手机号(可选,用于关联C端用户)", example = "13800138000") -+ @ApiModelProperty(value = "用户手机号(可选,用于关联C端用户)。如匹配到已注册用户则自动绑定订单", example = "13800138000") - @Size(max = 20) - private String userPhone; - - @ApiModelProperty(value = "定制师ID(可选,默认为创建人)", example = "1760000000000010") - private Long customizerId; - -- @ApiModelProperty(value = "支付时限(分钟),不传则使用全局默认值", example = "30") -+ @ApiModelProperty(value = "支付时限(分钟),不传则使用全局默认值。超时未支付订单自动取消", example = "30") - @Min(value = 1, message = "支付时限最少1分钟") - @Max(value = 1440, message = "支付时限最多1440分钟") - private Integer expiryMinutes; -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/AdminRefundReviewRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminRefundReviewRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminRefundReviewRequest.java -index dfdbe7d..3eb5db1 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminRefundReviewRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminRefundReviewRequest.java -@@ -11,11 +11,11 @@ import java.math.BigDecimal; - @Data - @ApiModel("管理员退款审批请求") - public class AdminRefundReviewRequest { -- @ApiModelProperty(value = "审批结果(APPROVE/REJECT)", required = true, example = "APPROVE") -+ @ApiModelProperty(value = "审批结果:APPROVE=通过(自动调起微信退款)、REJECT=拒绝(用户可发起申诉)", required = true, example = "APPROVE") - @NotBlank(message = "审批结果不能为空") - private String action; - -- @ApiModelProperty(value = "实际退款金额(审批通过时可调整)", example = "1500.00") -+ @ApiModelProperty(value = "实际退款金额(审批通过时可调整,不传则使用申请金额)。不能超过订单已付金额", example = "1500.00") - private BigDecimal actualAmount; - - @ApiModelProperty(value = "审批备注", example = "同意全额退款") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/AdminUpdateOrderRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminUpdateOrderRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminUpdateOrderRequest.java -index 2d1c10e..44a424e 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/AdminUpdateOrderRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/AdminUpdateOrderRequest.java -@@ -44,7 +44,7 @@ public class AdminUpdateOrderRequest { - @Min(value = 0, message = "幼童数不能为负") - private Integer babyCount; - -- @ApiModelProperty(value = "商户号", example = "1246532201") -+ @ApiModelProperty(value = "商户号(微信支付商户号,多商户场景使用)", example = "1246532201") - @Size(max = 32, message = "商户号不能超过32个字符") - private String mchId; - -@@ -62,6 +62,6 @@ public class AdminUpdateOrderRequest { - - // Note: discount is now managed via separate discount CRUD endpoints (POST/PUT/DELETE /admin/order/{orderId}/discount) - -- @ApiModelProperty(value = "出行人列表(如提供则替换全部出行人)") -+ @ApiModelProperty(value = "出行人列表(如提供则替换全部出行人,不传则不修改出行人)") - private List travelers; - } -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/CreateWorkOrderRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/CreateWorkOrderRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/CreateWorkOrderRequest.java -index aeb8c8c..b984863 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/CreateWorkOrderRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/CreateWorkOrderRequest.java -@@ -13,11 +13,12 @@ public class CreateWorkOrderRequest { - @NotNull(message = "订单ID不能为空") - private Long orderId; - -- @ApiModelProperty(value = "工单类型: ROOM_CHANGE/ROOM_ADD/CHECKOUT_CHANGE/HOTEL_ISSUE/VEHICLE_CHANGE/SCENIC_ADD/SCENIC_REMOVE/OTHER", required = true) -+ @ApiModelProperty(value = "工单类型: ROOM_CHANGE(换房)/ROOM_ADD(加房)/CHECKOUT_CHANGE(改退房日期)/" + -+ "HOTEL_ISSUE(酒店问题)/VEHICLE_CHANGE(换车)/SCENIC_ADD(加景点)/SCENIC_REMOVE(减景点)/OTHER(其他)", required = true) - @NotBlank(message = "工单类型不能为空") - private String type; - -- @ApiModelProperty(value = "优先级: URGENT/NORMAL", required = true) -+ @ApiModelProperty(value = "优先级: URGENT(紧急,如当天出发需处理)/NORMAL(普通)", required = true) - @NotBlank(message = "优先级不能为空") - private String priority; - -@@ -31,7 +32,7 @@ public class CreateWorkOrderRequest { - @ApiModelProperty("资源详情JSON(酒店/车辆/景点信息)") - private String resourceDetail; - -- @ApiModelProperty("差价(正数=加价, 负数=退费)") -+ @ApiModelProperty("差价(正数=客户需补差价, 负数=需退费给客户)") - private BigDecimal costDifference; - - @ApiModelProperty("指定处理人ID") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/EarlyBirdPlanRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/EarlyBirdPlanRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/EarlyBirdPlanRequest.java -index f2f451c..a678aff 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/EarlyBirdPlanRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/EarlyBirdPlanRequest.java -@@ -24,12 +24,12 @@ public class EarlyBirdPlanRequest { - @NotNull(message = "生效结束日期不能为空") - private LocalDate endDate; - -- @ApiModelProperty(value = "最低人数", required = true, example = "2") -+ @ApiModelProperty(value = "最低出行人数(含成人+儿童),订单人数>=此值才能享受优惠", required = true, example = "2") - @NotNull(message = "最低人数不能为空") - @Min(value = 1, message = "最低人数至少为1") - private Integer minPeople; - -- @ApiModelProperty(value = "优惠金额", required = true, example = "200.00") -+ @ApiModelProperty(value = "优惠金额(从订单总价中扣减的固定金额)", required = true, example = "200.00") - @NotNull(message = "优惠金额不能为空") - @DecimalMin(value = "0.01", message = "优惠金额必须大于0") - private BigDecimal discountAmount; -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/InvoiceApplyRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/InvoiceApplyRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/InvoiceApplyRequest.java -index 125cd6a..9a93336 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/InvoiceApplyRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/InvoiceApplyRequest.java -@@ -13,7 +13,7 @@ public class InvoiceApplyRequest { - @NotNull(message = "orderId is required") - private Long orderId; - -- @ApiModelProperty(value = "抬头类型(personal=个人/company=企业)", example = "personal") -+ @ApiModelProperty(value = "抬头类型:personal=个人(默认)、company=企业(需填写税号)", example = "personal") - private String titleType = "personal"; - - @ApiModelProperty(value = "发票抬头", required = true, example = "张三") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/MpOrderQueryRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/MpOrderQueryRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/MpOrderQueryRequest.java -index 98b28d5..c28453b 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/MpOrderQueryRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/MpOrderQueryRequest.java -@@ -10,7 +10,7 @@ import javax.validation.constraints.Min; - @Data - @ApiModel("C端订单查询请求") - public class MpOrderQueryRequest { -- @ApiModelProperty(value = "订单状态", example = "PAID") -+ @ApiModelProperty(value = "订单状态(不传则查全部)。可选值:PENDING_PAY/DEPOSIT_PAID/PAID/CONFIRMED/PENDING_BALANCE/PENDING_DEPARTURE/TRAVELLING/COMPLETED/AFTER_SALE/REFUNDING/REFUNDED/CANCELLED", example = "PAID") - private String status; - - @ApiModelProperty(value = "页码", example = "1") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/MpUpdateOrderRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/MpUpdateOrderRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/MpUpdateOrderRequest.java -index 9782f64..0b13f71 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/MpUpdateOrderRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/MpUpdateOrderRequest.java -@@ -9,12 +9,12 @@ import java.time.LocalDate; - import java.util.List; - - @Data --@ApiModel("小程序修改订单请求") -+@ApiModel(value = "小程序修改订单请求", description = "用户可修改出发日期和出行人。修改后系统自动重算价格,内部流程已启动的订单会通知定制师") - public class MpUpdateOrderRequest { - -- @ApiModelProperty(value = "出发日期", example = "2026-05-01") -+ @ApiModelProperty(value = "出发日期(修改出发日期会触发价格重算)", example = "2026-05-01") - private LocalDate departureDate; - -- @ApiModelProperty(value = "出行人列表(如提供则替换全部出行人)") -+ @ApiModelProperty(value = "出行人列表(如提供则替换全部出行人,不传则不修改出行人)") - private List travelers; - } -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/RefundApplyRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/RefundApplyRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/RefundApplyRequest.java -index 4d8aa75..7c32a24 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/RefundApplyRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/RefundApplyRequest.java -@@ -11,11 +11,11 @@ import javax.validation.constraints.Size; - @Data - @ApiModel("退款申请请求") - public class RefundApplyRequest { -- @ApiModelProperty(value = "退款类型(字典:refund_type)", required = true, example = "FULL") -+ @ApiModelProperty(value = "退款类型:FULL=全额退款、PARTIAL=部分退款", required = true, example = "FULL") - @NotBlank(message = "退款类型不能为空") - private String refundType; - -- @ApiModelProperty(value = "退款原因ID", example = "1760000000000001") -+ @ApiModelProperty(value = "退款原因ID(从退款原因列表接口获取)", example = "1760000000000001") - private Long reasonId; - - @ApiModelProperty(value = "退款原因", required = true, example = "行程有变,无法出行") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/RefundPolicyRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/RefundPolicyRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/RefundPolicyRequest.java -index cb0873c..a6a18a7 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/RefundPolicyRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/RefundPolicyRequest.java -@@ -42,12 +42,12 @@ public class RefundPolicyRequest { - @Data - @ApiModel("退款规则项") - public static class RuleItem { -- @ApiModelProperty(value = "距出发最少天数", required = true, example = "7") -+ @ApiModelProperty(value = "距出发最少天数(含当天)。例如:minDays=7表示出发前7天及以上适用此规则", required = true, example = "7") - @NotNull(message = "最少天数不能为空") - @Min(value = 0, message = "最少天数不能小于0") - private Integer minDays; - -- @ApiModelProperty(value = "退款比例(百分比)", required = true, example = "80") -+ @ApiModelProperty(value = "退款比例(百分比,0-100)。例如:80表示退已付金额的80%", required = true, example = "80") - @NotNull(message = "退款比例不能为空") - @Min(value = 0, message = "退款比例不能小于0") - @Max(value = 100, message = "退款比例不能超过100") -``` - -### `hl-order-service/src/main/java/com/hulalv/order/dto/UpdateOrderStatusRequest.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/dto/UpdateOrderStatusRequest.java b/hl-order-service/src/main/java/com/hulalv/order/dto/UpdateOrderStatusRequest.java -index f290109..c40fb91 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/dto/UpdateOrderStatusRequest.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/dto/UpdateOrderStatusRequest.java -@@ -9,7 +9,10 @@ import javax.validation.constraints.NotBlank; - @Data - @ApiModel("更新订单状态请求") - public class UpdateOrderStatusRequest { -- @ApiModelProperty(value = "目标状态(字典:order_status)", required = true, example = "CONFIRMED") -+ @ApiModelProperty(value = "目标状态。可选值:PENDING_PAY(待支付)/DEPOSIT_PAID(已付定金)/PAID(已全额支付)/" + -+ "CONFIRMED(已确认)/PENDING_BALANCE(待付尾款)/PENDING_DEPARTURE(待出行)/" + -+ "TRAVELLING(旅行中)/COMPLETED(已完成)/AFTER_SALE(售后中)/REFUNDING(退款中)/" + -+ "REFUNDED(已退款)/CANCELLED(已取消)", required = true, example = "CONFIRMED") - @NotBlank(message = "状态不能为空") - private String status; - } -``` - -### `hl-order-service/src/main/java/com/hulalv/order/service/WeatherService.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/service/WeatherService.java b/hl-order-service/src/main/java/com/hulalv/order/service/WeatherService.java -index 74d4a55..f5b652e 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/service/WeatherService.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/service/WeatherService.java -@@ -127,7 +127,11 @@ public class WeatherService { - * 获取指定城市的天气预报(带缓存) - */ - public WeatherInfo getCachedForecast(String cityName) { -- if (!StringUtils.hasText(cityName) || !StringUtils.hasText(amapKey)) { -+ if (!StringUtils.hasText(amapKey)) { -+ log.error("天气服务未配置: amap.key为空"); -+ return null; -+ } -+ if (!StringUtils.hasText(cityName)) { - return null; - } - String cacheKey = WEATHER_CACHE_PREFIX + cityName; -@@ -141,7 +145,10 @@ public class WeatherService { - } - - String adcode = getCachedAdcode(cityName); -- if (adcode == null) return null; -+ if (adcode == null) { -+ log.warn("无法获取城市adcode: city={}, 可能是城市名不正确或API Key无效", cityName); -+ return null; -+ } - - WeatherInfo weather = amapWeatherClient.getForecastWeather(adcode, amapKey); - if (weather != null) { -``` - -### `hl-order-service/src/main/java/com/hulalv/order/vo/WorkOrderVO.java` (M) - -```diff -diff --git a/hl-order-service/src/main/java/com/hulalv/order/vo/WorkOrderVO.java b/hl-order-service/src/main/java/com/hulalv/order/vo/WorkOrderVO.java -index 58106e0..f6bcd64 100644 ---- a/hl-order-service/src/main/java/com/hulalv/order/vo/WorkOrderVO.java -+++ b/hl-order-service/src/main/java/com/hulalv/order/vo/WorkOrderVO.java -@@ -82,12 +82,24 @@ public class WorkOrderVO { - private List logs; - - @Data -+ @io.swagger.annotations.ApiModel("工单操作日志VO") - public static class WorkOrderLogVO { -+ @ApiModelProperty("日志ID") - private String logId; -+ -+ @ApiModelProperty("操作动作") - private String action; -+ -+ @ApiModelProperty("操作动作标签") - private String actionLabel; -+ -+ @ApiModelProperty("操作内容") - private String content; -+ -+ @ApiModelProperty("操作人姓名") - private String operatorName; -+ -+ @ApiModelProperty("操作时间") - private LocalDateTime createdAt; - } - } -``` - -### `hl-payment-service/src/main/java/com/hulalv/payment/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-payment-service/src/main/java/com/hulalv/payment/config/Knife4jConfig.java b/hl-payment-service/src/main/java/com/hulalv/payment/config/Knife4jConfig.java -index 35ae74b..be0e684 100644 ---- a/hl-payment-service/src/main/java/com/hulalv/payment/config/Knife4jConfig.java -+++ b/hl-payment-service/src/main/java/com/hulalv/payment/config/Knife4jConfig.java -@@ -1,9 +1,9 @@ - package com.hulalv.payment.config; - -+import com.google.common.base.Predicate; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import springfox.documentation.builders.ApiInfoBuilder; --import springfox.documentation.builders.PathSelectors; - import springfox.documentation.builders.RequestHandlerSelectors; - import springfox.documentation.spi.DocumentationType; - import springfox.documentation.spring.web.plugins.Docket; -@@ -11,6 +11,11 @@ import springfox.documentation.spring.web.plugins.Docket; - @Configuration - public class Knife4jConfig { - -+ /** 排除内部接口和回调接口路径 */ -+ private Predicate adminPaths() { -+ return input -> input != null && !input.contains("/internal/") && !input.contains("/callback/"); -+ } -+ - @Bean - public Docket paymentApi() { - return new Docket(DocumentationType.SWAGGER_2) -@@ -22,7 +27,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.payment.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - } -``` - -### `hl-payment-service/src/main/java/com/hulalv/payment/controller/AdminPaymentController.java` (M) - -```diff -diff --git a/hl-payment-service/src/main/java/com/hulalv/payment/controller/AdminPaymentController.java b/hl-payment-service/src/main/java/com/hulalv/payment/controller/AdminPaymentController.java -index 3392e72..10a9ea4 100644 ---- a/hl-payment-service/src/main/java/com/hulalv/payment/controller/AdminPaymentController.java -+++ b/hl-payment-service/src/main/java/com/hulalv/payment/controller/AdminPaymentController.java -@@ -27,13 +27,13 @@ public class AdminPaymentController { - private final RefundService refundService; - - @GetMapping("/list") -- @ApiOperation(value = "支付交易列表", notes = "分页查询支付交易记录,支持按订单号、交易状态、交易类型筛选") -+ @ApiOperation(value = "支付交易列表", notes = "分页查询支付交易记录,支持按订单号、交易状态、交易类型筛选\n\n**关联字典**:\n- payment_mode:支付模式(列表筛选+显示)") - public Result> listTransactions(@ApiParam("支付查询条件") @Valid PaymentQueryRequest request) { - return Result.success(paymentService.listTransactions(request)); - } - - @GetMapping("/{transactionId}") -- @ApiOperation(value = "交易详情", notes = "获取单笔交易的完整信息,包含微信支付流水号") -+ @ApiOperation(value = "交易详情", notes = "获取单笔交易的完整信息,包含微信支付流水号\n\n**关联字典**:\n- payment_mode:支付模式(显示)") - public Result getDetail(@ApiParam("交易ID") @PathVariable Long transactionId) { - return Result.success(paymentService.getDetail(transactionId)); - } -``` - -### `hl-payment-service/src/main/java/com/hulalv/payment/controller/InternalPaymentController.java` (M) - -```diff -diff --git a/hl-payment-service/src/main/java/com/hulalv/payment/controller/InternalPaymentController.java b/hl-payment-service/src/main/java/com/hulalv/payment/controller/InternalPaymentController.java -index d195a48..dbdfc84 100644 ---- a/hl-payment-service/src/main/java/com/hulalv/payment/controller/InternalPaymentController.java -+++ b/hl-payment-service/src/main/java/com/hulalv/payment/controller/InternalPaymentController.java -@@ -25,14 +25,14 @@ import java.util.List; - @RestController - @RequestMapping("/internal/payment") - @RequiredArgsConstructor --@Api(tags = "【内部接口】支付(Feign调用)") -+@Api(tags = "【内部接口】支付(Feign调用)", hidden = true) - public class InternalPaymentController { - - private final PaymentService paymentService; - private final RefundService refundService; - - @PostMapping("/prepay") -- @ApiOperation("Create prepay order (called by BFF)") -+ @ApiOperation(value = "创建预支付订单", notes = "由BFF层调用,向微信支付API发起预支付请求,返回前端调起支付所需的参数(prepay_id等)") - public Result prepay( - @RequestParam("userId") Long userId, - @Valid @RequestBody PrepayRequest request) { -@@ -41,7 +41,7 @@ public class InternalPaymentController { - } - - @GetMapping("/status/{orderId}") -- @ApiOperation("Query payment status (called by BFF)") -+ @ApiOperation(value = "查询支付状态", notes = "查询订单的支付状态,含用户权限校验(userId不匹配时拒绝访问)\n\n**关联字典**:\n- payment_status:支付状态(返回字段)") - public Result getStatus(@RequestParam(value = "userId", required = false) Long userId, - @PathVariable Long orderId) { - PaymentVO vo = paymentService.getPaymentStatus(orderId); -@@ -53,7 +53,7 @@ public class InternalPaymentController { - } - - @GetMapping("/transactions/{orderId}") -- @ApiOperation("List all transactions for an order (called by BFF)") -+ @ApiOperation(value = "订单交易记录列表", notes = "查询指定订单的所有支付交易记录(含支付和退款),含用户权限校验\n\n**关联字典**:\n- payment_status:支付状态(返回字段)") - public Result> listTransactions(@RequestParam(value = "userId", required = false) Long userId, - @PathVariable Long orderId) { - List list = paymentService.listByOrder(orderId); -@@ -67,7 +67,7 @@ public class InternalPaymentController { - } - - @PostMapping("/refund") -- @ApiOperation("Create refund (called by order-service)") -+ @ApiOperation(value = "创建退款", notes = "由订单服务调用,向微信支付API发起退款请求。退款金额不能超过原支付金额,退款结果通过微信回调异步通知") - public Result createRefund(@Valid @RequestBody PaymentRefundRequest refundRequest) { - RefundRequest request = new RefundRequest(); - request.setOrderId(refundRequest.getOrderId()); -``` - -### `hl-payment-service/src/main/java/com/hulalv/payment/controller/PaymentCallbackController.java` (M) - -```diff -diff --git a/hl-payment-service/src/main/java/com/hulalv/payment/controller/PaymentCallbackController.java b/hl-payment-service/src/main/java/com/hulalv/payment/controller/PaymentCallbackController.java -index d950113..8b8106b 100644 ---- a/hl-payment-service/src/main/java/com/hulalv/payment/controller/PaymentCallbackController.java -+++ b/hl-payment-service/src/main/java/com/hulalv/payment/controller/PaymentCallbackController.java -@@ -23,14 +23,14 @@ import java.util.Map; - @RestController - @RequestMapping("/pay/callback") - @RequiredArgsConstructor --@Api(tags = "【回调接口】支付回调") -+@Api(tags = "【回调接口】支付回调", hidden = true) - public class PaymentCallbackController { - - private final PaymentService paymentService; - private final RefundService refundService; - - @PostMapping("/notify/{mchId}") -- @ApiOperation("支付成功回调") -+ @ApiOperation(value = "支付成功回调", notes = "微信支付成功后的异步通知回调(无需认证,通过微信签名验证安全性)。验证签名 → 更新支付状态 → 发送MQ消息通知订单服务") - public ResponseEntity> payNotify( - @PathVariable String mchId, - HttpServletRequest request) { -@@ -49,7 +49,7 @@ public class PaymentCallbackController { - } - - @PostMapping("/refund-notify/{mchId}") -- @ApiOperation("退款回调") -+ @ApiOperation(value = "退款回调", notes = "微信退款结果的异步通知回调(无需认证,通过微信签名验证安全性)。验证签名 → 更新退款状态 → 发送MQ消息通知订单服务") - public ResponseEntity> refundNotify( - @PathVariable String mchId, - HttpServletRequest request) { -``` - -### `hl-product-service/src/main/java/com/hulalv/product/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/config/Knife4jConfig.java b/hl-product-service/src/main/java/com/hulalv/product/config/Knife4jConfig.java -index 746c86e..f483fa8 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/config/Knife4jConfig.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/config/Knife4jConfig.java -@@ -1,9 +1,9 @@ - package com.hulalv.product.config; - -+import com.google.common.base.Predicate; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import springfox.documentation.builders.ApiInfoBuilder; --import springfox.documentation.builders.PathSelectors; - import springfox.documentation.builders.RequestHandlerSelectors; - import springfox.documentation.spi.DocumentationType; - import springfox.documentation.spring.web.plugins.Docket; -@@ -11,6 +11,11 @@ import springfox.documentation.spring.web.plugins.Docket; - @Configuration - public class Knife4jConfig { - -+ /** 排除内部接口和回调接口路径 */ -+ private Predicate adminPaths() { -+ return input -> input != null && !input.contains("/internal/") && !input.contains("/callback/"); -+ } -+ - @Bean - public Docket productApi() { - return new Docket(DocumentationType.SWAGGER_2) -@@ -22,7 +27,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.product.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/DistrictController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/DistrictController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/DistrictController.java -index 3d92709..5a21261 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/DistrictController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/DistrictController.java -@@ -21,7 +21,12 @@ public class DistrictController { - - private final AmapDistrictService amapDistrictService; - -- @ApiOperation("搜索行政区划(城市/区县)") -+ @ApiOperation(value = "搜索行政区划(城市/区县)", -+ notes = "通过高德地图 API 搜索行政区划,用于产品的出发城市和目的地城市选择。\n" -+ + "输入关键词(如\"丽江\"、\"昆明\"),返回匹配的城市/区县列表,包含行政区划编码。\n\n" -+ + "**关联字典**:\n" -+ + "- cities(城市):搜索结果可用于产品行程中的城市预览\n" -+ + "- city(城市筛选):搜索结果可用于资源面板城市筛选") - @GetMapping("/search") - public Result> search( - @ApiParam("搜索关键词") @RequestParam String keywords) { -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/FamilyController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/FamilyController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/FamilyController.java -index b1bba5b..8e8827f 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/FamilyController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/FamilyController.java -@@ -21,13 +21,19 @@ public class FamilyController { - - private final ProductFamilyService familyService; - -- @ApiOperation("获取家庭分组列表") -+ @ApiOperation(value = "获取家庭分组列表", -+ notes = "获取产品的家庭分组列表,按排序序号升序。\n\n" -+ + "**仅适用于 CUSTOM(定制)产品**。\n" -+ + "家庭分组用于将定制产品的行程按家庭单位分配,每个家庭可以有不同的人数和行程安排。\n" -+ + "行程节点通过 familyIds 字段关联到具体的家庭分组。") - @GetMapping("/families") - public Result> listFamilies(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(familyService.listFamilies(productId)); - } - -- @ApiOperation("添加家庭分组") -+ @ApiOperation(value = "添加家庭分组", -+ notes = "为 CUSTOM 定制产品添加一个家庭分组,指定家庭名称和各类型人数。\n" -+ + "添加后可在行程节点中关联此家庭,实现按家庭分配行程。") - @PostMapping("/family") - public Result addFamily( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -35,7 +41,9 @@ public class FamilyController { - return Result.success(familyService.addFamily(productId, request)); - } - -- @ApiOperation("更新家庭分组") -+ @ApiOperation(value = "更新家庭分组", -+ notes = "更新家庭分组的名称、各类型人数等信息。\n" -+ + "**仅适用于 CUSTOM(定制)产品**。") - @PutMapping("/family/{familyId}") - public Result updateFamily( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -44,7 +52,9 @@ public class FamilyController { - return Result.success(familyService.updateFamily(familyId, request)); - } - -- @ApiOperation("删除家庭分组") -+ @ApiOperation(value = "删除家庭分组", -+ notes = "删除家庭分组。如果有行程节点通过 familyIds 关联了该分组,需要手动移除关联。\n" -+ + "**仅适用于 CUSTOM(定制)产品**。") - @DeleteMapping("/family/{familyId}") - public Result deleteFamily( - @ApiParam("产品ID") @PathVariable Long productId, -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/FormulaController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/FormulaController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/FormulaController.java -index 9d4395e..6cc32f3 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/FormulaController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/FormulaController.java -@@ -32,20 +32,34 @@ public class FormulaController { - - // ===== Group endpoints ===== - -- @ApiOperation("公式组列表") -+ @ApiOperation(value = "公式组列表", -+ notes = "获取定价公式组列表,可按产品类型筛选。\n\n" -+ + "**公式引擎说明**:定价公式用于自动计算产品的成本价和售价。\n" -+ + "每种产品类型可以有多个公式组,但同一时间只能有一个激活的公式组。\n" -+ + "公式组包含多个步骤,按顺序执行,每步计算一个中间变量或最终结果。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,筛选条件):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/group/list") - public Result> listGroups( - @RequestParam(required = false) String productType) { - return Result.success(groupService.listGroups(productType)); - } - -- @ApiOperation("公式组详情") -+ @ApiOperation(value = "公式组详情", -+ notes = "获取公式组完整信息。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/group/{groupId}") - public Result getGroup(@PathVariable Long groupId) { - return Result.success(groupService.getGroup(groupId)); - } - -- @ApiOperation("创建公式组") -+ @ApiOperation(value = "创建公式组", -+ notes = "创建一个新的定价公式组。创建后默认为未激活状态。\n\n" -+ + "公式组编码(groupCode)在同一产品类型下必须唯一。\n" -+ + "建议命名规范:{产品类型}_PRICING_V{版本号},如 CORE_PRICING_V2。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,公式组所属类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PostMapping("/group") - public Result createGroup(@Valid @RequestBody FormulaGroupRequest request, - HttpServletRequest httpRequest) { -@@ -53,21 +67,31 @@ public class FormulaController { - return Result.success(groupService.createGroup(request, adminId)); - } - -- @ApiOperation("更新公式组") -+ @ApiOperation(value = "更新公式组", -+ notes = "更新公式组信息。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PutMapping("/group/{groupId}") - public Result updateGroup(@PathVariable Long groupId, - @Valid @RequestBody FormulaGroupRequest request) { - return Result.success(groupService.updateGroup(groupId, request)); - } - -- @ApiOperation("激活公式组") -+ @ApiOperation(value = "激活公式组", -+ notes = "激活指定公式组,同时自动停用同产品类型下的其他公式组。\n\n" -+ + "同一产品类型下只能有一个激活的公式组,激活操作具有排他性。\n" -+ + "激活后,该产品类型的自动成本计算将使用此公式组。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,同类型排他激活):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PutMapping("/group/{groupId}/activate") - public Result activateGroup(@PathVariable Long groupId) { - groupService.activateGroup(groupId); - return Result.success(); - } - -- @ApiOperation("删除公式组") -+ @ApiOperation(value = "删除公式组", -+ notes = "删除公式组及其下所有步骤。\n" -+ + "**限制**:已激活的公式组不能删除,需先激活其他公式组。") - @DeleteMapping("/group/{groupId}") - public Result deleteGroup(@PathVariable Long groupId) { - groupService.deleteGroup(groupId); -@@ -76,25 +100,35 @@ public class FormulaController { - - // ===== Step endpoints ===== - -- @ApiOperation("公式步骤列表") -+ @ApiOperation(value = "公式步骤列表", -+ notes = "获取公式组下所有步骤,按执行顺序(executionOrder)升序排列。\n" -+ + "步骤按顺序依次执行,前一步的输出变量可作为后续步骤的输入。") - @GetMapping("/group/{groupId}/steps") - public Result> listSteps(@PathVariable Long groupId) { - return Result.success(stepService.listSteps(groupId)); - } - -- @ApiOperation("公式步骤详情") -+ @ApiOperation(value = "公式步骤详情", -+ notes = "获取单个公式步骤的完整信息,包含表达式、输入/输出变量、执行顺序等。") - @GetMapping("/step/{formulaId}") - public Result getStep(@PathVariable Long formulaId) { - return Result.success(stepService.getStep(formulaId)); - } - -- @ApiOperation("创建公式步骤") -+ @ApiOperation(value = "创建公式步骤", -+ notes = "在公式组中创建一个计算步骤。\n\n" -+ + "**表达式语法**:使用 Aviator 表达式引擎,支持数学运算、条件判断、内置函数等。\n" -+ + "示例:`baseCost = adultCount * adultUnitCost + childCount * childUnitCost`\n\n" -+ + "**输入变量**:可引用公式变量表中定义的变量,或前置步骤的输出变量。\n" -+ + "**输出变量**:每个步骤必须指定一个输出变量名,供后续步骤引用。") - @PostMapping("/step") - public Result createStep(@Valid @RequestBody FormulaStepRequest request) { - return Result.success(stepService.createStep(request)); - } - -- @ApiOperation("更新公式步骤") -+ @ApiOperation(value = "更新公式步骤", -+ notes = "更新公式步骤的表达式、输入/输出变量等。\n" -+ + "每次更新会自动保存一个版本快照,可通过版本历史接口查看和回滚。") - @PutMapping("/step/{formulaId}") - public Result updateStep(@PathVariable Long formulaId, - @Valid @RequestBody FormulaStepRequest request, -@@ -103,27 +137,36 @@ public class FormulaController { - return Result.success(stepService.updateStep(formulaId, request, adminId)); - } - -- @ApiOperation("启用/禁用公式步骤") -+ @ApiOperation(value = "启用/禁用公式步骤", -+ notes = "切换公式步骤的启用状态。\n" -+ + "禁用的步骤在公式执行时会被跳过,不影响其他步骤的执行。\n" -+ + "适用场景:临时跳过某个计算步骤进行调试或测试。") - @PutMapping("/step/{formulaId}/toggle") - public Result toggleStep(@PathVariable Long formulaId) { - stepService.toggleStep(formulaId); - return Result.success(); - } - -- @ApiOperation("删除公式步骤") -+ @ApiOperation(value = "删除公式步骤", -+ notes = "删除指定的公式步骤。删除后其他步骤的执行顺序不会自动调整。\n" -+ + "**注意**:如果后续步骤引用了被删步骤的输出变量,执行时会报错。") - @DeleteMapping("/step/{formulaId}") - public Result deleteStep(@PathVariable Long formulaId) { - stepService.deleteStep(formulaId); - return Result.success(); - } - -- @ApiOperation("公式步骤版本历史") -+ @ApiOperation(value = "公式步骤版本历史", -+ notes = "获取公式步骤的所有历史版本列表,按版本号倒序。\n" -+ + "每次更新步骤表达式会自动创建新版本,方便追溯和回滚。") - @GetMapping("/step/{formulaId}/versions") - public Result> listVersions(@PathVariable Long formulaId) { - return Result.success(stepService.listVersions(formulaId)); - } - -- @ApiOperation("回滚公式步骤到指定版本") -+ @ApiOperation(value = "回滚公式步骤到指定版本", -+ notes = "将公式步骤回滚到历史版本。\n" -+ + "回滚操作会用历史版本的表达式、变量等覆盖当前内容,并创建一个新的版本记录。") - @PutMapping("/step/{formulaId}/rollback/{versionNum}") - public Result rollbackStep(@PathVariable Long formulaId, - @PathVariable Integer versionNum, -@@ -134,7 +177,11 @@ public class FormulaController { - - // ===== Test endpoint ===== - -- @ApiOperation("测试公式执行") -+ @ApiOperation(value = "测试公式执行", -+ notes = "使用自定义变量值测试公式组的执行结果,不影响任何业务数据。\n\n" -+ + "传入公式组ID和测试变量(变量名→值的映射),返回每个步骤的执行结果。\n" -+ + "适用于公式调试:验证表达式是否正确、计算结果是否符合预期。\n" -+ + "如果某步骤执行出错,会在结果中标明错误信息。") - @PostMapping("/test") - public Result testFormulas(@Valid @RequestBody FormulaTestRequest request) { - return Result.success(testService.testFormulas(request)); -@@ -142,27 +189,41 @@ public class FormulaController { - - // ===== Var endpoints ===== - -- @ApiOperation("公式变量列表") -+ @ApiOperation(value = "公式变量列表", -+ notes = "获取公式变量列表,可按变量分类筛选。\n\n" -+ + "**变量分类**:\n" -+ + "- INPUT:输入变量,从业务数据获取(如成人人数、资源单价)\n" -+ + "- INTERMEDIATE:中间变量,由公式步骤计算得出\n" -+ + "- OUTPUT:输出变量,最终报价结果(如总成本、售价)") - @GetMapping("/var/list") - public Result> listVars( - @RequestParam(required = false) String category) { - return Result.success(varService.listVars(category)); - } - -- @ApiOperation("创建公式变量") -+ @ApiOperation(value = "创建公式变量", -+ notes = "创建公式变量定义。变量名(varName)全局唯一,建议使用驼峰命名。\n" -+ + "可指定适用的产品类型列表(productTypes),为空则适用于所有类型。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,变量适用范围):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PostMapping("/var") - public Result createVar(@Valid @RequestBody FormulaVarRequest request) { - return Result.success(varService.createVar(request)); - } - -- @ApiOperation("更新公式变量") -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/GroupBatchController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/GroupBatchController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/GroupBatchController.java -index 7e553dc..ab7b818 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/GroupBatchController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/GroupBatchController.java -@@ -25,7 +25,16 @@ public class GroupBatchController { - - // ===== Batch CRUD ===== - -- @ApiOperation("创建主批次") -+ @ApiOperation(value = "创建主批次", -+ notes = "为 GROUP(小蒙马拼团)产品创建一个团期主批次。\n\n" -+ + "**仅适用于 GROUP 产品类型**。\n" -+ + "每个批次有独立的出发日期、报名截止日期、人数上限。\n" -+ + "创建后状态为 PENDING(待开放),需手动开启报名。\n\n" -+ + "**批次状态流转**:PENDING → ENROLLING(报名中)→ CONFIRMED(已成团)→ CLOSED(已关闭)\n" -+ + "任意报名状态均可被解散(DISBANDED)。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,仅限GROUP):GROUP=小蒙马拼团\n" -+ + "- batch_status(批次状态):PENDING=待开放, ENROLLING=报名中, CONFIRMED=已成团, FULL=已满员, CLOSED=已关闭, DISBANDED=已解散, IN_PROGRESS=进行中, FINISHED=已结束") - @PostMapping - public Result createBatch(@PathVariable Long productId, - @Valid @RequestBody GroupBatchCreateRequest request, -@@ -34,7 +43,11 @@ public class GroupBatchController { - return Result.success(batchService.createBatch(productId, request, adminId)); - } - -- @ApiOperation("创建子批次(溢出)") -+ @ApiOperation(value = "创建子批次(溢出)", -+ notes = "当主批次人数满员时,创建子批次接收溢出报名。\n\n" -+ + "子批次共享主批次的出发日期和行程,但有独立的人数上限和报名人数。\n" -+ + "适用场景:某团期特别火爆,需要扩容但希望分开管理。\n" -+ + "子批次在列表中显示为主批次的子级节点。") - @PostMapping("/{batchId}/sub-batch") - public Result createSubBatch(@PathVariable Long productId, - @PathVariable Long batchId, -@@ -44,7 +57,9 @@ public class GroupBatchController { - return Result.success(batchService.createSubBatch(batchId, request, adminId)); - } - -- @ApiOperation("更新批次") -+ @ApiOperation(value = "更新批次", -+ notes = "更新批次基本信息。仅传入需要修改的字段。\n" -+ + "已有报名人员的批次修改人数上限时,不能低于已报名人数。") - @PutMapping("/{batchId}") - public Result updateBatch(@PathVariable Long productId, - @PathVariable Long batchId, -@@ -52,20 +67,30 @@ public class GroupBatchController { - return Result.success(batchService.updateBatch(batchId, request)); - } - -- @ApiOperation("删除批次") -+ @ApiOperation(value = "删除批次", -+ notes = "删除批次(软删除)。\n" -+ + "**限制**:已有报名人员的批次不能直接删除,需先解散批次。") - @DeleteMapping("/{batchId}") - public Result deleteBatch(@PathVariable Long productId, @PathVariable Long batchId) { - batchService.deleteBatch(batchId); - return Result.success(); - } - -- @ApiOperation("批次列表(树形)") -+ @ApiOperation(value = "批次列表(树形)", -+ notes = "获取产品所有批次,以树形结构返回(主批次包含子批次列表)。\n" -+ + "按出发日期升序排列,包含每个批次的报名人数和剩余名额。\n\n" -+ + "**关联字典**:\n" -+ + "- batch_status(批次状态,返回字段):PENDING=待开放, ENROLLING=报名中, CONFIRMED=已成团, FULL=已满员, CLOSED=已关闭, DISBANDED=已解散, IN_PROGRESS=进行中, FINISHED=已结束") - @GetMapping("/list") - public Result> listBatches(@PathVariable Long productId) { - return Result.success(batchService.listBatches(productId)); - } - -- @ApiOperation("批次详情") -+ @ApiOperation(value = "批次详情", -+ notes = "获取单个批次的完整信息,包括批次基本信息、服务人员配置、套餐组合等。\n\n" -+ + "**关联字典**:\n" -+ + "- batch_status(批次状态):PENDING=待开放, ENROLLING=报名中, CONFIRMED=已成团, FULL=已满员, CLOSED=已关闭, DISBANDED=已解散, IN_PROGRESS=进行中, FINISHED=已结束\n" -+ + "- staff_type(人员类型,服务人员配置):GUIDE=领队, DRIVER=司机, PHOTOGRAPHER=摄影师, ASSISTANT=助理, OTHER=其他") - @GetMapping("/{batchId}") - public Result getBatchDetail(@PathVariable Long productId, - @PathVariable Long batchId) { -@@ -74,21 +99,33 @@ public class GroupBatchController { - - // ===== Status operations ===== - -- @ApiOperation("开启报名(PENDING->ENROLLING)") -+ @ApiOperation(value = "开启报名(PENDING->ENROLLING)", -+ notes = "将批次从 PENDING 状态变更为 ENROLLING(报名中)。\n" -+ + "开启后用户可在小程序端看到该团期并报名。\n" -+ + "前提条件:产品必须已上架(PUBLISHED)。") - @PutMapping("/{batchId}/open") - public Result openEnrollment(@PathVariable Long productId, @PathVariable Long batchId) { - batchService.openEnrollment(batchId); - return Result.success(); - } - -- @ApiOperation("关闭报名(ENROLLING/CONFIRMED->CLOSED)") -+ @ApiOperation(value = "关闭报名(ENROLLING/CONFIRMED->CLOSED)", -+ notes = "关闭批次报名,不再接受新的报名。\n" -+ + "已报名的订单不受影响,仅阻止新增报名。\n" -+ + "适用于报名截止日期到达或手动提前关闭的场景。") - @PutMapping("/{batchId}/close") - public Result closeEnrollment(@PathVariable Long productId, @PathVariable Long batchId) { - batchService.closeEnrollment(batchId); - return Result.success(); - } - -- @ApiOperation("解散批次") -+ @ApiOperation(value = "解散批次", -+ notes = "解散批次并处理已报名的订单。\n\n" -+ + "**重要**:解散操作会触发以下流程:\n" -+ + "1. 批次状态变更为 DISBANDED\n" -+ + "2. 通过 MQ 消息通知订单服务,自动取消该批次下的所有未完成订单\n" -+ + "3. 已支付订单会触发退款流程\n\n" -+ + "必须填写解散原因(如:报名人数不足、行程调整等)。") - @PostMapping("/{batchId}/disband") - public Result disbandBatch(@PathVariable Long productId, - @PathVariable Long batchId, -@@ -103,7 +140,13 @@ public class GroupBatchController { - - // ===== Staff operations ===== - -- @ApiOperation("保存服务人员(全量替换)") -+ @ApiOperation(value = "保存服务人员(全量替换)", -+ notes = "保存批次的服务人员配置,采用全量替换模式(先删后增)。\n\n" -+ + "每次提交完整的人员列表,替换掉该批次原有的所有人员配置。\n" -+ + "人员来源于资源服务的人员库,通过 staffId 关联。\n" -+ + "**角色类型**:LEADER(领队)/PHOTOGRAPHER(摄影师)/DRIVER(司机)/OTHER(其他)\n\n" -+ + "**关联字典**:\n" -+ + "- staff_type(人员类型):GUIDE=领队, DRIVER=司机, PHOTOGRAPHER=摄影师, ASSISTANT=助理, OTHER=其他") - @PostMapping("/{batchId}/staff") - public Result> saveStaff(@PathVariable Long productId, - @PathVariable Long batchId, -@@ -111,14 +154,18 @@ public class GroupBatchController { - return Result.success(staffService.saveStaff(batchId, productId, requests)); - } - -- @ApiOperation("服务人员列表") -+ @ApiOperation(value = "服务人员列表", -+ notes = "**关联字典**:\n" -+ + "- staff_type(人员类型):GUIDE=领队, DRIVER=司机, PHOTOGRAPHER=摄影师, ASSISTANT=助理, OTHER=其他") - @GetMapping("/{batchId}/staff") - public Result> listStaff(@PathVariable Long productId, - @PathVariable Long batchId) { - return Result.success(staffService.listStaff(batchId)); - } - -- @ApiOperation("从其他批次复制服务人员") -+ @ApiOperation(value = "从其他批次复制服务人员", -+ notes = "将源批次的服务人员配置复制到当前批次(全量替换当前批次已有人员)。\n" -+ + "适用场景:多个团期使用相同的服务人员班底。") - @PostMapping("/{batchId}/staff/copy-from/{sourceId}") - public Result> copyStaff(@PathVariable Long productId, - @PathVariable Long batchId, -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/InternalMpProductController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/InternalMpProductController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/InternalMpProductController.java -index 61d9a75..7a6ea65 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/InternalMpProductController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/InternalMpProductController.java -@@ -36,7 +36,7 @@ import java.util.Map; - * C端产品内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "【内部接口】小程序产品(Feign调用)") -+@Api(tags = "【内部接口】小程序产品(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/product") - @RequiredArgsConstructor -@@ -50,39 +50,56 @@ public class InternalMpProductController { - private final ProductPriceCalendarMapper priceCalendarMapper; - private final GroupTourBatchMapper groupTourBatchMapper; - -- @ApiOperation("产品列表") -+ @ApiOperation(value = "产品列表", -+ notes = "内部Feign接口,返回已上架产品列表。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,筛选+返回字段):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/list") - public Result> listProducts(@Valid MpProductQueryRequest query) { - return Result.success(productService.listPublishedProducts(query)); - } - -- @ApiOperation("产品详情") -+ @ApiOperation(value = "产品详情", -+ notes = "内部Feign接口,返回已上架产品详情。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态):PUBLISHED=已上架\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @GetMapping("/{productId}") - public Result getProduct(@PathVariable Long productId) { - return Result.success(productService.getPublishedProduct(productId)); - } - -- @ApiOperation("报价计算") -+ @ApiOperation(value = "报价计算", -+ notes = "内部服务间调用,供 hl-mp-service BFF 层 Feign 调用的报价计算接口。\n" -+ + "计算逻辑与管理后台报价一致,根据日期和人数计算总价。") - @PostMapping("/{productId}/quote") - public Result calculateQuote(@PathVariable Long productId, - @Valid @RequestBody QuoteRequest request) { - return Result.success(quoteCalculatorService.calculateQuote(productId, request)); - } - -- @ApiOperation("产品线列表(活跃)") -+ @ApiOperation(value = "产品线列表(活跃)", -+ notes = "内部服务间调用,供 hl-mp-service 获取所有启用的产品线列表,用于小程序端筛选。") - @GetMapping("/lines") - public Result> listActiveLines() { - return Result.success(productLineService.listAllActive()); - } - -- @ApiOperation("推荐产品列表") -+ @ApiOperation(value = "推荐产品列表", -+ notes = "返回推荐的已上架产品。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,返回字段):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/recommend") - public Result> listRecommendProducts( - @RequestParam(defaultValue = "6") int limit) { - return Result.success(productService.listRecommendProducts(limit)); - } - -- @ApiOperation("C端价格日历") -+ @ApiOperation(value = "C端价格日历", -+ notes = "内部服务间调用,供 hl-mp-service 获取产品的价格日历数据。\n\n" -+ + "可通过 startDate/endDate 限定查询范围,不传则返回今天及之后的所有可用日期。\n" -+ + "返回每天的售价和库存信息,供小程序端日历选择器使用。") - @GetMapping("/{productId}/price-calendar") - public Result>> getPriceCalendar( - @PathVariable Long productId, -@@ -91,7 +108,10 @@ public class InternalMpProductController { - return Result.success(priceCalendarService.getMpPriceCalendar(productId, startDate, endDate)); - } - -- @ApiOperation("产品最早可订日期") -+ @ApiOperation(value = "产品最早可订日期", -+ notes = "根据产品类型查询最早可预订日期。GROUP类型查批次出发日期,CORE/CUSTOM类型查价格日历。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,影响查询逻辑):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/earliest-booking-date") - public Result getEarliestBookingDate(@RequestParam Long productId) { - Product product = productMapper.selectById(productId); -@@ -137,7 +157,10 @@ public class InternalMpProductController { - } - } - -- @ApiOperation("定制师产品统计(C端用)") -+ @ApiOperation(value = "定制师产品统计(C端用)", -+ notes = "统计指定定制师已发布的产品数量。\n\n" -+ + "**关联字典**:\n" -+ + "- product_status(产品状态,统计条件):PUBLISHED=已上架") - @GetMapping("/designer-stats") - public Result> getDesignerStats(@RequestParam Long customizerId) { - long routeCount = productMapper.selectCount( -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/InternalProductController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/InternalProductController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/InternalProductController.java -index 978f513..7c0b2e7 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/InternalProductController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/InternalProductController.java -@@ -49,7 +49,7 @@ import java.util.stream.Collectors; - @RestController - @RequestMapping("/internal/product") - @RequiredArgsConstructor --@Api(tags = "【内部接口】产品(Feign调用)") -+@Api(tags = "【内部接口】产品(Feign调用)", hidden = true) - public class InternalProductController { - - private final ProductStatusService productStatusService; -@@ -66,8 +66,12 @@ public class InternalProductController { - private final GroupTourBatchMapper groupBatchMapper; - private final ObjectMapper objectMapper; - -+ @ApiOperation(value = "处理产品审批结果", -+ notes = "接收企微审批回调结果,更新产品状态。\n\n" -+ + "**关联字典**:\n" -+ + "- product_status(产品状态):PENDING_REVIEW=待审核, REVIEWED=已审核, REJECTED=已驳回, PUBLISHED=已上架") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@Valid @RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@Valid @RequestBody ApprovalResultDTO dto) { - try { - productStatusService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -@@ -78,10 +82,12 @@ public class InternalProductController { - } - } - -- /** -- * 获取产品详情(不过滤状态,供 order-service 创建订单时获取快照) -- * 可选传入 date 参数,传入后会从资源价格日历查询各节点的成本价并填入快照 -- */ -+ @ApiOperation(value = "获取产品详情(内部)", -+ notes = "不过滤状态,供 order-service 创建订单时获取快照。可选传入 date 参数查询各节点成本价。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态):DRAFT=草稿, PENDING_REVIEW=待审核, REVIEWED=已审核, REJECTED=已驳回, PUBLISHED=已上架, UNPUBLISHED=已下架, COMPLETED=已完成, ORDERED=已下单\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @GetMapping("/{productId}/detail") - public Result getProductDetail(@PathVariable Long productId, - @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) { -@@ -91,19 +97,20 @@ public class InternalProductController { - return Result.success(productService.getProduct(productId)); - } - -- /** -- * 报价计算(供 order-service 创建订单时自动报价) -- */ -+ @ApiOperation(value = "报价计算(内部)", -+ notes = "供 order-service 创建订单时自动报价。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,影响计算逻辑):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PostMapping("/{productId}/quote") - public Result calculateQuote(@PathVariable Long productId, - @Valid @RequestBody QuoteRequest request) { - return Result.success(quoteCalculatorService.calculateQuote(productId, request)); - } - -- /** -- * 简单报价:直接从价格日历取售价 × 人数,不走资源价格计算。 -- * 小童 = 儿童售价 × 折扣比例,幼童 = 固定价格。 -- */ -+ @ApiOperation(value = "简单报价(内部)", -+ notes = "直接从价格日历取售价乘以人数,不走资源价格计算。CUSTOM/ROUTE按整单,CORE/GROUP按人头。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,影响计算逻辑):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/{productId}/simple-quote") - public Result> simpleQuote( - @PathVariable Long productId, -@@ -253,6 +260,10 @@ public class InternalProductController { - /** - * Deduct stock (optimistic lock: only succeeds if stock >= count) - */ -+ @ApiOperation(value = "扣减库存(内部)", -+ notes = "内部服务间调用,供 order-service 创建订单时扣减价格日历库存。\n\n" -+ + "使用乐观锁机制:只有当库存 >= count 时才扣减成功。\n" -+ + "扣减失败返回错误(库存不足),调用方需处理失败情况。") - @PostMapping("/{productId}/deduct-stock") - public Result deductStock(@PathVariable Long productId, - @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") String date, -@@ -268,6 +279,9 @@ public class InternalProductController { - /** - * Restore stock (compensation for cancelled/expired orders) - */ -+ @ApiOperation(value = "恢复库存(内部)", -+ notes = "内部服务间调用,供 order-service 订单取消/过期时恢复价格日历库存。\n" -+ + "用于补偿已扣减的库存,恢复数量不校验上限。") - @PostMapping("/{productId}/restore-stock") - public Result restoreStock(@PathVariable Long productId, - @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") String date, -@@ -281,6 +295,9 @@ public class InternalProductController { - * Get itinerary resources (SCENIC/ACTIVITY/HOTEL) for review service. - * Returns deduplicated list of { resourceType, resourceId, resourceName }. - */ -+ @ApiOperation(value = "获取行程关联资源(内部)", -+ notes = "内部服务间调用,供 review-service 获取产品行程中关联的资源列表。\n\n" -+ + "返回去重后的景区(SCENIC)、活动(ACTIVITY)、酒店(HOTEL)资源,用于评价时选择关联的资源对象。") - @GetMapping("/{productId}/itinerary-resources") - public Result>> getItineraryResources(@PathVariable Long productId) { - // Allowed resource types for review -@@ -310,9 +327,11 @@ public class InternalProductController { - return Result.success(result); - } - -- /** -- * 变更定制产品状态(供 order-service 调用:下单→ORDERED / 取消→COMPLETED) -- */ -+ @ApiOperation(value = "变更定制产品状态(内部)", -+ notes = "供 order-service 调用:下单时 COMPLETED→ORDERED,取消时 ORDERED→COMPLETED。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,仅限CUSTOM):CUSTOM=定制产品\n" -+ + "- product_status(产品状态):COMPLETED=已完成, ORDERED=已下单") - @PutMapping("/{productId}/custom-status") - public Result changeCustomProductStatus(@PathVariable Long productId, - @RequestParam String targetStatus) { -@@ -339,6 +358,10 @@ public class InternalProductController { - /** - * Enroll participants (optimistic lock on batch). - */ -+ @ApiOperation(value = "报名入团(内部)", -+ notes = "内部服务间调用,供 order-service 下单时增加批次已报名人数。\n\n" -+ + "使用乐观锁机制:只有当剩余名额 >= peopleCount 时才报名成功。\n" -+ + "报名成功后自动检查是否满员(FULL)或达到成团条件(CONFIRMED)。") - @PostMapping("/batch/{batchId}/enroll") - public Result enrollBatch(@PathVariable Long batchId, - @RequestParam @Min(1) int peopleCount) { -@@ -349,6 +372,9 @@ public class InternalProductController { - /** - * Unenroll participants (compensation for cancellation). - */ -+ @ApiOperation(value = "退出报名(内部)", -+ notes = "内部服务间调用,供 order-service 订单取消/退款时减少批次已报名人数。\n" -+ + "用于补偿已报名的人数,恢复剩余名额。") - @PostMapping("/batch/{batchId}/unenroll") - public Result unenrollBatch(@PathVariable Long batchId, - @RequestParam @Min(1) int peopleCount) { -@@ -356,9 +382,10 @@ public class InternalProductController { - return Result.success(); - } - -- /** -- * Get batch info (for order snapshot). -- */ -+ @ApiOperation(value = "批次信息(内部)", -+ notes = "供 order-service 创建订单时获取批次快照。\n\n" -+ + "**关联字典**:\n" -+ + "- batch_status(批次状态,返回字段):PENDING=待开放, ENROLLING=报名中, CONFIRMED=已成团, FULL=已满员, CLOSED=已关闭, DISBANDED=已解散, IN_PROGRESS=进行中, FINISHED=已结束") - @GetMapping("/batch/{batchId}/info") - public Result> getBatchInfo(@PathVariable Long batchId) { - GroupTourBatch batch = groupTourBatchService.getBatchById(batchId); -@@ -385,6 +412,10 @@ public class InternalProductController { - /** - * GROUP quote: returns adult/child dynamic pricing for a batch. - */ -+ @ApiOperation(value = "GROUP产品报价(内部)", -+ notes = "内部服务间调用,供 order-service 和 mp-service 获取 GROUP 产品按套餐组合的报价。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,仅限GROUP):GROUP=小蒙马拼团") - @GetMapping("/{productId}/group-quote") - public Result getGroupQuote(@PathVariable Long productId, - @RequestParam Long batchId, -@@ -395,6 +426,9 @@ public class InternalProductController { - /** - * C-end calendar data for GROUP products. - */ -+ @ApiOperation(value = "团期日历数据(内部)", -+ notes = "内部服务间调用,供小程序端展示 GROUP 产品的团期日历。\n\n" -+ + "返回可报名批次的出发日期、状态、剩余名额等信息,用于日历选择器展示。") - @GetMapping("/{productId}/batches/calendar") - public Result> getBatchesCalendar(@PathVariable Long productId) { - return Result.success(groupTourBatchService.listCalendar(productId)); -@@ -403,6 +437,9 @@ public class InternalProductController { - /** - * C-end combo list for a batch (套餐列表). - */ -+ @ApiOperation(value = "批次套餐列表(内部)", -+ notes = "内部服务间调用,供小程序端展示 GROUP 产品批次下的套餐组合列表。\n\n" -+ + "每个套餐包含成人/儿童人数搭配、售价、原价、库存和已售数量。") - @GetMapping("/batch/{batchId}/combos") - public Result>> listBatchCombos(@PathVariable Long batchId) { - List combos = comboMapper.selectList( -@@ -431,7 +468,9 @@ public class InternalProductController { - - // ===== 定制师内部接口 ===== - -- @ApiOperation("获取定制师已发布产品ID列表") -+ @ApiOperation(value = "获取定制师已发布产品ID列表", -+ notes = "**关联字典**:\n" -+ + "- product_status(产品状态,筛选条件):PUBLISHED=已上架") - @GetMapping("/designer-published-ids") - public Result> getDesignerPublishedProductIds(@RequestParam Long createBy) { - List ids = productService.getDesignerPublishedProductIds(createBy); -@@ -439,19 +478,28 @@ public class InternalProductController { - return Result.success(strIds); - } - -- @ApiOperation("获取全局产品统计") -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/ItineraryController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/ItineraryController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/ItineraryController.java -index f813a83..7ea5e3b 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/ItineraryController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/ItineraryController.java -@@ -28,7 +28,10 @@ public class ItineraryController { - - // ========================= Day ========================= - -- @ApiOperation("更新行程天") -+ @ApiOperation(value = "更新行程天", -+ notes = "更新指定天的行程信息,如当天主题、概述等。\n" -+ + "行程天在创建产品时根据 tripDays 自动生成,不支持单独增删,只能更新。\n" -+ + "dayNumber 从 1 开始,对应第几天的行程。") - @PutMapping("/item/{productId}/day/{dayNumber}") - public Result updateDay( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -37,7 +40,9 @@ public class ItineraryController { - return Result.success(dayService.updateDay(productId, dayNumber, request)); - } - -- @ApiOperation("获取行程天列表") -+ @ApiOperation(value = "获取行程天列表", -+ notes = "获取产品所有行程天的信息,按 dayNumber 升序排列。\n" -+ + "每一天包含当天主题、概述等信息,不包含节点详情(节点通过单独接口获取)。") - @GetMapping("/item/{productId}/days") - public Result> listDays(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(dayService.listDays(productId)); -@@ -45,7 +50,14 @@ public class ItineraryController { - - // ========================= Node ========================= - -- @ApiOperation("添加行程节点") -+ @ApiOperation(value = "添加行程节点", -+ notes = "在指定天添加一个行程节点。节点是行程的最小单元,可关联资源服务中的景区、酒店、活动等。\n\n" -+ + "**节点类型**:TRANSPORT(交通)/SCENIC(景区)/DINING(餐饮)/ACTIVITY(活动)/" -+ + "PHOTOGRAPHY(摄影)/HOTEL(酒店)/FREE(自由活动)/CUSTOM(自定义)\n\n" -+ + "**CUSTOM 定制产品特有**:可通过 familyIds 指定节点所属的家庭分组,实现按家庭分配行程。\n" -+ + "新建节点自动追加到当天最后位置,可通过排序接口调整顺序。\n\n" -+ + "**关联字典**:\n" -+ + "- city(城市,资源面板筛选用):用于在添加节点时按城市筛选可选资源") - @PostMapping("/item/{productId}/day/{dayNumber}/node") - public Result createNode( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -54,7 +66,12 @@ public class ItineraryController { - return Result.success(nodeService.createNode(productId, dayNumber, request)); - } - -- @ApiOperation("更新行程节点") -+ @ApiOperation(value = "更新行程节点", -+ notes = "更新行程节点信息,仅传入需要修改的字段。\n" -+ + "可修改节点名称、时间、关联资源、图片、描述等。\n\n" -+ + "**关联字典**:\n" -+ + "- city(城市):资源面板城市筛选\n" -+ + "- cities(城市ID映射):城市名称预览") - @PutMapping("/node/{nodeId}") - public Result updateNode( - @ApiParam("行程节点ID") @PathVariable Long nodeId, -@@ -62,14 +79,17 @@ public class ItineraryController { - return Result.success(nodeService.updateNode(nodeId, request)); - } - -- @ApiOperation("删除行程节点") -+ @ApiOperation(value = "删除行程节点", -+ notes = "删除指定行程节点,同天其他节点的排序自动调整。") - @DeleteMapping("/node/{nodeId}") - public Result deleteNode(@ApiParam("行程节点ID") @PathVariable Long nodeId) { - nodeService.deleteNode(nodeId); - return Result.success(); - } - -- @ApiOperation("行程节点拖拽排序") -+ @ApiOperation(value = "行程节点拖拽排序", -+ notes = "重新排列指定天的所有行程节点顺序。前端拖拽排序后,将新的节点ID顺序全量提交。\n" -+ + "nodeIds 列表中的顺序即为新的排序顺序(从上到下)。") - @PutMapping("/item/{productId}/day/{dayNumber}/nodes/sort") - public Result sortNodes( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -79,13 +99,17 @@ public class ItineraryController { - return Result.success(); - } - -- @ApiOperation("复制行程节点") -+ @ApiOperation(value = "复制行程节点", -+ notes = "复制指定节点到同一天的末尾位置,包括节点的所有属性(名称、资源关联、图片等)。\n" -+ + "适用场景:同一天有相似的行程安排时快速复制。") - @PostMapping("/node/{nodeId}/copy") - public Result copyNode(@ApiParam("行程节点ID") @PathVariable Long nodeId) { - return Result.success(nodeService.copyNode(nodeId)); - } - -- @ApiOperation("移动行程节点到其他天") -+ @ApiOperation(value = "移动行程节点到其他天", -+ notes = "将节点从当前天移动到目标天的末尾位置。\n" -+ + "移动后原天和目标天的节点排序自动调整。") - @PutMapping("/node/{nodeId}/move") - public Result moveNode( - @ApiParam("行程节点ID") @PathVariable Long nodeId, -@@ -93,7 +117,12 @@ public class ItineraryController { - return Result.success(nodeService.moveNode(nodeId, request.getTargetDayNumber())); - } - -- @ApiOperation("获取某天的节点列表") -+ @ApiOperation(value = "获取某天的节点列表", -+ notes = "获取指定天的所有行程节点,按排序顺序返回。\n" -+ + "每个节点包含类型、名称、时间、关联资源信息、图片等完整数据。\n\n" -+ + "**关联字典**:\n" -+ + "- city(城市):资源面板城市筛选\n" -+ + "- cities(城市ID映射):城市名称预览") - @GetMapping("/item/{productId}/day/{dayNumber}/nodes") - public Result> listNodes( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -103,7 +132,10 @@ public class ItineraryController { - - // ========================= Hotel ========================= - -- @ApiOperation("添加每日住宿") -+ @ApiOperation(value = "添加每日住宿", -+ notes = "为指定天添加住宿安排,关联资源服务中的酒店和房型。\n" -+ + "每天可以有多个住宿选项(如不同档次),参与成本自动计算。\n" -+ + "住宿费用会体现在价格日历的成本计算中。") - @PostMapping("/item/{productId}/day/{dayNumber}/hotel") - public Result addHotel( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -112,7 +144,8 @@ public class ItineraryController { - return Result.success(hotelService.addHotel(productId, dayNumber, request)); - } - -- @ApiOperation("更新每日住宿") -+ @ApiOperation(value = "更新每日住宿", -+ notes = "更新住宿记录的酒店、房型、数量等信息。") - @PutMapping("/hotel/{id}") - public Result updateHotel( - @ApiParam("住宿记录ID") @PathVariable Long id, -@@ -120,14 +153,16 @@ public class ItineraryController { - return Result.success(hotelService.updateHotel(id, request)); - } - -- @ApiOperation("删除每日住宿") -+ @ApiOperation(value = "删除每日住宿", -+ notes = "删除指定住宿记录。删除后该天的住宿成本会从报价中移除。") - @DeleteMapping("/hotel/{id}") - public Result deleteHotel(@ApiParam("住宿记录ID") @PathVariable Long id) { - hotelService.deleteHotel(id); - return Result.success(); - } - -- @ApiOperation("获取某天的住宿列表") -+ @ApiOperation(value = "获取某天的住宿列表", -+ notes = "获取指定天的所有住宿安排,包含酒店名称、房型、数量等信息。") - @GetMapping("/item/{productId}/day/{dayNumber}/hotels") - public Result> listHotels( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -137,7 +172,9 @@ public class ItineraryController { - - // ========================= Dining ========================= - -- @ApiOperation("添加每日餐厅推荐") -+ @ApiOperation(value = "添加每日餐厅推荐", -+ notes = "为指定天添加餐饮推荐,关联资源服务中的餐厅。\n" -+ + "用于展示当天的用餐安排,可按早/午/晚分类。") - @PostMapping("/item/{productId}/day/{dayNumber}/dining") - public Result addDiningOption( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -146,7 +183,8 @@ public class ItineraryController { - return Result.success(diningOptionService.addDiningOption(productId, dayNumber, request)); - } - -- @ApiOperation("更新餐饮推荐") -+ @ApiOperation(value = "更新餐饮推荐", -+ notes = "更新餐饮推荐的餐厅、用餐类型(早/午/晚)、描述等信息。") - @PutMapping("/dining/{id}") - public Result updateDiningOption( - @ApiParam("餐饮推荐ID") @PathVariable Long id, -@@ -154,7 +192,8 @@ public class ItineraryController { - return Result.success(diningOptionService.updateDiningOption(id, request)); - } - -- @ApiOperation("获取某天的餐厅推荐列表") -+ @ApiOperation(value = "获取某天的餐厅推荐列表", -+ notes = "获取指定天的所有餐饮推荐,包含餐厅名称、用餐类型、描述等信息。") - @GetMapping("/item/{productId}/day/{dayNumber}/dining") - public Result> listDining( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -162,7 +201,8 @@ public class ItineraryController { - return Result.success(diningOptionService.listDiningOptions(productId, dayNumber)); - } - -- @ApiOperation("删除餐饮推荐") -+ @ApiOperation(value = "删除餐饮推荐", -+ notes = "删除指定的餐饮推荐记录。") - @DeleteMapping("/dining/{id}") - public Result deleteDiningOption(@ApiParam("餐饮推荐ID") @PathVariable Long id) { - diningOptionService.deleteDiningOption(id); -@@ -171,7 +211,9 @@ public class ItineraryController { - - // ========================= Supplies ========================= - -- @ApiOperation("添加物资配品") -+ @ApiOperation(value = "添加物资配品", -+ notes = "为产品添加物资配品(如帐篷、睡袋、登山杖等),关联资源服务中的物资。\n" -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/MpProductController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/MpProductController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/MpProductController.java -index 526bc16..94a6723 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/MpProductController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/MpProductController.java -@@ -31,19 +31,33 @@ public class MpProductController { - private final ProductService productService; - private final QuoteCalculatorService quoteCalculatorService; - -- @ApiOperation("产品列表") -+ @ApiOperation(value = "产品列表(C端)", -+ notes = "小程序端产品列表接口,仅返回已上架(PUBLISHED)的产品。\n\n" -+ + "支持按产品类型、季节、行程天数、目的地、产品线、支付模式、定制师等筛选。\n" -+ + "默认按 sortOrder 排序,也可按价格或行程天数排序。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,筛选条件):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @GetMapping("/list") - public Result> listProducts(@ApiParam("产品查询请求") @Valid MpProductQueryRequest query) { - return Result.success(productService.listPublishedProducts(query)); - } - -- @ApiOperation("产品详情") -+ @ApiOperation(value = "产品详情(C端)", -+ notes = "小程序端产品详情接口,仅返回已上架(PUBLISHED)的产品。\n" -+ + "包含完整的行程信息、定价配置、费用说明、创作者寄语等。\n" -+ + "未上架的产品会返回 404 错误。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @GetMapping("/{productId}") - public Result getProduct(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(productService.getPublishedProduct(productId)); - } - -- @ApiOperation("报价计算") -+ @ApiOperation(value = "报价计算(C端)", -+ notes = "小程序端报价计算接口,根据用户选择的日期和人数计算总价。\n" -+ + "内部会校验产品是否存在且已上架。\n" -+ + "详细计算逻辑参见管理后台的报价计算接口说明。") - @PostMapping("/{productId}/quote") - public Result calculateQuote( - @ApiParam("产品ID") @PathVariable Long productId, -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/PricingController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/PricingController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/PricingController.java -index cdd0cb8..1599755 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/PricingController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/PricingController.java -@@ -28,7 +28,18 @@ public class PricingController { - - // ========== 定价规则 ========== - -- @ApiOperation("保存定价规则") -+ @ApiOperation(value = "保存定价规则", -+ notes = "保存或更新产品的定价配置(一个产品仅一条定价记录,重复调用为覆盖更新)。\n\n" -+ + "**定价模式**:\n" -+ + "- AUTO:自动计算,通过公式引擎根据行程资源价格自动测算成本和售价\n" -+ + "- MANUAL:手动定价,直接在价格日历中手动设置每日价格\n" -+ + "- CUSTOM:定制定价,设置整单总价(customTotalPrice),不按人头\n\n" -+ + "**利润模式**(AUTO 模式下生效):\n" -+ + "- FIXED:固定金额加价,售价 = 成本 + profitAmount\n" -+ + "- PERCENT:百分比加价,售价 = 成本 × (1 + markupPercent/100)\n\n" -+ + "**支付方式**:FULL=全款支付,DEPOSIT=定金+尾款(需设置 depositRatio 或 depositAmount)\n\n" -+ + "**关联字典**:\n" -+ + "- vehicle_type(车型):费用配置中车辆相关成本计算") - @PostMapping("/pricing") - public Result savePricing( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -36,7 +47,11 @@ public class PricingController { - return Result.success(pricingService.savePricing(productId, request)); - } - -- @ApiOperation("获取定价规则") -+ @ApiOperation(value = "获取定价规则", -+ notes = "获取产品的定价配置,包括定价模式、利润设置、儿童/婴儿价格、支付方式等。\n" -+ + "如果产品尚未设置定价规则,返回 null。\n\n" -+ + "**关联字典**:\n" -+ + "- vehicle_type(车型):费用配置中车辆相关成本显示") - @GetMapping("/pricing") - public Result getPricing(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(pricingService.getPricing(productId)); -@@ -44,7 +59,11 @@ public class PricingController { - - // ========== 价格日历 ========== - -- @ApiOperation("获取月度价格日历") -+ @ApiOperation(value = "获取月度价格日历", -+ notes = "获取指定月份的价格日历数据列表。\n\n" -+ + "每条数据包含:日期、成人售价/成本价、儿童售价/成本价、库存、状态(OPEN/CLOSED)等。\n" -+ + "**CORE/GROUP 产品**:价格为单人价格,按人头 × 价格计算总价。\n" -+ + "**CUSTOM/ROUTE 产品**:价格为整单总价,不乘以人头数。") - @GetMapping("/price-calendar") - public Result> getMonthCalendar( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -53,7 +72,10 @@ public class PricingController { - return Result.success(calendarService.getMonthCalendar(productId, year, month)); - } - -- @ApiOperation("设置单日价格") -+ @ApiOperation(value = "设置单日价格", -+ notes = "设置或更新指定日期的价格和库存。如果该日期已有记录则更新,否则新建。\n\n" -+ + "可设置成人售价/成本价、儿童售价/成本价、库存数量、状态(OPEN/CLOSED)。\n" -+ + "状态为 CLOSED 的日期不会出现在小程序端的可选日期中。") - @PostMapping("/price-calendar") - public Result setDayPrice( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -61,7 +83,11 @@ public class PricingController { - return Result.success(calendarService.setDayPrice(productId, request)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", -+ notes = "批量设置日期范围内的价格和库存,支持按星期筛选。\n\n" -+ + "指定 startDate 和 endDate 日期范围,可选 selectedWeekdays 过滤星期几。\n" -+ + "示例:设置5月1日-5月31日的工作日(周一到周五=[1,2,3,4,5])价格。\n" -+ + "selectedWeekdays 为空时,范围内所有日期都会被设置。") - @PostMapping("/price-calendar/batch") - public Result> batchSetPrices( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -69,7 +95,13 @@ public class PricingController { - return Result.success(calendarService.batchSetPrices(productId, request)); - } - -- @ApiOperation("测算预览(不写入数据库)") -+ @ApiOperation(value = "测算预览(不写入数据库)", -+ notes = "根据行程中的资源价格日历,自动计算指定日期的成本价和售价,仅预览不保存。\n\n" -+ + "用于在设置价格日历前预览自动计算的结果。\n" -+ + "计算逻辑:汇总当天所有行程节点关联资源的价格 → 应用公式引擎 → 加上利润。\n" -+ + "GROUP 产品需要传 adultCount 参数(影响均摊计算)。\n\n" -+ + "**关联字典**:\n" -+ + "- vehicle_type(车型):车辆费用成本测算") - @PostMapping("/price-calendar/calc-preview") - public Result calcPreview( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -77,13 +109,21 @@ public class PricingController { - return Result.success(calendarService.calcPreview(productId, request)); - } - -- @ApiOperation("重新测算所有自动测算日期的价格") -+ @ApiOperation(value = "重新测算所有自动测算日期的价格", -+ notes = "重新计算价格日历中所有 costAutoCalc=true 的日期的成本价和售价。\n\n" -+ + "适用场景:资源价格调整后,批量刷新所有自动计算的价格日历。\n" -+ + "返回更新的日期数量和详情。手动设置的价格(costAutoCalc=false)不受影响。") - @PostMapping("/price-calendar/recalculate") - public Result> recalculate(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(calendarService.recalculateAll(productId)); - } - -- @ApiOperation("自动计算成本并同步到价格日历") -+ @ApiOperation(value = "自动计算成本并同步到价格日历", -+ notes = "根据出发日期和人数,自动计算成本并将结果写入价格日历。\n\n" -+ + "与测算预览不同,此接口会实际更新价格日历数据。\n" -+ + "计算逻辑:查询各资源的价格日历 → 汇总成本 → 应用公式和利润规则 → 写入结果。\n\n" -+ + "**关联字典**:\n" -+ + "- vehicle_type(车型):车辆费用成本计算") - @PostMapping("/price-calendar/auto-calc") - public Result autoCalcCost( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -100,7 +140,10 @@ public class PricingController { - - // ========== 费用包含/不包含 ========== - -- @ApiOperation("添加费用项") -+ @ApiOperation(value = "添加费用项", -+ notes = "添加产品的费用包含/不包含说明项。\n\n" -+ + "用于在产品详情页展示\"费用包含\"和\"费用不包含\"信息。\n" -+ + "仅用于前端展示,不参与报价计算。") - @PostMapping("/cost-item") - public Result addCostItem( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -108,7 +151,8 @@ public class PricingController { - return Result.success(costItemService.addCostItem(productId, request)); - } - -- @ApiOperation("更新费用项") -+ @ApiOperation(value = "更新费用项", -+ notes = "更新费用包含/不包含说明项的内容。仅用于前端展示,不参与报价计算。") - @PutMapping("/cost-item/{itemId}") - public Result updateCostItem( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -117,7 +161,8 @@ public class PricingController { - return Result.success(costItemService.updateCostItem(itemId, request)); - } - -- @ApiOperation("删除费用项") -+ @ApiOperation(value = "删除费用项", -+ notes = "删除费用包含/不包含说明项。") - @DeleteMapping("/cost-item/{itemId}") - public Result deleteCostItem( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -126,7 +171,8 @@ public class PricingController { - return Result.success(); - } - -- @ApiOperation("获取费用项列表") -+ @ApiOperation(value = "获取费用项列表", -+ notes = "获取产品的所有费用包含/不包含说明项列表。") - @GetMapping("/cost-items") - public Result> listCostItems(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(costItemService.listCostItems(productId)); -@@ -134,7 +180,10 @@ public class PricingController { - - // ========== 额外成本关联 ========== - -- @ApiOperation("添加额外成本关联") -+ @ApiOperation(value = "添加额外成本关联", -+ notes = "关联资源服务中的费用项(cost_item)到产品,参与成本自动计算。\n\n" -+ + "额外成本是指不包含在行程节点中、但需要计入总成本的费用。\n" -+ + "例如:导游服务费、保险费、通讯费等固定运营开支。") - @PostMapping("/extra-cost") - public Result addExtraCost( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -142,7 +191,8 @@ public class PricingController { - return Result.success(extraCostService.addExtraCost(productId, request)); - } - -- @ApiOperation("更新额外成本关联") -+ @ApiOperation(value = "更新额外成本关联", -+ notes = "更新额外成本关联的费用项、数量等信息。修改后会影响成本自动计算结果。") - @PutMapping("/extra-cost/{ecId}") - public Result updateExtraCost( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -151,7 +201,8 @@ public class PricingController { - return Result.success(extraCostService.updateExtraCost(ecId, request)); - } - -- @ApiOperation("删除额外成本关联") -+ @ApiOperation(value = "删除额外成本关联", -+ notes = "删除额外成本关联记录。删除后该费用项不再计入成本自动计算。") - @DeleteMapping("/extra-cost/{ecId}") - public Result removeExtraCost( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -160,7 +211,8 @@ public class PricingController { - return Result.success(); - } - -- @ApiOperation("获取额外成本关联列表") -+ @ApiOperation(value = "获取额外成本关联列表", -+ notes = "获取产品关联的所有额外成本项列表,包含费用项名称、金额等信息。") - @GetMapping("/extra-costs") - public Result> listExtraCosts(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(extraCostService.listExtraCosts(productId)); -@@ -168,7 +220,10 @@ public class PricingController { - -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/ProductController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductController.java -index bc250d7..5f48dff 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductController.java -@@ -28,7 +28,20 @@ public class ProductController { - private final ProductStatusService productStatusService; - private final RouteMapService routeMapService; - -- @ApiOperation("创建产品(草稿)") -+ @ApiOperation(value = "创建产品(草稿)", -+ notes = "创建一个新产品,初始状态为 DRAFT(草稿)。\n\n" -+ + "**产品类型说明**:\n" -+ + "- CORE:核心产品,标准旅游产品,支持上架/下架审批流程\n" -+ + "- GROUP:小蒙马拼团,需配合团期批次管理,按人头计价\n" -+ + "- CUSTOM:定制产品,由定制师为客户量身定制,按单计价\n" -+ + "- ROUTE:线路产品,预设线路模板,按单计价\n\n" -+ + "**注意事项**:\n" -+ + "- 创建后需依次完善行程、定价、价格日历等信息\n" -+ + "- CUSTOM/ROUTE 产品的价格日历存储的是整单总价,不按人头乘算\n" -+ + "- GROUP 产品需额外创建团期批次才能报名\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @PostMapping - public Result createProduct( - @ApiParam("创建产品请求") @Valid @RequestBody ProductCreateRequest request, -@@ -37,13 +50,28 @@ public class ProductController { - return Result.success(productService.createProduct(request, adminId)); - } - -- @ApiOperation("获取产品详情") -+ @ApiOperation(value = "获取产品详情", -+ notes = "获取产品完整信息,包括基本信息、行程天列表、定价配置、费用项等。\n" -+ + "返回数据包含关联的行程节点资源详情,适用于产品编辑页面。\n" -+ + "不过滤产品状态,所有状态的产品都可查看。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态):DRAFT=草稿, PENDING_REVIEW=待审核, REVIEWED=已审核, REJECTED=已驳回, PUBLISHED=已上架, UNPUBLISHED=已下架, COMPLETED=已完成, ORDERED=已下单\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @GetMapping("/{productId}") - public Result getProduct(@ApiParam("产品ID") @PathVariable Long productId) { - return Result.success(productService.getProduct(productId)); - } - -- @ApiOperation("更新产品") -+ @ApiOperation(value = "更新产品", -+ notes = "更新产品基本信息,仅传入需要修改的字段,未传字段不会被覆盖。\n\n" -+ + "**权限说明**:\n" -+ + "- 普通管理员只能编辑自己创建的产品\n" -+ + "- SUPER_ADMIN 可编辑所有产品\n\n" -+ + "**注意**:行程、定价、价格日历等通过各自独立的接口管理,不在此接口中处理。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_category(产品分类):family=亲子游, honeymoon=蜜月游, photography=旅拍, experience=体验, driving=自驾") - @PutMapping("/{productId}") - public Result updateProduct( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -54,7 +82,10 @@ public class ProductController { - return Result.success(productService.updateProduct(productId, request, adminId, role)); - } - -- @ApiOperation("删除产品") -+ @ApiOperation(value = "删除产品", -+ notes = "软删除产品(设置 deleted_at 字段)。\n\n" -+ + "**权限说明**:普通管理员只能删除自己创建的产品,SUPER_ADMIN 可删除所有产品。\n" -+ + "**限制**:已上架(PUBLISHED)的产品不能直接删除,需先下架。") - @DeleteMapping("/{productId}") - public Result deleteProduct( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -65,17 +96,33 @@ public class ProductController { - return Result.success(); - } - -- @ApiOperation("产品列表") -+ @ApiOperation(value = "产品列表", -+ notes = "分页查询产品列表,支持多维度筛选和排序。\n\n" -+ + "**权限说明**:\n" -+ + "- 普通管理员只能看到自己创建的产品\n" -+ + "- SUPER_ADMIN 可看到所有产品\n\n" -+ + "**筛选条件**:关键词(名称/副标题模糊匹配)、产品类型、状态、文件夹、产品线、季节、行程天数。\n" -+ + "支持多状态筛选(statuses 字段,逗号分隔)。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,筛选条件):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态,筛选条件+返回字段):DRAFT=草稿, PENDING_REVIEW=待审核, REVIEWED=已审核, REJECTED=已驳回, PUBLISHED=已上架, UNPUBLISHED=已下架, COMPLETED=已完成, ORDERED=已下单") - @GetMapping("/list") - public Result> listProducts( - @ApiParam("产品查询请求") @Valid ProductQueryRequest query, - HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -- boolean isSuperAdmin = "SUPER_ADMIN".equals(httpRequest.getAttribute("role")); -- return Result.success(productService.listProducts(query, adminId, isSuperAdmin)); -+ String role = (String) httpRequest.getAttribute("role"); -+ boolean canViewAll = "SUPER_ADMIN".equals(role) || "CUSTOMER_SERVICE".equals(role); -+ return Result.success(productService.listProducts(query, adminId, canViewAll)); - } - -- @ApiOperation("复制产品") -+ @ApiOperation(value = "复制产品", -+ notes = "深度复制产品,包括行程天、行程节点、定价配置、住宿、餐饮、物资、人员配置等所有关联数据。\n\n" -+ + "复制后的产品状态为 DRAFT,名称自动添加\"(副本)\"后缀。\n" -+ + "适用场景:基于已有产品快速创建新产品。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,返回字段):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态,复制后固定为 DRAFT)") - @PostMapping("/{productId}/copy") - public Result copyProduct( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -84,7 +131,9 @@ public class ProductController { - return Result.success(productService.copyProduct(productId, adminId)); - } - -- @ApiOperation("移动产品到文件夹") -+ @ApiOperation(value = "移动产品到文件夹", -+ notes = "将产品移动到指定文件夹,或移出文件夹(folderId 传空字符串或 null)。\n" -+ + "文件夹用于组织管理产品,不影响产品的业务逻辑。") - @PutMapping("/{productId}/move") - public Result moveProduct( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -95,7 +144,10 @@ public class ProductController { - return Result.success(); - } - -- @ApiOperation("生成定制产品分享链接") -+ @ApiOperation(value = "生成定制产品分享链接", -+ notes = "为 CUSTOM(定制)产品生成小程序分享链接,用于定制师发送给客户查看方案。\n\n" -+ + "**限制**:仅 CUSTOM 类型且状态为 COMPLETED 的产品可生成。\n" -+ + "**权限**:普通管理员只能为自己创建的产品生成链接,SUPER_ADMIN 不受限制。") - @PostMapping("/{productId}/share-link") - public Result generateShareLink( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -105,7 +157,10 @@ public class ProductController { - return Result.success(productService.generateShareLink(productId, adminId, role)); - } - -- @ApiOperation("手动生成路径图") -+ @ApiOperation(value = "手动生成路径图", -+ notes = "根据产品行程节点的经纬度信息,调用地图API生成行程路径图。\n\n" -+ + "通常在行程编辑完成后手动触发,生成结果为 OSS 图片 URL。\n" -+ + "如果行程节点没有经纬度信息,则无法生成路径图。") - @PostMapping("/{productId}/generate-route-map") - public Result generateRouteMap(@ApiParam("产品ID") @PathVariable Long productId) { - try { -@@ -116,7 +171,20 @@ public class ProductController { - } - } - -- @ApiOperation("产品状态变更(上架/下架等)") -+ @ApiOperation(value = "产品状态变更(上架/下架/完成)", -+ notes = "根据产品类型,状态流转规则不同:\n\n" -+ + "**核心产品(CORE) / 小蒙马(GROUP)**:支持上架/下架,需企微审批\n" -+ + "- DRAFT → PENDING_REVIEW → REVIEWED → PUBLISHED(上架)\n" -+ + "- PUBLISHED → UNPUBLISHED(下架)\n" -+ + "- UNPUBLISHED → PUBLISHED(重新上架)\n" -+ + "- REJECTED → DRAFT(驳回后重新编辑)\n\n" -+ + "**定制产品(CUSTOM)**:仅支持完成,无上架/下架概念\n" -+ + "- DRAFT → COMPLETED(定制师完成设计)\n" -+ + "- COMPLETED → ORDERED(客户下单,系统自动变更)\n" -+ + "- ORDERED → COMPLETED(订单取消/退款后回退)\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,影响状态流转规则):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品\n" -+ + "- product_status(产品状态,请求+返回字段):DRAFT=草稿, PENDING_REVIEW=待审核, REVIEWED=已审核, REJECTED=已驳回, PUBLISHED=已上架, UNPUBLISHED=已下架, COMPLETED=已完成, ORDERED=已下单") - @PutMapping("/{productId}/status") - public Result changeStatus( - @ApiParam("产品ID") @PathVariable Long productId, -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/ProductFolderController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductFolderController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductFolderController.java -index 2562b23..2b69413 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductFolderController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductFolderController.java -@@ -23,7 +23,9 @@ public class ProductFolderController { - - private final ProductFolderService folderService; - -- @ApiOperation("创建文件夹") -+ @ApiOperation(value = "创建文件夹", -+ notes = "创建产品文件夹,用于组织管理产品。支持多级目录结构。\n" -+ + "文件夹归属于创建人,普通管理员只能看到自己的文件夹。") - @PostMapping - public Result createFolder( - @ApiParam("创建文件夹请求") @Valid @RequestBody FolderCreateRequest request, -@@ -33,7 +35,9 @@ public class ProductFolderController { - return Result.success(folderService.createFolder(request, adminId, ownerName)); - } - -- @ApiOperation("更新文件夹") -+ @ApiOperation(value = "更新文件夹", -+ notes = "更新文件夹名称等信息。\n" -+ + "**权限说明**:普通管理员只能更新自己创建的文件夹,SUPER_ADMIN 可更新任何文件夹。") - @PutMapping("/{folderId}") - public Result updateFolder( - @ApiParam("文件夹ID") @PathVariable Long folderId, -@@ -44,7 +48,9 @@ public class ProductFolderController { - return Result.success(folderService.updateFolder(folderId, request, adminId, isSuperAdmin)); - } - -- @ApiOperation("删除文件夹") -+ @ApiOperation(value = "删除文件夹", -+ notes = "删除文件夹。如果文件夹下有产品,产品会自动移到根目录(folderId 置空)。\n" -+ + "普通管理员只能删除自己的文件夹,SUPER_ADMIN 可删除任何文件夹。") - @DeleteMapping("/{folderId}") - public Result deleteFolder(@ApiParam("文件夹ID") @PathVariable Long folderId, HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -@@ -53,7 +59,10 @@ public class ProductFolderController { - return Result.success(); - } - -- @ApiOperation("获取文件夹树") -+ @ApiOperation(value = "获取文件夹树", -+ notes = "获取当前用户可见的文件夹树形结构。\n" -+ + "普通管理员只能看到自己创建的文件夹,SUPER_ADMIN 可看到所有文件夹。\n" -+ + "返回结构为嵌套的树形列表,包含每个文件夹的子文件夹。") - @GetMapping("/tree") - public Result> getFolderTree(HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/ProductLineController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductLineController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductLineController.java -index 28d7d17..13683ab 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/ProductLineController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/ProductLineController.java -@@ -25,7 +25,9 @@ public class ProductLineController { - - private final ProductLineService lineService; - -- @ApiOperation("创建产品线") -+ @ApiOperation(value = "创建产品线", -+ notes = "创建产品线,用于对产品进行业务分类(如:亲子游、蜜月游、探险游等)。\n" -+ + "产品线在小程序端可作为筛选条件,帮助用户快速找到感兴趣的产品类别。") - @PostMapping - public Result createLine( - @ApiParam("创建产品线请求") @Valid @RequestBody LineCreateRequest request, -@@ -34,7 +36,8 @@ public class ProductLineController { - return Result.success(lineService.createLine(request, adminId)); - } - -- @ApiOperation("更新产品线") -+ @ApiOperation(value = "更新产品线", -+ notes = "更新产品线名称、描述、状态等信息。") - @PutMapping("/{lineId}") - public Result updateLine( - @ApiParam("产品线ID") @PathVariable Long lineId, -@@ -42,26 +45,31 @@ public class ProductLineController { - return Result.success(lineService.updateLine(lineId, request)); - } - -- @ApiOperation("删除产品线") -+ @ApiOperation(value = "删除产品线", -+ notes = "删除产品线(软删除)。已关联产品的产品线仍可删除,但关联产品的产品线字段不会被清空。") - @DeleteMapping("/{lineId}") - public Result deleteLine(@ApiParam("产品线ID") @PathVariable Long lineId) { - lineService.deleteLine(lineId); - return Result.success(); - } - -- @ApiOperation("产品线详情") -+ @ApiOperation(value = "产品线详情", -+ notes = "获取指定产品线的完整信息。") - @GetMapping("/{lineId}") - public Result getLine(@ApiParam("产品线ID") @PathVariable Long lineId) { - return Result.success(lineService.getLine(lineId)); - } - -- @ApiOperation("产品线列表(分页)") -+ @ApiOperation(value = "产品线列表(分页)", -+ notes = "分页查询产品线列表,支持按名称关键词筛选。") - @GetMapping("/list") - public Result> listLines(@ApiParam("产品线查询请求") @Valid LineQueryRequest query) { - return Result.success(lineService.listLines(query)); - } - -- @ApiOperation("所有启用的产品线") -+ @ApiOperation(value = "所有启用的产品线", -+ notes = "获取所有启用状态的产品线,不分页。\n" -+ + "适用于产品编辑时的产品线下拉选择,以及小程序端的筛选项。") - @GetMapping("/active") - public Result> listAllActive() { - return Result.success(lineService.listAllActive()); -``` - -### `hl-product-service/src/main/java/com/hulalv/product/controller/QuoteController.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/controller/QuoteController.java b/hl-product-service/src/main/java/com/hulalv/product/controller/QuoteController.java -index b6676e4..81f33f0 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/controller/QuoteController.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/controller/QuoteController.java -@@ -23,7 +23,18 @@ public class QuoteController { - private final QuoteCalculatorService quoteCalculatorService; - private final CostCalculationService costCalculationService; - -- @ApiOperation("计算报价") -+ @ApiOperation(value = "计算报价", -+ notes = "根据出发日期和人数组合,计算产品的完整报价。\n\n" -+ + "**计算流程**:\n" -+ + "1. 从价格日历获取指定日期的单价\n" -+ + "2. 按人数类型分别计算:成人 × 成人价、儿童 × 儿童价\n" -+ + "3. 小童按儿童价 × 折扣比例(childDiscountPercent)计算\n" -+ + "4. 婴儿使用固定价格(babyPrice)\n" -+ + "5. 儿童加床(childNeedBed=true)额外加收 childWithBed 费用\n\n" -+ + "**CUSTOM/ROUTE 产品**:价格日历存的是整单总价,不按人头乘算。\n" -+ + "**GROUP 产品**:建议使用 group-quote 接口,支持套餐组合报价。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,影响计算逻辑):CORE=核心产品, GROUP=小蒙马拼团, CUSTOM=定制产品, ROUTE=线路产品") - @PostMapping("/quote") - public Result calculateQuote( - @ApiParam("产品ID") @PathVariable Long productId, -@@ -31,7 +42,13 @@ public class QuoteController { - return Result.success(quoteCalculatorService.calculateQuote(productId, request)); - } - -- @ApiOperation("GROUP产品报价(按组合)") -+ @ApiOperation(value = "GROUP产品报价(按套餐组合)", -+ notes = "为 GROUP(小蒙马拼团)产品按团期批次和套餐组合计算报价。\n\n" -+ + "GROUP 产品的价格由批次下的套餐组合(combo)决定,不同组合有不同的成人/儿童人数搭配和价格。\n" -+ + "传入 batchId 指定团期批次,adultCount 用于匹配合适的套餐组合。\n\n" -+ + "**与普通报价的区别**:普通报价从价格日历取单价,GROUP 报价从套餐组合取打包价。\n\n" -+ + "**关联字典**:\n" -+ + "- product_type(产品类型,仅限GROUP):GROUP=小蒙马拼团") - @GetMapping("/group-quote") - public Result calculateGroupQuote( - @ApiParam("产品ID") @PathVariable Long productId, -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/FamilySaveRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/FamilySaveRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/FamilySaveRequest.java -index 223810b..84591cf 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/FamilySaveRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/FamilySaveRequest.java -@@ -9,7 +9,7 @@ import javax.validation.constraints.NotBlank; - import javax.validation.constraints.Size; - - @Data --@ApiModel("家庭分组保存请求") -+@ApiModel(value = "家庭分组保存请求", description = "仅适用于CUSTOM定制产品,用于将行程按家庭单位分配") - public class FamilySaveRequest { - - @ApiModelProperty(value = "家庭名称", required = true, example = "家庭1") -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/FormulaStepRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/FormulaStepRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/FormulaStepRequest.java -index 4acb045..89b3240 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/FormulaStepRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/FormulaStepRequest.java -@@ -29,7 +29,8 @@ public class FormulaStepRequest { - @ApiModelProperty(value = "执行顺序", example = "1") - private Integer executionOrder; - -- @ApiModelProperty(value = "表达式", required = true, example = "baseCost = adultCount * adultUnitCost + childCount * childUnitCost") -+ @ApiModelProperty(value = "Aviator表达式(支持数学运算、条件判断、内置函数;可引用前置步骤的输出变量和公式变量表中的变量)", -+ required = true, example = "baseCost = adultCount * adultUnitCost + childCount * childUnitCost") - @NotBlank(message = "表达式不能为空") - @Size(max = 2000, message = "表达式不能超过2000个字符") - private String expression; -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchCreateRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchCreateRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchCreateRequest.java -index 70e06ec..2cf6432 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchCreateRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchCreateRequest.java -@@ -8,34 +8,34 @@ import javax.validation.constraints.*; - import java.time.LocalDate; - - @Data --@ApiModel("create group batch request") -+@ApiModel("创建拼团批次请求") - public class GroupBatchCreateRequest { - -- @ApiModelProperty(value = "batch name", required = true, example = "Jul 20 Batch 1") -- @NotBlank(message = "batch name required") -+ @ApiModelProperty(value = "批次名称", required = true, example = "7月20日第1批") -+ @NotBlank(message = "批次名称不能为空") - @Size(max = 128) - private String batchName; - -- @ApiModelProperty(value = "departure date", required = true, example = "2026-07-20") -- @NotNull(message = "departure date required") -+ @ApiModelProperty(value = "出发日期", required = true, example = "2026-07-20") -+ @NotNull(message = "出发日期不能为空") - private LocalDate departureDate; - -- @ApiModelProperty(value = "enrollment deadline", required = true, example = "2026-07-15") -- @NotNull(message = "enrollment deadline required") -+ @ApiModelProperty(value = "报名截止日期,必须早于出发日期", required = true, example = "2026-07-15") -+ @NotNull(message = "报名截止日期不能为空") - private LocalDate enrollmentDeadline; - -- @ApiModelProperty(value = "min participants for group confirmation (0=no limit)", example = "10") -+ @ApiModelProperty(value = "最低成团人数(0=不限制,达到此人数自动变为CONFIRMED状态)", example = "10") - @Min(0) - private int minParticipants = 0; - -- @ApiModelProperty(value = "max participants", required = true, example = "30") -- @Min(value = 1, message = "max participants must be >= 1") -+ @ApiModelProperty(value = "最大参团人数(报名人数达到上限后自动关闭报名)", required = true, example = "30") -+ @Min(value = 1, message = "最大参团人数至少为1") - private int maxParticipants; - -- @ApiModelProperty(value = "remark", example = "summer special batch") -+ @ApiModelProperty(value = "备注说明", example = "暑期特别批次") - @Size(max = 512) - private String remark; - -- @ApiModelProperty(value = "sort order", example = "0") -+ @ApiModelProperty(value = "排序序号(越小越靠前)", example = "0") - private int sortOrder = 0; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchDisbandRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchDisbandRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchDisbandRequest.java -index 369a7ca..ca769e4 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchDisbandRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchDisbandRequest.java -@@ -8,11 +8,11 @@ import javax.validation.constraints.NotBlank; - import javax.validation.constraints.Size; - - @Data --@ApiModel("disband batch request") -+@ApiModel("解散批次请求") - public class GroupBatchDisbandRequest { - -- @ApiModelProperty(value = "disband reason", required = true, example = "insufficient enrollment") -- @NotBlank(message = "disband reason required") -+ @ApiModelProperty(value = "解散原因(如:报名人数不足、行程调整等)", required = true, example = "报名人数不足") -+ @NotBlank(message = "解散原因不能为空") - @Size(max = 512) - private String reason; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchStaffRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchStaffRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchStaffRequest.java -index 8c2f4bb..712181e 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchStaffRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchStaffRequest.java -@@ -9,22 +9,22 @@ import javax.validation.constraints.NotNull; - import javax.validation.constraints.Size; - - @Data --@ApiModel("batch staff assignment request") -+@ApiModel("批次服务人员分配请求") - public class GroupBatchStaffRequest { - -- @ApiModelProperty(value = "staff ID (from resource-service)", required = true, example = "1760000000000001") -- @NotNull(message = "staff ID required") -+ @ApiModelProperty(value = "人员ID(来自资源服务的人员库)", required = true, example = "1760000000000001") -+ @NotNull(message = "人员ID不能为空") - private Long staffId; - -- @ApiModelProperty(value = "role in this batch: LEADER/PHOTOGRAPHER/DRIVER/OTHER", required = true, example = "LEADER") -- @NotBlank(message = "staff role required") -+ @ApiModelProperty(value = "在该批次中的角色:LEADER(领队)/PHOTOGRAPHER(摄影师)/DRIVER(司机)/OTHER(其他)", required = true, example = "LEADER") -+ @NotBlank(message = "人员角色不能为空") - @Size(max = 32) - private String staffRole; - -- @ApiModelProperty(value = "remark", example = "main guide") -+ @ApiModelProperty(value = "备注(如:主导游、备用摄影师等)", example = "主导游") - @Size(max = 256) - private String remark; - -- @ApiModelProperty(value = "sort order", example = "0") -+ @ApiModelProperty(value = "排序序号(越小越靠前)", example = "0") - private int sortOrder = 0; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchUpdateRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchUpdateRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchUpdateRequest.java -index a8e2de6..4532f60 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchUpdateRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/GroupBatchUpdateRequest.java -@@ -9,31 +9,31 @@ import javax.validation.constraints.Size; - import java.time.LocalDate; - - @Data --@ApiModel("update group batch request") -+@ApiModel("更新拼团批次请求") - public class GroupBatchUpdateRequest { - -- @ApiModelProperty(value = "batch name", example = "Jul 20 Batch 1") -+ @ApiModelProperty(value = "批次名称", example = "7月20日第1批") - @Size(max = 128) - private String batchName; - -- @ApiModelProperty(value = "departure date", example = "2026-07-20") -+ @ApiModelProperty(value = "出发日期", example = "2026-07-20") - private LocalDate departureDate; - -- @ApiModelProperty(value = "enrollment deadline", example = "2026-07-15") -+ @ApiModelProperty(value = "报名截止日期", example = "2026-07-15") - private LocalDate enrollmentDeadline; - -- @ApiModelProperty(value = "min participants", example = "10") -+ @ApiModelProperty(value = "最低成团人数(0=不限制)", example = "10") - @Min(0) - private Integer minParticipants; - -- @ApiModelProperty(value = "max participants", example = "30") -+ @ApiModelProperty(value = "最大参团人数(不能低于已报名人数)", example = "30") - @Min(1) - private Integer maxParticipants; - -- @ApiModelProperty(value = "remark") -+ @ApiModelProperty(value = "备注说明") - @Size(max = 512) - private String remark; - -- @ApiModelProperty(value = "sort order") -+ @ApiModelProperty(value = "排序序号") - private Integer sortOrder; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/NodeCreateRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/NodeCreateRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/NodeCreateRequest.java -index a19ae8a..eae3469 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/NodeCreateRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/NodeCreateRequest.java -@@ -37,10 +37,10 @@ public class NodeCreateRequest { - @ApiModelProperty(value = "纬度", example = "26.872108") - private BigDecimal latitude; - -- @ApiModelProperty(value = "关联资源类型:SCENIC_SPOT/HOTEL/RESTAURANT/ACTIVITY/VEHICLE/SERVICE", example = "SCENIC_SPOT") -+ @ApiModelProperty(value = "关联资源类型(关联后可从资源服务获取价格参与成本计算):SCENIC/HOTEL/RESTAURANT/ACTIVITY/VEHICLE/SERVICE", example = "SCENIC") - private String resourceType; - -- @ApiModelProperty(value = "关联资源ID", example = "1893012345678901234") -+ @ApiModelProperty(value = "关联资源ID(来自资源服务,关联后节点名称和图片可自动同步)", example = "1893012345678901234") - private String resourceId; - - @ApiModelProperty(value = "节点描述", example = "漫步古城,感受纳西文化") -@@ -58,6 +58,6 @@ public class NodeCreateRequest { - @ApiModelProperty(value = "数量", example = "1") - private Integer quantity; - -- @ApiModelProperty(value = "所属家庭ID列表(定制产品按家庭分配)") -+ @ApiModelProperty(value = "所属家庭ID列表(仅CUSTOM定制产品使用,实现按家庭分配行程节点)") - private List familyIds; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/PriceCalendarRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/PriceCalendarRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/PriceCalendarRequest.java -index a5188da..dacb69c 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/PriceCalendarRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/PriceCalendarRequest.java -@@ -28,13 +28,13 @@ public class PriceCalendarRequest { - @ApiModelProperty(value = "儿童成本价", example = "1800.00") - private BigDecimal childCostPrice; - -- @ApiModelProperty(value = "是否自动计算成本", example = "true") -+ @ApiModelProperty(value = "是否自动计算成本(true时重新测算会自动更新此日期的价格)", example = "true") - private Boolean costAutoCalc; - -- @ApiModelProperty(value = "库存数量", example = "30") -+ @ApiModelProperty(value = "库存数量(CORE/GROUP按人头扣减,CUSTOM/ROUTE按单扣减)", example = "30") - private Integer stock; - -- @ApiModelProperty(value = "状态:OPEN=开放 CLOSED=关闭", example = "OPEN") -+ @ApiModelProperty(value = "状态:OPEN=开放预订 CLOSED=关闭(不可预订)", example = "OPEN") - private String status; - - @ApiModelProperty(value = "备注", example = "五一黄金周特价") -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/PricingRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/PricingRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/PricingRequest.java -index 28b7e49..a937367 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/PricingRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/PricingRequest.java -@@ -11,10 +11,10 @@ import java.util.List; - @ApiModel("定价配置请求") - public class PricingRequest { - -- @ApiModelProperty(value = "定价模式:AUTO=自动计算 MANUAL=手动定价 CUSTOM=定制定价", example = "AUTO") -+ @ApiModelProperty(value = "定价模式:AUTO=根据行程资源价格自动计算 MANUAL=手动在价格日历设置每日价格 CUSTOM=定制产品整单定价", example = "AUTO") - private String pricingMode; - -- @ApiModelProperty(value = "利润模式:FIXED=固定金额 PERCENT=百分比", example = "FIXED") -+ @ApiModelProperty(value = "利润模式(AUTO模式下生效):FIXED=在成本基础上加固定金额 PERCENT=在成本基础上按百分比加价", example = "FIXED") - private String profitMode; - - @ApiModelProperty(value = "利润金额(FIXED模式下使用)", example = "500.00") -@@ -32,16 +32,16 @@ public class PricingRequest { - @ApiModelProperty(value = "餐费预算", example = "100.00") - private BigDecimal mealBudget; - -- @ApiModelProperty(value = "儿童占床价", example = "1800.00") -+ @ApiModelProperty(value = "儿童加床费(childNeedBed=true时额外加收的费用)", example = "1800.00") - private BigDecimal childWithBed; - -- @ApiModelProperty(value = "儿童不占床价", example = "1200.00") -+ @ApiModelProperty(value = "儿童不占床价(暂未使用,预留字段)", example = "1200.00") - private BigDecimal childNoBed; - -- @ApiModelProperty(value = "婴儿价", example = "300.00") -+ @ApiModelProperty(value = "婴儿固定价格(不随日期变化)", example = "300.00") - private BigDecimal babyPrice; - -- @ApiModelProperty(value = "儿童折扣百分比", example = "70.00") -+ @ApiModelProperty(value = "小童折扣百分比(小童价=儿童价×此百分比/100,如70表示打7折)", example = "70.00") - private BigDecimal childDiscountPercent; - - @ApiModelProperty(value = "车型ID列表") -@@ -56,24 +56,24 @@ public class PricingRequest { - @ApiModelProperty(value = "陪同人员价格", example = "0.00") - private BigDecimal companionPrice; - -- @ApiModelProperty(value = "定制产品总价(CUSTOM模式下使用)", example = "28800.00") -+ @ApiModelProperty(value = "定制产品总价(CUSTOM定价模式下使用,代表整单总价)", example = "28800.00") - private BigDecimal customTotalPrice; - -- @ApiModelProperty(value = "最小成团人数", example = "2") -+ @ApiModelProperty(value = "最小成团人数(CORE/GROUP产品用,影响均摊成本计算)", example = "2") - private Integer minGroupSize; - -- @ApiModelProperty(value = "最大成团人数", example = "16") -+ @ApiModelProperty(value = "最大成团人数(CORE/GROUP产品用)", example = "16") - private Integer maxGroupSize; - -- @ApiModelProperty(value = "支付方式:FULL=全款 DEPOSIT=定金+尾款", example = "FULL") -+ @ApiModelProperty(value = "支付方式:FULL=全款支付 DEPOSIT=定金+尾款分期支付", example = "FULL") - private String paymentType; - -- @ApiModelProperty(value = "定金比例(百分比)", example = "30") -+ @ApiModelProperty(value = "定金比例(百分比,如30代表30%。与depositAmount二选一,优先使用比例)", example = "30") - private Integer depositRatio; - -- @ApiModelProperty(value = "定金金额", example = "1000.00") -+ @ApiModelProperty(value = "定金金额(固定金额,与depositRatio二选一)", example = "1000.00") - private BigDecimal depositAmount; - -- @ApiModelProperty(value = "尾款支付截止天数(出发前N天)", example = "7") -+ @ApiModelProperty(value = "尾款支付截止天数(出发前N天必须支付尾款,超时可能取消订单)", example = "7") - private Integer balanceDueDays; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/ProductStatusRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/ProductStatusRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/ProductStatusRequest.java -index 23e1203..99033be 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/ProductStatusRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/ProductStatusRequest.java -@@ -10,10 +10,11 @@ import javax.validation.constraints.NotBlank; - @ApiModel("产品状态变更请求") - public class ProductStatusRequest { - -- @ApiModelProperty(value = "目标状态:DRAFT/PENDING_REVIEW/REVIEWED/REJECTED/PUBLISHED/UNPUBLISHED/COMPLETED", required = true, example = "PUBLISHED") -+ @ApiModelProperty(value = "目标状态。核心/小蒙马:DRAFT/PENDING_REVIEW/REVIEWED/REJECTED/PUBLISHED/UNPUBLISHED;定制产品:COMPLETED", -+ required = true, example = "PUBLISHED") - @NotBlank(message = "目标状态不能为空") - private String status; - -- @ApiModelProperty(value = "状态变更原因(驳回时必填)", example = "行程信息不完整,请补充") -+ @ApiModelProperty(value = "状态变更原因(驳回时必填;上架/下架审批时可填)", example = "行程信息不完整,请补充") - private String reason; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/dto/QuoteRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/dto/QuoteRequest.java b/hl-product-service/src/main/java/com/hulalv/product/dto/QuoteRequest.java -index fd39d97..92c28aa 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/dto/QuoteRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/dto/QuoteRequest.java -@@ -21,18 +21,18 @@ public class QuoteRequest { - @Min(value = 1, message = "成人人数最少1人") - private Integer adultCount; - -- @ApiModelProperty(value = "儿童人数(占床)", example = "1") -+ @ApiModelProperty(value = "儿童人数(占床,按儿童价计算)", example = "1") - @Min(value = 0, message = "儿童人数不能为负数") - private Integer childCount = 0; - -- @ApiModelProperty(value = "小童人数(不占床)", example = "0") -+ @ApiModelProperty(value = "小童人数(不占床,按儿童价 × childDiscountPercent 折扣比例计算)", example = "0") - @Min(value = 0, message = "小童人数不能为负数") - private Integer youngChildCount = 0; - -- @ApiModelProperty(value = "婴儿人数", example = "0") -+ @ApiModelProperty(value = "婴儿人数(按固定 babyPrice 计算)", example = "0") - @Min(value = 0, message = "幼童人数不能为负数") - private Integer babyCount = 0; - -- @ApiModelProperty(value = "儿童是否加床", example = "false") -+ @ApiModelProperty(value = "儿童是否加床(true 时额外加收 childWithBed 费用)", example = "false") - private Boolean childNeedBed = false; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/BatchMaterialIdsRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/BatchMaterialIdsRequest.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/BatchMaterialIdsRequest.java -index 46060ff..63b4dc9 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/BatchMaterialIdsRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/BatchMaterialIdsRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -9,7 +11,9 @@ import java.util.List; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("批量素材ID请求") - public class BatchMaterialIdsRequest { - -+ @ApiModelProperty("素材ID列表") - private List materialIds; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchBindRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchBindRequest.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchBindRequest.java -index e859cea..53c0c3d 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchBindRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchBindRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -9,7 +11,9 @@ import java.util.List; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("批量引用绑定请求") - public class RefBatchBindRequest { - -+ @ApiModelProperty("引用绑定列表") - private List refs; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchUnbindRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchUnbindRequest.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchUnbindRequest.java -index 965c0e9..b532ee1 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchUnbindRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBatchUnbindRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -9,7 +11,9 @@ import java.util.List; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("批量引用解绑请求") - public class RefBatchUnbindRequest { - -+ @ApiModelProperty("引用解绑列表") - private List refs; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBindRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBindRequest.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBindRequest.java -index 8d95b02..16fdb65 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBindRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefBindRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -7,11 +9,21 @@ import lombok.NoArgsConstructor; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("引用绑定请求") - public class RefBindRequest { - -+ @ApiModelProperty("素材ID") - private Long materialId; -+ -+ @ApiModelProperty("业务类型") - private String bizType; -+ -+ @ApiModelProperty("业务ID") - private Long bizId; -+ -+ @ApiModelProperty("业务名称") - private String bizName; -+ -+ @ApiModelProperty("用途类型") - private String usageType; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefUnbindRequest.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefUnbindRequest.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefUnbindRequest.java -index 04252db..cdd7901 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefUnbindRequest.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/RefUnbindRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -7,10 +9,18 @@ import lombok.NoArgsConstructor; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("引用解绑请求") - public class RefUnbindRequest { - -+ @ApiModelProperty("素材ID") - private Long materialId; -+ -+ @ApiModelProperty("业务类型") - private String bizType; -+ -+ @ApiModelProperty("业务ID") - private Long bizId; -+ -+ @ApiModelProperty("用途类型") - private String usageType; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourceCoverQuery.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourceCoverQuery.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourceCoverQuery.java -index da0d81d..9188dfb 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourceCoverQuery.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourceCoverQuery.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; -@@ -7,7 +9,12 @@ import lombok.NoArgsConstructor; - @Data - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("资源封面查询") - public class ResourceCoverQuery { -+ -+ @ApiModelProperty("资源类型") - private String resourceType; -+ -+ @ApiModelProperty("资源ID") - private String resourceId; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourcePriceQuery.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourcePriceQuery.java b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourcePriceQuery.java -index 90b98cf..685d2e0 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourcePriceQuery.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/dto/ResourcePriceQuery.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Builder; - import lombok.Data; -@@ -12,16 +14,21 @@ import java.util.List; - @Builder - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("资源价格查询") - public class ResourcePriceQuery { - -+ @ApiModelProperty("资源ID列表") - private List resourceIds; - -+ @ApiModelProperty("人员类型列表") - private List staffTypes; - -+ @ApiModelProperty("开始日期") - private LocalDate startDate; - -+ @ApiModelProperty("结束日期") - private LocalDate endDate; - -- /** resource sub-type (e.g. room_type_id for hotel, vehicle category for vehicle) */ -+ @ApiModelProperty("资源子类型(如酒店房型ID、车辆类别)") - private String subType; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/vo/MaterialVO.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/vo/MaterialVO.java b/hl-product-service/src/main/java/com/hulalv/product/feign/vo/MaterialVO.java -index d072f29..ec5b204 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/vo/MaterialVO.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/vo/MaterialVO.java -@@ -1,13 +1,25 @@ - package com.hulalv.product.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - @Data -+@ApiModel("素材信息VO") - public class MaterialVO { - -+ @ApiModelProperty("素材ID") - private String materialId; -+ -+ @ApiModelProperty("OSS访问URL") - private String ossUrl; -+ -+ @ApiModelProperty("缩略图URL") - private String thumbnailUrl; -+ -+ @ApiModelProperty("素材名称") - private String materialName; -+ -+ @ApiModelProperty("文件类型") - private String fileType; - } -``` - -### `hl-product-service/src/main/java/com/hulalv/product/feign/vo/ResourcePriceVO.java` (M) - -```diff -diff --git a/hl-product-service/src/main/java/com/hulalv/product/feign/vo/ResourcePriceVO.java b/hl-product-service/src/main/java/com/hulalv/product/feign/vo/ResourcePriceVO.java -index 4cf6dae..232915a 100644 ---- a/hl-product-service/src/main/java/com/hulalv/product/feign/vo/ResourcePriceVO.java -+++ b/hl-product-service/src/main/java/com/hulalv/product/feign/vo/ResourcePriceVO.java -@@ -1,5 +1,7 @@ - package com.hulalv.product.feign.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.AllArgsConstructor; - import lombok.Builder; - import lombok.Data; -@@ -12,15 +14,21 @@ import java.time.LocalDate; - @Builder - @NoArgsConstructor - @AllArgsConstructor -+@ApiModel("资源价格VO") - public class ResourcePriceVO { - -+ @ApiModelProperty("资源ID") - private Long resourceId; - -+ @ApiModelProperty("人员类型") - private String staffType; - -+ @ApiModelProperty("日期") - private LocalDate date; - -+ @ApiModelProperty("价格") - private BigDecimal price; - -+ @ApiModelProperty("资源名称") - private String resourceName; - } -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityController.java b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityController.java -index ab64e9e..4015f1e 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityController.java -@@ -26,7 +26,7 @@ public class ActivityController { - - private final ActivityService activityService; - -- @ApiOperation("创建游玩项目") -+ @ApiOperation(value = "创建游玩项目", notes = "新建游玩项目资源(如漂流、骑行、篝火晚会等),初始状态为草稿(status=0)。需通过「提交启用/禁用审批」走企微审批后上架。支持按项收费(PER_ITEM)和按人收费(PER_PERSON)两种计费方式。\n\n**关联字典**:\n- activity_category:活动分类(表单选择)\n- activity_billing_type:计费方式(表单选择)") - @PostMapping("/item") - public Result createActivity( - @ApiParam("游玩项目创建请求") @Valid @RequestBody ActivityCreateRequest request, -@@ -35,19 +35,19 @@ public class ActivityController { - return Result.success(activityService.createActivity(request, adminId)); - } - -- @ApiOperation("游玩项目列表") -+ @ApiOperation(value = "游玩项目列表", notes = "分页查询游玩项目列表,支持按名称、状态、分类等条件筛选。返回摘要信息,按sortOrder倒序+创建时间倒序排列。\n\n**关联字典**:\n- activity_category:活动分类(筛选+列表显示)\n- activity_billing_type:计费方式(列表显示)") - @GetMapping("/items") - public Result> listActivities(@ApiParam("游玩项目查询请求") @Valid ActivityQueryRequest query) { - return Result.success(activityService.listActivities(query)); - } - -- @ApiOperation("游玩项目详情") -+ @ApiOperation(value = "游玩项目详情", notes = "获取游玩项目完整信息,包含富文本内容、素材URL、标签、价格日历等。\n\n**关联字典**:\n- activity_category:活动分类(详情显示)\n- activity_billing_type:计费方式(详情显示)") - @GetMapping("/item/{activityId}") - public Result getActivity(@ApiParam("游玩项目ID") @PathVariable Long activityId) { - return Result.success(activityService.getActivity(activityId)); - } - -- @ApiOperation("更新游玩项目") -+ @ApiOperation(value = "更新游玩项目", notes = "更新游玩项目基本信息,不改变当前状态。已上架的项目修改后仍保持上架。\n\n**关联字典**:\n- activity_category:活动分类(表单选择)\n- activity_billing_type:计费方式(表单选择)") - @PutMapping("/item/{activityId}") - public Result updateActivity( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -57,7 +57,7 @@ public class ActivityController { - return Result.success(activityService.updateActivity(activityId, request, adminId)); - } - -- @ApiOperation("删除游玩项目") -+ @ApiOperation(value = "删除游玩项目", notes = "软删除游玩项目。仅SUPER_ADMIN或创建者可操作。删除后关联的素材引用会被清理。") - @DeleteMapping("/item/{activityId}") - public Result deleteActivity( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -68,7 +68,7 @@ public class ActivityController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交审批。targetStatus=1申请上架,targetStatus=2申请下架。审批通过后自动更新状态,返回审批单号spNo。") - @PostMapping("/item/{activityId}/submit-approval") - public Result> submitApproval( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -80,7 +80,7 @@ public class ActivityController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("启用/禁用切换") -+ @ApiOperation(value = "启用/禁用切换", notes = "直接修改状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/item/{activityId}/status") - public Result updateStatus( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -91,7 +91,7 @@ public class ActivityController { - return Result.success(); - } - -- @ApiOperation("批量启用/禁用") -+ @ApiOperation(value = "批量启用/禁用", notes = "批量修改多个游玩项目的状态,跳过审批流程。") - @PutMapping("/items/batch/status") - public Result batchUpdateStatus( - @ApiParam("游玩项目状态请求") @Valid @RequestBody ActivityStatusRequest request, -@@ -103,7 +103,7 @@ public class ActivityController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个游玩项目。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/items/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityPriceCalendarController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityPriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityPriceCalendarController.java -index 9fec542..3fff48f 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityPriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityPriceCalendarController.java -@@ -25,7 +25,7 @@ public class ActivityPriceCalendarController { - - private final ActivityPriceCalendarService priceService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询游玩项目的每日价格和可接待状态。") - @GetMapping("/item/{activityId}/prices") - public Result getPriceCalendar( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -34,7 +34,7 @@ public class ActivityPriceCalendarController { - return Result.success(priceService.getPriceCalendar(activityId, year, month)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", notes = "在指定日期范围内批量设置成本价和可接待状态。支持按星期过滤和排除特定日期。") - @PutMapping("/item/{activityId}/prices") - public Result batchSetPrices( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -43,7 +43,7 @@ public class ActivityPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改可接待状态") -+ @ApiOperation(value = "批量修改可接待状态", notes = "批量修改指定日期范围内的可接待状态,不影响价格。") - @PutMapping("/item/{activityId}/prices/batch-status") - public Result batchUpdateStatus( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -52,7 +52,7 @@ public class ActivityPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量清除价格") -+ @ApiOperation(value = "批量清除价格", notes = "删除指定日期范围内的所有价格记录。日期格式:yyyy-MM-dd。") - @DeleteMapping("/item/{activityId}/prices") - public Result deletePrices( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityTagController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityTagController.java -index 2a01cd2..80b72a0 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/ActivityTagController.java -@@ -27,7 +27,7 @@ public class ActivityTagController { - - private final ActivityTagService tagService; - -- @ApiOperation("获取管理标签列表(分页)") -+ @ApiOperation(value = "获取管理标签列表(分页)", notes = "分页查询游玩项目标签库,支持按关键词搜索。包含预设标签和自定义标签。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class ActivityTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("获取全部标签") -+ @ApiOperation(value = "获取全部标签", notes = "不分页返回所有标签,用于项目编辑时的标签选择下拉。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建管理标签") -+ @ApiOperation(value = "创建管理标签", notes = "创建预设标签,标签名不可重复。可指定颜色(tagColor),默认#409EFF。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class ActivityTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "按名称查找或自动创建标签。用于项目编辑时快速输入新标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class ActivityTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("编辑标签") -+ @ApiOperation(value = "编辑标签", notes = "修改标签名称或颜色,所有关联项目自动生效。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class ActivityTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并自动解除所有项目与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("更新项目标签") -+ @ApiOperation(value = "更新项目标签", notes = "全量替换指定项目的标签列表。传入tagIds为最终关联的标签ID列表,为空则清除所有标签。") - @PutMapping("/item/{activityId}/tags") - public Result updateActivityTags( - @ApiParam("游玩项目ID") @PathVariable Long activityId, -@@ -87,7 +87,7 @@ public class ActivityTagController { - return Result.success(); - } - -- @ApiOperation("批量打标签") -+ @ApiOperation(value = "批量打标签", notes = "对多个项目批量添加/移除标签。增量操作,不影响未指定的标签。") - @PutMapping("/items/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalActivityController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalActivityController.java b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalActivityController.java -index e24ce98..1b5dd8f 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalActivityController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalActivityController.java -@@ -17,7 +17,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】游玩项目(Feign调用)") -+@Api(tags = "【内部接口】游玩项目(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/activity") - @RequiredArgsConstructor -@@ -25,7 +25,7 @@ public class InternalActivityController { - - private final ActivityService activityService; - -- @ApiOperation("获取项目简要信息") -+ @ApiOperation(value = "获取项目简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个游玩项目的简要信息,返回ID、名称、分类编码、计费类型、状态。不存在时返回错误。\n\n**关联字典**:\n- activity_category(活动分类,返回字段categoryCode):OUTDOOR=户外, INDOOR=室内, CULTURAL=文化, ADVENTURE=探险\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/item/{activityId}") - public Result> getActivityBrief(@PathVariable Long activityId) { - Activity item = activityService.getActivityEntity(activityId); -@@ -41,7 +41,7 @@ public class InternalActivityController { - return Result.success(brief); - } - -- @ApiOperation("批量获取项目简要信息") -+ @ApiOperation(value = "批量获取项目简要信息", notes = "【仅限内部Feign调用】批量获取游玩项目简要信息,最多500个ID。不存在的ID自动过滤,返回实际找到的项目列表。供产品服务批量查询行程节点绑定的活动资源。\n\n**关联字典**:\n- activity_category(活动分类,返回字段categoryCode):OUTDOOR=户外, INDOOR=室内, CULTURAL=文化, ADVENTURE=探险\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/items/batch") - public Result>> getActivityBatch(@RequestParam @Size(max = 500) List activityIds) { - List> results = activityIds.stream() -@@ -61,9 +61,9 @@ public class InternalActivityController { - return Result.success(results); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo(审批单号)匹配游玩项目并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - activityService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalMpActivityController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalMpActivityController.java b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalMpActivityController.java -index 63164c0..03e9f1d 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalMpActivityController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/activity/controller/InternalMpActivityController.java -@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.*; - /** - * C端活动内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - */ --@Api(tags = "【内部接口】小程序活动(Feign调用)") -+@Api(tags = "【内部接口】小程序活动(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/activity") - @RequiredArgsConstructor -@@ -22,14 +22,14 @@ public class InternalMpActivityController { - - private final ActivityService activityService; - -- @ApiOperation("C端活动列表") -+ @ApiOperation(value = "C端活动列表", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用。强制status=1只返回已上架活动,支持分页和筛选。C端用户通过小程序间接访问。\n\n**关联字典**:\n- activity_category(活动分类,返回字段categoryCode):OUTDOOR=户外, INDOOR=室内, CULTURAL=文化, ADVENTURE=探险\n- environment_type(环境类型,返回字段environmentType):INDOOR=室内, OUTDOOR=户外, MIXED=混合") - @GetMapping("/list") - public Result> listActivities(ActivityQueryRequest query) { - query.setStatus(1); - return Result.success(activityService.listActivities(query)); - } - -- @ApiOperation("C端活动详情") -+ @ApiOperation(value = "C端活动详情", notes = "【仅限内部Feign调用】供mp-service获取活动完整详情,包含封面、轮播图、标签、富文本介绍等。注意:不限制status,由BFF层校验是否展示。\n\n**关联字典**:\n- activity_category(活动分类,返回字段categoryCode):OUTDOOR=户外, INDOOR=室内, CULTURAL=文化, ADVENTURE=探险\n- environment_type(环境类型,返回字段environmentType):INDOOR=室内, OUTDOOR=户外, MIXED=混合") - @GetMapping("/{activityId}") - public Result getActivityDetail(@PathVariable Long activityId) { - ActivityVO vo = activityService.getActivity(activityId); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/config/Knife4jConfig.java b/hl-resource-service/src/main/java/com/hulalv/resource/config/Knife4jConfig.java -index 88feb5b..21cce9b 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/config/Knife4jConfig.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/config/Knife4jConfig.java -@@ -1,5 +1,6 @@ - package com.hulalv.resource.config; - -+import com.google.common.base.Predicate; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import springfox.documentation.builders.ApiInfoBuilder; -@@ -11,12 +12,18 @@ import springfox.documentation.spring.web.plugins.Docket; - /** - * Knife4j API文档配置(9个资源领域分组) - *

-- * 为每个资源领域创建独立的API文档分组,便于分类查阅接口 -+ * 为每个资源领域创建独立的API文档分组,便于分类查阅接口。 -+ * 内部Feign接口(/internal/路径)不在文档中展示。 - *

- */ - @Configuration - public class Knife4jConfig { - -+ /** 排除内部接口路径 */ -+ private Predicate adminPaths() { -+ return input -> input != null && !input.contains("/internal/") && !input.contains("/callback/"); -+ } -+ - /** 景区管理API分组 */ - @Bean - public Docket scenicApi() { -@@ -29,7 +36,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.resource.scenic.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - -@@ -45,7 +52,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.resource.restaurant.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - -@@ -61,7 +68,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.resource.supplies.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - -@@ -77,7 +84,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.resource.activity.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - -@@ -93,7 +100,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.resource.hotel.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - -@@ -109,7 +116,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.resource.service.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - -@@ -125,7 +132,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.resource.vehicle.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - -@@ -141,7 +148,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.resource.cost.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - -@@ -157,7 +164,7 @@ public class Knife4jConfig { - .build()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.hulalv.resource.staff.controller")) -- .paths(PathSelectors.any()) -+ .paths(adminPaths()) - .build(); - } - } -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalMpResourceBriefController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalMpResourceBriefController.java b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalMpResourceBriefController.java -index 3fcaf95..a7c45f5 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalMpResourceBriefController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalMpResourceBriefController.java -@@ -40,7 +40,7 @@ import java.util.stream.Collectors; - */ - @Slf4j - @Validated --@Api(tags = "【内部接口】资源摘要(Feign调用)") -+@Api(tags = "【内部接口】资源摘要(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/resource") - @RequiredArgsConstructor -@@ -60,7 +60,7 @@ public class InternalMpResourceBriefController { - - private final MaterialRefFeignClient materialRefClient; - -- @ApiOperation("批量查询景区摘要") -+ @ApiOperation(value = "批量查询景区摘要", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用(收藏列表/足迹列表),返回最小化信息:id、name、coverUrl、tags。最多500个ID。") - @GetMapping("/scenic/brief") - public Result>> getScenicBrief(@RequestParam @Size(max = 500) List ids) { - if (ids == null || ids.isEmpty()) { -@@ -94,7 +94,7 @@ public class InternalMpResourceBriefController { - return Result.success(result); - } - -- @ApiOperation("批量查询餐厅摘要") -+ @ApiOperation(value = "批量查询餐厅摘要", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用,返回最小化信息。最多500个ID。") - @GetMapping("/restaurant/brief") - public Result>> getRestaurantBrief(@RequestParam @Size(max = 500) List ids) { - if (ids == null || ids.isEmpty()) { -@@ -126,7 +126,7 @@ public class InternalMpResourceBriefController { - return Result.success(result); - } - -- @ApiOperation("批量查询活动摘要") -+ @ApiOperation(value = "批量查询活动摘要", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用,返回最小化信息。最多500个ID。") - @GetMapping("/activity/brief") - public Result>> getActivityBrief(@RequestParam @Size(max = 500) List ids) { - if (ids == null || ids.isEmpty()) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceController.java b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceController.java -index d4158a8..44cd22e 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceController.java -@@ -25,7 +25,7 @@ import org.springframework.web.bind.annotation.*; - *

- */ - @Slf4j --@Api(tags = "【内部接口】资源审批(Feign调用)") -+@Api(tags = "【内部接口】资源审批(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/resource") - @RequiredArgsConstructor -@@ -42,9 +42,9 @@ public class InternalResourceController { - private final StaffService staffService; - - /** 处理审批回调 - 分发到9个资源领域服务 */ -- @ApiOperation("处理审批回调 - 分发到9个资源领域服务") -+ @ApiOperation(value = "处理审批回调 - 分发到9个资源领域服务", notes = "【仅限内部Feign调用】接收企微审批回调结果,按thirdNo(审批单号)在9个资源领域中匹配并更新状态。每个领域服务内部通过approval_no匹配,未找到则忽略(幂等处理)。由hl-callback-service通过MQ消费后调用。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - - // 分发到9个领域服务 - 每个服务内部检查approval_no -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceDetailController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceDetailController.java b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceDetailController.java -index a6adb66..e726a14 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceDetailController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceDetailController.java -@@ -41,7 +41,7 @@ import java.util.stream.Collectors; - * 供产品服务的行程节点获取绑定资源的详细信息(含图片、地址等) - */ - @Slf4j --@Api(tags = "【内部接口】资源详情(Feign调用)") -+@Api(tags = "【内部接口】资源详情(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/resource") - @RequiredArgsConstructor -@@ -69,7 +69,7 @@ public class InternalResourceDetailController { - * @param activityIds 活动ID列表 - * @return resourceType:resourceId → ResourceDetailDTO - */ -- @ApiOperation("批量查询资源详情(行程节点用)") -+ @ApiOperation(value = "批量查询资源详情(行程节点用)", notes = "【仅限内部Feign调用】供产品服务获取行程节点绑定资源的详细信息。按类型分组查询,返回Map。包含封面、轮播图URL、地址、坐标、标签、富文本介绍等完整信息。\n\n**关联字典**:\n- city(城市,返回字段city)") - @GetMapping("/batch-details") - public Result> batchDetails( - @RequestParam(required = false) List scenicIds, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourcePriceController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourcePriceController.java b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourcePriceController.java -index 366168b..e1ddd03 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourcePriceController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourcePriceController.java -@@ -53,7 +53,7 @@ import java.util.stream.Collectors; - @RestController - @RequestMapping("/internal/resource/prices") - @RequiredArgsConstructor --@Api(tags = "【内部接口】资源价格(Feign调用)") -+@Api(tags = "【内部接口】资源价格(Feign调用)", hidden = true) - public class InternalResourcePriceController { - - private final ScenicPriceCalendarMapper scenicPriceMapper; -@@ -71,7 +71,7 @@ public class InternalResourcePriceController { - private final SuppliesItemMapper suppliesItemMapper; - private final SuppliesService suppliesService; - -- /** 查询景区价格 */ -+ /** 查询景区价格 - 按景区ID和日期范围查询价格日历的成本价 */ - @PostMapping("/scenic") - public Result> getScenicPrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -108,7 +108,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询酒店价格(按hotelId查最低房型价格) */ -+ /** 查询酒店价格 - 按hotelId查询日期范围内最低房型的成本价(取所有房型中最低价) */ - @PostMapping("/hotel") - public Result> getHotelPrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -143,7 +143,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询房型价格(按roomTypeId精确查询) */ -+ /** 查询房型价格 - 按roomTypeId精确查询日期范围内的成本价(取最低价) */ - @PostMapping("/room-type") - public Result> getRoomTypePrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -178,7 +178,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询活动价格 */ -+ /** 查询活动价格 - 按活动ID和日期范围查询价格日历的成本价 */ - @PostMapping("/activity") - public Result> getActivityPrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -214,7 +214,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询车辆价格 */ -+ /** 查询车辆价格 - 按车型ID和日期范围查询价格日历的成本价 */ - @PostMapping("/vehicle") - public Result> getVehiclePrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -250,7 +250,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询服务项价格 */ -+ /** 查询服务项价格 - 按服务项ID和日期范围查询价格日历的成本价 */ - @PostMapping("/service") - public Result> getServicePrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -283,13 +283,13 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询餐厅价格(餐厅无价格日历,返回空) */ -+ /** 查询餐厅价格 - 餐厅无独立价格日历,始终返回空列表(餐费通过费用项管理) */ - @PostMapping("/restaurant") - public Result> getRestaurantPrices(@RequestBody PriceQuery query) { - return Result.success(new ArrayList<>()); - } - -- /** 查询服务人员价格(按人员类型) */ -+ /** 查询服务人员价格 - 按staffType(人员类型)和日期范围查询价格日历的成本价(人员价格按类型而非个人) */ - @PostMapping("/staff") - public Result> getStaffPrices(@RequestBody PriceQuery query) { - List results = new ArrayList<>(); -@@ -321,7 +321,7 @@ public class InternalResourcePriceController { - return Result.success(results); - } - -- /** 查询酒店下所有房型(简要信息) */ -+ /** 查询酒店下所有已启用房型 - 返回roomTypeId、name、maxOccupancy、basePrice,按sortOrder排序 */ - @GetMapping("/room-types-by-hotel/{hotelId}") - public Result> getRoomTypesByHotel(@PathVariable Long hotelId) { - List roomTypes = roomTypeMapper.selectList( -@@ -336,7 +336,7 @@ public class InternalResourcePriceController { - return Result.success(vos); - } - -- /** 查询所有可用车型(简要信息) */ -+ /** 查询所有已启用车型 - 返回vehicleId、name、seatCount、basePrice,按sortOrder排序,供产品服务车辆下拉选择使用 */ - @GetMapping("/vehicle-models") - public Result> getVehicleModels() { - List vehicles = vehicleModelMapper.selectList( -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceStatsController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceStatsController.java b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceStatsController.java -index 019a26f..3ef23db 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceStatsController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/controller/InternalResourceStatsController.java -@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RestController; - import java.util.HashMap; - import java.util.Map; - --@Api(tags = "【内部接口】资源统计(Feign调用)") -+@Api(tags = "【内部接口】资源统计(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/resource") - @RequiredArgsConstructor -@@ -24,7 +24,7 @@ public class InternalResourceStatsController { - private final RoomTypeMapper roomTypeMapper; - private final VehicleModelMapper vehicleModelMapper; - -- @ApiOperation("获取酒店统计") -+ @ApiOperation(value = "获取酒店统计", notes = "【仅限内部Feign调用】返回酒店总数和房型总数,供管理后台仪表盘展示。") - @GetMapping("/hotel/stats") - public Result> getHotelStats() { - long totalHotels = hotelMapper.selectCount(null); -@@ -36,7 +36,7 @@ public class InternalResourceStatsController { - return Result.success(stats); - } - -- @ApiOperation("获取车辆统计") -+ @ApiOperation(value = "获取车辆统计", notes = "【仅限内部Feign调用】返回车型总数,供管理后台仪表盘展示。") - @GetMapping("/vehicle/stats") - public Result> getVehicleStats() { - long totalVehicles = vehicleModelMapper.selectCount(null); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostItemController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostItemController.java b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostItemController.java -index ce21f8c..b138078 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostItemController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostItemController.java -@@ -28,7 +28,7 @@ public class CostItemController { - - private final CostItemService costItemService; - -- @ApiOperation("创建费用项") -+ @ApiOperation(value = "创建费用项", notes = "新建费用项(如门票成本、餐费、保险费等),用于产品报价计算。费用项有独立的价格日历,价格变更会记录变更日志。创建后需走企微审批上架。\n\n**关联字典**:\n- cost_category:费用分类(表单选择)\n- cost_apply_role:适用角色(表单选择)\n- cost_unit:计量单位(表单选择)") - @PostMapping("/item") - public Result createCostItem(@ApiParam("费用项创建请求") @Valid @RequestBody CostItemCreateRequest request, - HttpServletRequest httpRequest) { -@@ -36,19 +36,19 @@ public class CostItemController { - return Result.success(costItemService.createCostItem(request, adminId)); - } - -- @ApiOperation("费用项列表") -+ @ApiOperation(value = "费用项列表", notes = "分页查询费用项列表,支持按名称、状态等条件筛选。\n\n**关联字典**:\n- cost_category:费用分类(筛选+列表显示)\n- cost_apply_role:适用角色(筛选+列表显示)\n- cost_unit:计量单位(列表显示)") - @GetMapping("/items") - public Result> listCostItems(@ApiParam("费用项查询请求") @Valid CostItemQueryRequest query) { - return Result.success(costItemService.listCostItems(query)); - } - -- @ApiOperation("费用项详情") -+ @ApiOperation(value = "费用项详情", notes = "获取费用项完整信息,包含当前价格、引用计数等。\n\n**关联字典**:\n- cost_category:费用分类(详情显示)\n- cost_apply_role:适用角色(详情显示)\n- cost_unit:计量单位(详情显示)") - @GetMapping("/item/{costId}") - public Result getCostItem(@ApiParam("费用项ID") @PathVariable Long costId) { - return Result.success(costItemService.getCostItem(costId)); - } - -- @ApiOperation("更新费用项") -+ @ApiOperation(value = "更新费用项", notes = "更新费用项信息。如果修改了价格,会自动记录价格变更日志。\n\n**关联字典**:\n- cost_category:费用分类(表单选择)\n- cost_apply_role:适用角色(表单选择)\n- cost_unit:计量单位(表单选择)") - @PutMapping("/item/{costId}") - public Result updateCostItem(@ApiParam("费用项ID") @PathVariable Long costId, - @ApiParam("费用项更新请求") @Valid @RequestBody CostItemUpdateRequest request, -@@ -57,7 +57,7 @@ public class CostItemController { - return Result.success(costItemService.updateCostItem(costId, request, adminId)); - } - -- @ApiOperation("删除费用项") -+ @ApiOperation(value = "删除费用项", notes = "软删除费用项。仅SUPER_ADMIN或创建者可操作。被产品引用(refCount>0)的费用项不建议删除。") - @DeleteMapping("/item/{costId}") - public Result deleteCostItem(@ApiParam("费用项ID") @PathVariable Long costId, HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -@@ -66,7 +66,7 @@ public class CostItemController { - return Result.success(); - } - -- @ApiOperation("提交审批") -+ @ApiOperation(value = "提交审批", notes = "向企微OA提交费用项启用/禁用审批。targetStatus=1申请上架,targetStatus=2申请下架。返回审批单号spNo。") - @PostMapping("/item/{costId}/submit-approval") - public Result> submitApproval(@ApiParam("费用项ID") @PathVariable Long costId, - @ApiParam("审批提交请求体") @Valid @RequestBody ApprovalSubmitRequest request, -@@ -76,13 +76,13 @@ public class CostItemController { - return Result.success(java.util.Map.of("spNo", spNo)); - } - -- @ApiOperation("启用的费用项列表") -+ @ApiOperation(value = "启用的费用项列表", notes = "查询所有已启用(status=1)的费用项,不分页。用于产品编排时选择费用项的下拉列表。\n\n**关联字典**:\n- cost_category:费用分类(列表显示)\n- cost_apply_role:适用角色(列表显示)\n- cost_unit:计量单位(列表显示)") - @GetMapping("/items/enabled") - public Result> listEnabledCostItems() { - return Result.success(costItemService.listEnabledCostItems()); - } - -- @ApiOperation("费用项价格变更记录") -+ @ApiOperation(value = "费用项价格变更记录", notes = "查询费用项的历史价格变更记录,按时间倒序排列。用于追溯价格调整历史。") - @GetMapping("/item/{costId}/price-logs") - public Result> getPriceLogs(@ApiParam("费用项ID") @PathVariable Long costId) { - return Result.success(costItemService.getPriceLogs(costId)); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostPriceCalendarController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostPriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostPriceCalendarController.java -index 862c1b2..95007f0 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostPriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/CostPriceCalendarController.java -@@ -26,7 +26,7 @@ public class CostPriceCalendarController { - - private final CostPriceCalendarService priceCalendarService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询费用项的每日价格。费用项价格日历用于产品报价计算时按日期获取成本价。") - @GetMapping("/item/{costId}/prices") - public Result getPriceCalendar(@ApiParam("费用项ID") @PathVariable Long costId, - @ApiParam("年份") @RequestParam @Min(2020) @Max(2100) Integer year, -@@ -34,7 +34,7 @@ public class CostPriceCalendarController { - return Result.success(priceCalendarService.getPriceCalendar(costId, year, month)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", notes = "在指定日期范围内批量设置费用项的成本价。") - @PutMapping("/item/{costId}/prices") - public Result batchSetPrices(@ApiParam("费用项ID") @PathVariable Long costId, - @ApiParam("价格日历设置请求") @Valid @RequestBody PriceCalendarSetRequest request) { -@@ -42,7 +42,7 @@ public class CostPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("清除价格日历") -+ @ApiOperation(value = "清除价格日历", notes = "删除指定日期范围内费用项的价格记录。日期格式:yyyy-MM-dd。") - @DeleteMapping("/item/{costId}/prices") - public Result deletePrices(@ApiParam("费用项ID") @PathVariable Long costId, - @ApiParam("开始日期") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/InternalCostController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/InternalCostController.java b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/InternalCostController.java -index 5e27f64..361c8de 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/InternalCostController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/cost/controller/InternalCostController.java -@@ -20,7 +20,7 @@ import java.util.Map; - - @Slf4j - @Validated --@Api(tags = "【内部接口】费用项(Feign调用)") -+@Api(tags = "【内部接口】费用项(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/cost") - @RequiredArgsConstructor -@@ -28,21 +28,21 @@ public class InternalCostController { - - private final CostItemService costItemService; - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配费用项并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - costItemService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); - } - -- @ApiOperation("批量获取费用项") -+ @ApiOperation(value = "批量获取费用项", notes = "【仅限内部Feign调用】批量获取费用项完整信息(含名称、分类、计费类型、基础价格等),最多500个ID。供产品服务批量查询产品关联的费用项。\n\n**关联字典**:\n- cost_unit(计费单位,返回字段unit):PER_PERSON=元/人, PER_VEHICLE=元/台, PER_DAY=元/天, PER_TIME=元/次, PER_ROOM=元/间, PER_TABLE=元/桌, FIXED=固定金额\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/items/batch") - public Result> batchGetCostItems(@RequestParam @Size(max = 500) List costIds) { - return Result.success(costItemService.batchGetCostItems(costIds)); - } - -- @ApiOperation("按日期获取费用项价格") -+ @ApiOperation(value = "按日期获取费用项价格", notes = "【仅限内部Feign调用】按指定日期批量查询费用项的成本价格。返回Map。优先取价格日历,无日历则取basePrice。供产品服务报价计算器使用。") - @GetMapping("/items/prices-by-date") - public Result> getByDatePrices( - @RequestParam @Size(max = 500) List costIds, -@@ -50,7 +50,7 @@ public class InternalCostController { - return Result.success(costItemService.getByDatePrices(costIds, date)); - } - -- @ApiOperation("更新引用计数") -+ @ApiOperation(value = "更新引用计数", notes = "【仅限内部Feign调用】更新费用项的引用计数。delta>0表示新增引用,delta<0表示减少引用。供产品服务在关联/取消关联费用项时调用,用于统计资源被使用次数。") - @PostMapping("/item/{costId}/ref-count") - public Result updateRefCount(@PathVariable Long costId, @RequestParam int delta) { - costItemService.updateRefCount(costId, delta); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelController.java -index 4a0c2c5..7faaef1 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelController.java -@@ -26,7 +26,7 @@ public class HotelController { - - private final HotelService hotelService; - -- @ApiOperation("创建住宿") -+ @ApiOperation(value = "创建住宿", notes = "新建住宿资源(酒店/民宿/营地等),初始状态为草稿(status=0)。创建后需通过「提交启用/禁用审批」走企微OA审批流程才能上架。住宿下可继续创建房型(RoomType),房型有独立的价格日历。\n\n**关联字典**:\n- hotel_type:住宿类型(表单选择)\n- hotel_star_level:酒店星级(表单选择)\n- hotel_facility:酒店设施(表单多选)") - @PostMapping("/item") - public Result createHotel( - @ApiParam("住宿创建请求") @Valid @RequestBody HotelCreateRequest request, -@@ -35,25 +35,25 @@ public class HotelController { - return Result.success(hotelService.createHotel(request, adminId)); - } - -- @ApiOperation("住宿列表") -+ @ApiOperation(value = "住宿列表", notes = "分页查询住宿列表,支持按名称关键词、状态、住宿类型等条件筛选。返回列表摘要信息,按sortOrder倒序+创建时间倒序排列。\n\n**关联字典**:\n- hotel_type:住宿类型(筛选+列表显示)\n- hotel_star_level:酒店星级(筛选+列表显示)\n- hotel_facility:酒店设施(列表显示)") - @GetMapping("/items") - public Result> listHotels(@ApiParam("住宿查询请求") @Valid HotelQueryRequest query) { - return Result.success(hotelService.listHotels(query)); - } - -- @ApiOperation("所有启用的住宿(不分页,仅ID和名称)") -+ @ApiOperation(value = "所有启用的住宿(不分页,仅ID和名称)", notes = "返回所有已上架(status=1)的住宿简要信息,用于下拉选择框。每项只含hotelId和name字段。适用于房型管理时选择所属住宿、产品编排时绑定住宿资源等场景。") - @GetMapping("/items/all-simple") - public Result>> listAllSimple() { - return Result.success(hotelService.listAllSimple()); - } - -- @ApiOperation("住宿详情") -+ @ApiOperation(value = "住宿详情", notes = "获取住宿完整信息,包含素材URL、标签列表、房型列表等。素材ID会自动解析为OSS访问地址。\n\n**关联字典**:\n- hotel_type:住宿类型(详情显示)\n- hotel_star_level:酒店星级(详情显示)\n- hotel_facility:酒店设施(详情显示)") - @GetMapping("/item/{hotelId}") - public Result getHotel(@ApiParam("住宿ID") @PathVariable Long hotelId) { - return Result.success(hotelService.getHotel(hotelId)); - } - -- @ApiOperation("更新住宿") -+ @ApiOperation(value = "更新住宿", notes = "更新住宿基本信息。更新不会改变当前状态,已上架的住宿修改后仍保持上架状态。\n\n**关联字典**:\n- hotel_type:住宿类型(表单选择)\n- hotel_star_level:酒店星级(表单选择)\n- hotel_facility:酒店设施(表单多选)") - @PutMapping("/item/{hotelId}") - public Result updateHotel( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -63,7 +63,7 @@ public class HotelController { - return Result.success(hotelService.updateHotel(hotelId, request, adminId)); - } - -- @ApiOperation("删除住宿") -+ @ApiOperation(value = "删除住宿", notes = "软删除住宿。仅SUPER_ADMIN或创建者可操作。删除住宿会同时删除其下所有房型和价格日历数据。") - @DeleteMapping("/item/{hotelId}") - public Result deleteHotel( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -74,7 +74,7 @@ public class HotelController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交住宿启用/禁用审批。targetStatus=1申请上架,targetStatus=2申请下架。审批通过后自动更新状态。返回企微审批单号spNo。") - @PostMapping("/item/{hotelId}/submit-approval") - public Result> submitApproval( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -86,7 +86,7 @@ public class HotelController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("启用/禁用切换") -+ @ApiOperation(value = "启用/禁用切换", notes = "直接修改住宿状态(跳过审批),仅限SUPER_ADMIN使用。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/item/{hotelId}/status") - public Result updateStatus( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -97,7 +97,7 @@ public class HotelController { - return Result.success(); - } - -- @ApiOperation("批量启用/禁用") -+ @ApiOperation(value = "批量启用/禁用", notes = "批量修改多个住宿的状态,跳过审批流程。hotelIds为住宿ID列表(字符串格式)。") - @PutMapping("/items/batch/status") - public Result batchUpdateStatus( - @ApiParam("住宿状态请求") @Valid @RequestBody HotelStatusRequest request, -@@ -109,7 +109,7 @@ public class HotelController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个住宿及其关联的房型和价格日历。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/items/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelTagController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelTagController.java -index 3b229f8..02e8708 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/HotelTagController.java -@@ -27,7 +27,7 @@ public class HotelTagController { - - private final HotelTagService tagService; - -- @ApiOperation("预设标签列表(分页)") -+ @ApiOperation(value = "预设标签列表(分页)", notes = "分页查询住宿标签库,支持按关键词搜索。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class HotelTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("所有标签列表") -+ @ApiOperation(value = "所有标签列表", notes = "不分页返回所有标签,用于住宿编辑时的标签选择。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建标签") -+ @ApiOperation(value = "创建标签", notes = "创建预设标签,标签名不可重复。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class HotelTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("查找或创建自定义标签") -+ @ApiOperation(value = "查找或创建自定义标签", notes = "按名称查找标签,不存在则自动创建。用于住宿编辑时快速输入新标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class HotelTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("更新标签") -+ @ApiOperation(value = "更新标签", notes = "修改标签名称或颜色,所有关联住宿自动生效。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class HotelTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并解除所有住宿与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("设置住宿标签") -+ @ApiOperation(value = "设置住宿标签", notes = "全量替换指定住宿的标签列表。") - @PutMapping("/item/{hotelId}/tags") - public Result updateHotelTags( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -87,7 +87,7 @@ public class HotelTagController { - return Result.success(); - } - -- @ApiOperation("批量添加/移除标签") -+ @ApiOperation(value = "批量添加/移除标签", notes = "对多个住宿批量添加/移除标签。增量操作,不影响未指定的标签。") - @PutMapping("/items/batch/tags") - public Result batchUpdateTags(@ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { - List hotelIds = request.getHotelIds().stream() -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalHotelController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalHotelController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalHotelController.java -index c758f6e..4b81939 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalHotelController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalHotelController.java -@@ -18,7 +18,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】住宿(Feign调用)") -+@Api(tags = "【内部接口】住宿(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/hotel") - @RequiredArgsConstructor -@@ -27,7 +27,7 @@ public class InternalHotelController { - private final HotelService hotelService; - private final RoomTypeService roomTypeService; - -- @ApiOperation("获取住宿简要信息") -+ @ApiOperation(value = "获取住宿简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个住宿的简要信息,返回ID、名称、住宿类型、状态。不存在时返回错误。\n\n**关联字典**:\n- hotel_type(住宿类型,返回字段hotelType):HOTEL=酒店, GUESTHOUSE=民宿, RESORT=度假村, CAMP=营地, HOMESTAY=农家院\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/item/{hotelId}") - public Result> getHotelBrief(@PathVariable Long hotelId) { - Hotel item = hotelService.getHotelEntity(hotelId); -@@ -42,7 +42,7 @@ public class InternalHotelController { - return Result.success(brief); - } - -- @ApiOperation("批量获取住宿简要信息") -+ @ApiOperation(value = "批量获取住宿简要信息", notes = "【仅限内部Feign调用】批量获取住宿简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询行程节点绑定的住宿资源。\n\n**关联字典**:\n- hotel_type(住宿类型,返回字段hotelType):HOTEL=酒店, GUESTHOUSE=民宿, RESORT=度假村, CAMP=营地, HOMESTAY=农家院\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/items/batch") - public Result>> getHotelBatch(@RequestParam @Size(max = 500) List hotelIds) { - List> results = hotelIds.stream() -@@ -61,9 +61,9 @@ public class InternalHotelController { - return Result.success(results); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配住宿和房型并更新启用/禁用状态。住宿和房型共享同一审批模板,此接口同时尝试匹配两者。由hl-callback-service通过MQ消费后调用。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - hotelService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - // Also try room type (same template, same callback) -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalMpHotelController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalMpHotelController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalMpHotelController.java -index ce4fd47..2a820f5 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalMpHotelController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/InternalMpHotelController.java -@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.*; - /** - * C端住宿内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - */ --@Api(tags = "【内部接口】小程序酒店(Feign调用)") -+@Api(tags = "【内部接口】小程序酒店(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/hotel") - @RequiredArgsConstructor -@@ -22,7 +22,7 @@ public class InternalMpHotelController { - - private final HotelService hotelService; - -- @ApiOperation("C端住宿列表") -+ @ApiOperation(value = "C端住宿列表", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用。强制status=1只返回已上架住宿,支持分页和筛选。C端用户通过小程序间接访问。\n\n**关联字典**:\n- hotel_type(住宿类型,返回字段hotelType):HOTEL=酒店, GUESTHOUSE=民宿, RESORT=度假村, CAMP=营地, HOMESTAY=农家院\n- hotel_star(星级,返回字段starLevel):FIVE=五星, FOUR=四星, THREE=三星, UNRATED=未评级") - @GetMapping("/list") - public Result> listHotels(HotelQueryRequest query) { - // Force status=1 for C-side (only show published hotels) -@@ -30,7 +30,7 @@ public class InternalMpHotelController { - return Result.success(hotelService.listHotels(query)); - } - -- @ApiOperation("C端住宿详情") -+ @ApiOperation(value = "C端住宿详情", notes = "【仅限内部Feign调用】供mp-service获取住宿完整详情,包含房型列表、封面、轮播图、地址等。注意:不限制status,由BFF层校验是否展示。\n\n**关联字典**:\n- hotel_type(住宿类型,返回字段hotelType):HOTEL=酒店, GUESTHOUSE=民宿, RESORT=度假村, CAMP=营地, HOMESTAY=农家院\n- hotel_star(星级,返回字段starLevel):FIVE=五星, FOUR=四星, THREE=三星, UNRATED=未评级") - @GetMapping("/{hotelId}") - public Result getHotelDetail(@PathVariable Long hotelId) { - HotelVO vo = hotelService.getHotel(hotelId); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomPriceCalendarController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomPriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomPriceCalendarController.java -index cf6df6c..d883d85 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomPriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomPriceCalendarController.java -@@ -25,7 +25,7 @@ public class RoomPriceCalendarController { - - private final RoomPriceCalendarService priceCalendarService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询房型的每日价格和可售状态。每个房型有独立的价格日历。") - @GetMapping("/room-type/{roomTypeId}/prices") - public Result getPriceCalendar( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -@@ -34,7 +34,7 @@ public class RoomPriceCalendarController { - return Result.success(priceCalendarService.getPriceCalendar(roomTypeId, year, month)); - } - -- @ApiOperation("批量设置价格日历") -+ @ApiOperation(value = "批量设置价格日历", notes = "在指定日期范围内批量设置房型的成本价和可售状态。支持按星期过滤和排除特定日期。") - @PutMapping("/room-type/{roomTypeId}/prices") - public Result batchSetPrices( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -@@ -43,7 +43,7 @@ public class RoomPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改日期可售状态") -+ @ApiOperation(value = "批量修改日期可售状态", notes = "批量修改指定日期范围内房型的可售状态,不影响价格。") - @PutMapping("/room-type/{roomTypeId}/prices/batch-status") - public Result batchUpdateStatus( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -@@ -52,7 +52,7 @@ public class RoomPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("删除价格日历") -+ @ApiOperation(value = "删除价格日历", notes = "删除指定日期范围内房型的所有价格记录。日期格式:yyyy-MM-dd。") - @DeleteMapping("/room-type/{roomTypeId}/prices") - public Result deletePrices( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomTypeController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomTypeController.java b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomTypeController.java -index 2048f4c..0d9cf42 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomTypeController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/hotel/controller/RoomTypeController.java -@@ -26,7 +26,7 @@ public class RoomTypeController { - - private final RoomTypeService roomTypeService; - -- @ApiOperation("创建房型") -+ @ApiOperation(value = "创建房型", notes = "在指定住宿下创建房型(如标准间、大床房、套房等)。每个房型有独立的价格日历、最大入住人数(maxOccupancy)和基础价格(basePrice)。房型初始状态为草稿(status=0),需独立审批后才能启用。创建后可通过「提交房型启用审批」接口提交企微OA审批。\n\n**关联字典**:\n- room_category:房型分类(表单选择)\n- bed_type:床型(表单选择)\n- window_type:窗户类型(表单选择)\n- bathroom_type:卫浴类型(表单选择)\n- room_facility:房间设施(表单多选)") - @PostMapping("/{hotelId}/room-type") - public Result createRoomType( - @ApiParam("住宿ID") @PathVariable Long hotelId, -@@ -36,19 +36,19 @@ public class RoomTypeController { - return Result.success(roomTypeService.createRoomType(hotelId, request, adminId)); - } - -- @ApiOperation("房型列表") -+ @ApiOperation(value = "房型列表", notes = "获取指定住宿下的所有房型列表(不分页),按sortOrder排序。\n\n**关联字典**:\n- room_category:房型分类(列表/详情显示)\n- bed_type:床型(列表/详情显示)\n- window_type:窗户类型(列表/详情显示)\n- bathroom_type:卫浴类型(列表/详情显示)\n- room_facility:房间设施(列表/详情显示)") - @GetMapping("/{hotelId}/room-types") - public Result> listRoomTypes(@ApiParam("住宿ID") @PathVariable Long hotelId) { - return Result.success(roomTypeService.listRoomTypes(hotelId)); - } - -- @ApiOperation("房型详情") -+ @ApiOperation(value = "房型详情", notes = "获取房型完整信息,包含价格、入住人数、素材等。\n\n**关联字典**:\n- room_category:房型分类(列表/详情显示)\n- bed_type:床型(列表/详情显示)\n- window_type:窗户类型(列表/详情显示)\n- bathroom_type:卫浴类型(列表/详情显示)\n- room_facility:房间设施(列表/详情显示)") - @GetMapping("/room-type/{roomTypeId}") - public Result getRoomType(@ApiParam("房型ID") @PathVariable Long roomTypeId) { - return Result.success(roomTypeService.getRoomType(roomTypeId)); - } - -- @ApiOperation("更新房型") -+ @ApiOperation(value = "更新房型", notes = "更新房型基本信息,不改变当前状态。\n\n**关联字典**:\n- room_category:房型分类(表单选择)\n- bed_type:床型(表单选择)\n- window_type:窗户类型(表单选择)\n- bathroom_type:卫浴类型(表单选择)\n- room_facility:房间设施(表单多选)") - @PutMapping("/room-type/{roomTypeId}") - public Result updateRoomType( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -@@ -58,14 +58,14 @@ public class RoomTypeController { - return Result.success(roomTypeService.updateRoomType(roomTypeId, request, adminId)); - } - -- @ApiOperation("删除房型") -+ @ApiOperation(value = "删除房型", notes = "软删除房型及其价格日历数据。") - @DeleteMapping("/room-type/{roomTypeId}") - public Result deleteRoomType(@ApiParam("房型ID") @PathVariable Long roomTypeId) { - roomTypeService.deleteRoomType(roomTypeId); - return Result.success(); - } - -- @ApiOperation("启用/禁用房型") -+ @ApiOperation(value = "启用/禁用房型", notes = "直接修改房型状态(跳过审批)。status=0禁用,status=1启用。禁用后该房型不会出现在C端展示中。") - @PutMapping("/room-type/{roomTypeId}/status") - public Result updateRoomTypeStatus( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -@@ -74,7 +74,7 @@ public class RoomTypeController { - return Result.success(); - } - -- @ApiOperation("提交房型启用/禁用审批") -+ @ApiOperation(value = "提交房型启用/禁用审批", notes = "向企微OA提交房型启用/禁用审批。审批流程与住宿共享同一模板。返回审批单号spNo。") - @PostMapping("/room-type/{roomTypeId}/submit-approval") - public Result> submitRoomTypeApproval( - @ApiParam("房型ID") @PathVariable Long roomTypeId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalMpRestaurantController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalMpRestaurantController.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalMpRestaurantController.java -index 41d485f..df17f5c 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalMpRestaurantController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalMpRestaurantController.java -@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.*; - /** - * C端餐厅内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - */ --@Api(tags = "【内部接口】小程序餐厅(Feign调用)") -+@Api(tags = "【内部接口】小程序餐厅(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/restaurant") - @RequiredArgsConstructor -@@ -22,7 +22,7 @@ public class InternalMpRestaurantController { - - private final RestaurantService restaurantService; - -- @ApiOperation("C端餐厅列表") -+ @ApiOperation(value = "C端餐厅列表", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用。强制status=1只返回已上架餐厅,支持分页和筛选。C端用户通过小程序间接访问。\n\n**关联字典**:\n- restaurant_category(餐厅分类,返回字段categoryCode):CHINESE=中餐, WESTERN=西餐, BBQ=烧烤, HOTPOT=火锅, LOCAL=当地特色") - @GetMapping("/list") - public Result> listRestaurants(RestaurantQueryRequest query) { - // Force status=1 for C-side (only show published restaurants) -@@ -30,7 +30,7 @@ public class InternalMpRestaurantController { - return Result.success(restaurantService.listRestaurants(query)); - } - -- @ApiOperation("C端餐厅详情") -+ @ApiOperation(value = "C端餐厅详情", notes = "【仅限内部Feign调用】供mp-service获取餐厅完整详情,包含封面、轮播图、标签、地址、富文本介绍等。注意:不限制status,由BFF层校验是否展示。\n\n**关联字典**:\n- restaurant_category(餐厅分类,返回字段categoryCode):CHINESE=中餐, WESTERN=西餐, BBQ=烧烤, HOTPOT=火锅, LOCAL=当地特色") - @GetMapping("/{restaurantId}") - public Result getRestaurantDetail(@PathVariable Long restaurantId) { - RestaurantVO vo = restaurantService.getRestaurant(restaurantId); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalRestaurantController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalRestaurantController.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalRestaurantController.java -index ac8e4db..a87aaea 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalRestaurantController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/InternalRestaurantController.java -@@ -17,7 +17,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】餐厅(Feign调用)") -+@Api(tags = "【内部接口】餐厅(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/restaurant") - @RequiredArgsConstructor -@@ -25,7 +25,7 @@ public class InternalRestaurantController { - - private final RestaurantService restaurantService; - -- @ApiOperation("\u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f") -+ @ApiOperation(value = "\u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f", notes = "\u3010\u4ec5\u9650\u5185\u90e8Feign\u8c03\u7528\u3011\u4f9b\u4ea7\u54c1\u670d\u52a1\u83b7\u53d6\u5355\u4e2a\u9910\u5385\u7684\u7b80\u8981\u4fe1\u606f\uff0c\u8fd4\u56deID\u3001\u540d\u79f0\u3001\u5206\u7c7b\u7f16\u7801\u3001\u57ce\u5e02\u3001\u72b6\u6001\u3002\u4e0d\u5b58\u5728\u65f6\u8fd4\u56de\u9519\u8bef\u3002\n\n**\u5173\u8054\u5b57\u5178**\uff1a\n- restaurant_category\uff08\u9910\u5385\u5206\u7c7b\uff0c\u8fd4\u56de\u5b57\u6bb5categoryCode\uff09\uff1aCHINESE=\u4e2d\u9910, WESTERN=\u897f\u9910, BBQ=\u70e7\u70e4, HOTPOT=\u706b\u9505, LOCAL=\u5f53\u5730\u7279\u8272\n- common_status\uff08\u72b6\u6001\uff0c\u8fd4\u56de\u5b57\u6bb5status\uff09\uff1aACTIVE=\u542f\u7528, INACTIVE=\u505c\u7528") - @GetMapping("/item/{restaurantId}") - public Result> getRestaurantBrief(@PathVariable Long restaurantId) { - Restaurant restaurant = restaurantService.getRestaurantEntity(restaurantId); -@@ -41,7 +41,7 @@ public class InternalRestaurantController { - return Result.success(brief); - } - -- @ApiOperation("\u6279\u91cf\u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f") -+ @ApiOperation(value = "\u6279\u91cf\u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f", notes = "\u3010\u4ec5\u9650\u5185\u90e8Feign\u8c03\u7528\u3011\u6279\u91cf\u83b7\u53d6\u9910\u5385\u7b80\u8981\u4fe1\u606f\uff0c\u6700\u591a500\u4e2aID\u3002\u4e0d\u5b58\u5728\u7684ID\u81ea\u52a8\u8fc7\u6ee4\u3002\u4f9b\u4ea7\u54c1\u670d\u52a1\u6279\u91cf\u67e5\u8be2\u884c\u7a0b\u8282\u70b9\u7ed1\u5b9a\u7684\u9910\u5385\u8d44\u6e90\u3002\n\n**\u5173\u8054\u5b57\u5178**\uff1a\n- restaurant_category\uff08\u9910\u5385\u5206\u7c7b\uff0c\u8fd4\u56de\u5b57\u6bb5categoryCode\uff09\uff1aCHINESE=\u4e2d\u9910, WESTERN=\u897f\u9910, BBQ=\u70e7\u70e4, HOTPOT=\u706b\u9505, LOCAL=\u5f53\u5730\u7279\u8272\n- common_status\uff08\u72b6\u6001\uff0c\u8fd4\u56de\u5b57\u6bb5status\uff09\uff1aACTIVE=\u542f\u7528, INACTIVE=\u505c\u7528") - @GetMapping("/items/batch") - public Result>> getRestaurantsBatch(@RequestParam @Size(max = 500) List restaurantIds) { - List> results = restaurantIds.stream() -@@ -61,9 +61,9 @@ public class InternalRestaurantController { - return Result.success(results); - } - -- @ApiOperation("\u5904\u7406\u5ba1\u6279\u56de\u8c03\u7ed3\u679c") -+ @ApiOperation(value = "\u5904\u7406\u5ba1\u6279\u56de\u8c03\u7ed3\u679c", notes = "\u3010\u4ec5\u9650\u5185\u90e8Feign\u8c03\u7528\u3011\u63a5\u6536\u4f01\u5faeOA\u5ba1\u6279\u56de\u8c03\uff0c\u6309thirdNo\u5339\u914d\u9910\u5385\u5e76\u66f4\u65b0\u542f\u7528/\u7981\u7528\u72b6\u6001\u3002\u7531hl-callback-service\u901a\u8fc7MQ\u6d88\u8d39\u540e\u8c03\u7528\uff0c\u5e42\u7b49\u5904\u7406\u3002\n\n**\u5173\u8054\u5b57\u5178**\uff1a\n- approval_sp_status\uff08\u5ba1\u6279\u72b6\u6001\uff0c\u8bf7\u6c42\u5b57\u6bb5spStatus\uff09") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - restaurantService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantController.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantController.java -index eb8164c..7c8961f 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantController.java -@@ -26,7 +26,7 @@ public class RestaurantController { - - private final RestaurantService restaurantService; - -- @ApiOperation("创建餐厅") -+ @ApiOperation(value = "创建餐厅", notes = "新建餐厅资源,初始状态为草稿(status=0)。餐厅没有价格日历,费用通过产品报价中的费用项管理。需走企微审批流程上架。\n\n**关联字典**:\n- restaurant_category:餐厅分类(表单选择)\n- cuisine_type:菜系类型(表单多选)\n- environment_type:环境类型(表单多选)\n- restaurant_facility:餐厅设施(表单多选)\n\n**纯文本字段**:\n- cityName:城市名称(手动输入,如「拉萨」「海拉尔」)") - @PostMapping("/item") - public Result createRestaurant( - @ApiParam("餐厅创建请求") @Valid @RequestBody RestaurantCreateRequest request, -@@ -35,19 +35,19 @@ public class RestaurantController { - return Result.success(restaurantService.createRestaurant(request, adminId)); - } - -- @ApiOperation("餐厅列表") -+ @ApiOperation(value = "餐厅列表", notes = "分页查询餐厅列表,支持按名称、状态、分类、城市等条件筛选。\n\n**关联字典**:\n- restaurant_category:餐厅分类(筛选+列表显示)\n- cuisine_type:菜系类型(列表显示)\n- environment_type:环境类型(列表显示)\n- restaurant_facility:餐厅设施(列表显示)") - @GetMapping("/items") - public Result> listRestaurants(@ApiParam("餐厅查询请求") @Valid RestaurantQueryRequest query) { - return Result.success(restaurantService.listRestaurants(query)); - } - -- @ApiOperation("餐厅详情") -+ @ApiOperation(value = "餐厅详情", notes = "获取餐厅完整信息,包含素材URL、标签、富文本介绍等。\n\n**关联字典**:\n- restaurant_category:餐厅分类(详情显示)\n- cuisine_type:菜系类型(详情显示)\n- environment_type:环境类型(详情显示)\n- restaurant_facility:餐厅设施(详情显示)") - @GetMapping("/item/{restaurantId}") - public Result getRestaurant(@ApiParam("餐厅ID") @PathVariable Long restaurantId) { - return Result.success(restaurantService.getRestaurant(restaurantId)); - } - -- @ApiOperation("更新餐厅") -+ @ApiOperation(value = "更新餐厅", notes = "更新餐厅基本信息,不改变当前状态。\n\n**关联字典**:\n- restaurant_category:餐厅分类(表单选择)\n- cuisine_type:菜系类型(表单多选)\n- environment_type:环境类型(表单多选)\n- restaurant_facility:餐厅设施(表单多选)\n\n**纯文本字段**:\n- cityName:城市名称(手动输入)") - @PutMapping("/item/{restaurantId}") - public Result updateRestaurant( - @ApiParam("餐厅ID") @PathVariable Long restaurantId, -@@ -57,7 +57,7 @@ public class RestaurantController { - return Result.success(restaurantService.updateRestaurant(restaurantId, request, adminId)); - } - -- @ApiOperation("删除餐厅") -+ @ApiOperation(value = "删除餐厅", notes = "软删除餐厅。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/item/{restaurantId}") - public Result deleteRestaurant( - @ApiParam("餐厅ID") @PathVariable Long restaurantId, -@@ -68,7 +68,7 @@ public class RestaurantController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交审批。targetStatus=1申请上架,targetStatus=2申请下架。返回审批单号spNo。") - @PostMapping("/item/{restaurantId}/submit-approval") - public Result> submitApproval( - @ApiParam("餐厅ID") @PathVariable Long restaurantId, -@@ -80,7 +80,7 @@ public class RestaurantController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("上下架切换") -+ @ApiOperation(value = "上下架切换", notes = "直接修改状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/item/{restaurantId}/status") - public Result updateStatus( - @ApiParam("餐厅ID") @PathVariable Long restaurantId, -@@ -91,7 +91,7 @@ public class RestaurantController { - return Result.success(); - } - -- @ApiOperation("批量上下架") -+ @ApiOperation(value = "批量上下架", notes = "批量修改多个餐厅的状态,跳过审批流程。") - @PutMapping("/items/batch/status") - public Result batchUpdateStatus( - @ApiParam("餐厅状态请求") @Valid @RequestBody RestaurantStatusRequest request, -@@ -103,7 +103,7 @@ public class RestaurantController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个餐厅。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/items/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantTagController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantTagController.java -index 05b1056..7f96d5a 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/controller/RestaurantTagController.java -@@ -27,7 +27,7 @@ public class RestaurantTagController { - - private final RestaurantTagService tagService; - -- @ApiOperation("\u83b7\u53d6\u7ba1\u7406\u6807\u7b7e\u5217\u8868\uff08\u5206\u9875\uff09") -+ @ApiOperation(value = "\u83b7\u53d6\u7ba1\u7406\u6807\u7b7e\u5217\u8868\uff08\u5206\u9875\uff09", notes = "\u5206\u9875\u67e5\u8be2\u9910\u5385\u6807\u7b7e\u5e93\uff0c\u652f\u6301\u6309\u5173\u952e\u8bcd\u641c\u7d22\u3002\u5305\u542b\u9884\u8bbe\u6807\u7b7e\u548c\u81ea\u5b9a\u4e49\u6807\u7b7e\u3002") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("\u9875\u7801") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class RestaurantTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("\u83b7\u53d6\u5168\u90e8\u6807\u7b7e") -+ @ApiOperation(value = "\u83b7\u53d6\u5168\u90e8\u6807\u7b7e", notes = "\u4e0d\u5206\u9875\u8fd4\u56de\u6240\u6709\u6807\u7b7e\uff0c\u7528\u4e8e\u9910\u5385\u7f16\u8f91\u65f6\u7684\u6807\u7b7e\u9009\u62e9\u4e0b\u62c9\u3002") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("\u521b\u5efa\u7ba1\u7406\u6807\u7b7e") -+ @ApiOperation(value = "\u521b\u5efa\u7ba1\u7406\u6807\u7b7e", notes = "\u521b\u5efa\u9884\u8bbe\u6807\u7b7e\uff0c\u6807\u7b7e\u540d\u4e0d\u53ef\u91cd\u590d\u3002\u53ef\u6307\u5b9a\u989c\u8272(tagColor)\uff0c\u9ed8\u8ba4#409EFF\u3002") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class RestaurantTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("\u89e3\u6790\u81ea\u5b9a\u4e49\u6807\u7b7e") -+ @ApiOperation(value = "\u89e3\u6790\u81ea\u5b9a\u4e49\u6807\u7b7e", notes = "\u6309\u540d\u79f0\u67e5\u627e\u6216\u81ea\u52a8\u521b\u5efa\u6807\u7b7e\u3002\u7528\u4e8e\u9910\u5385\u7f16\u8f91\u65f6\u5feb\u901f\u8f93\u5165\u65b0\u6807\u7b7e\u3002") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class RestaurantTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("\u7f16\u8f91\u6807\u7b7e") -+ @ApiOperation(value = "\u7f16\u8f91\u6807\u7b7e", notes = "\u4fee\u6539\u6807\u7b7e\u540d\u79f0\u6216\u989c\u8272\uff0c\u6240\u6709\u5173\u8054\u9910\u5385\u81ea\u52a8\u751f\u6548\u3002") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class RestaurantTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("\u5220\u9664\u6807\u7b7e") -+ @ApiOperation(value = "\u5220\u9664\u6807\u7b7e", notes = "\u5220\u9664\u6807\u7b7e\u5e76\u89e3\u9664\u6240\u6709\u9910\u5385\u4e0e\u8be5\u6807\u7b7e\u7684\u5173\u8054\u3002") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("\u66f4\u65b0\u9910\u5385\u6807\u7b7e") -+ @ApiOperation(value = "\u66f4\u65b0\u9910\u5385\u6807\u7b7e", notes = "\u5168\u91cf\u66ff\u6362\u6307\u5b9a\u9910\u5385\u7684\u6807\u7b7e\u5217\u8868\u3002\u4f20\u5165tagIds\u4e3a\u6700\u7ec8\u5173\u8054\u7684\u6807\u7b7eID\u5217\u8868\uff0c\u4e3a\u7a7a\u5219\u6e05\u9664\u6240\u6709\u6807\u7b7e\u3002") - @PutMapping("/item/{restaurantId}/tags") - public Result updateRestaurantTags( - @ApiParam("餐厅ID") @PathVariable Long restaurantId, -@@ -87,7 +87,7 @@ public class RestaurantTagController { - return Result.success(); - } - -- @ApiOperation("\u6279\u91cf\u6253\u6807\u7b7e") -+ @ApiOperation(value = "\u6279\u91cf\u6253\u6807\u7b7e", notes = "\u5bf9\u591a\u4e2a\u9910\u5385\u6279\u91cf\u6dfb\u52a0/\u79fb\u9664\u6807\u7b7e\u3002\u589e\u91cf\u64cd\u4f5c\uff0c\u4e0d\u5f71\u54cd\u672a\u6307\u5b9a\u7684\u6807\u7b7e\u3002") - @PutMapping("/items/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantCreateRequest.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantCreateRequest.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantCreateRequest.java -index 629213d..23de858 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantCreateRequest.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantCreateRequest.java -@@ -61,8 +61,8 @@ public class RestaurantCreateRequest { - @Size(max = 30) - private String district; - -- @ApiModelProperty(value = "城市标签", required = true, example = "拉萨") -- @NotBlank(message = "城市标签不能为空") -+ @ApiModelProperty(value = "城市名称(纯文本输入)", required = true, example = "拉萨") -+ @NotBlank(message = "城市名称不能为空") - @Size(max = 30) - private String cityName; - -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantQueryRequest.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantQueryRequest.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantQueryRequest.java -index 34e331b..ba2f6e9 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantQueryRequest.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantQueryRequest.java -@@ -25,7 +25,7 @@ public class RestaurantQueryRequest { - @ApiModelProperty(value = "省份", example = "西藏自治区") - private String province; - -- @ApiModelProperty(value = "城市标签", example = "拉萨") -+ @ApiModelProperty(value = "城市名称筛选(纯文本)", example = "拉萨") - private String cityName; - - @ApiModelProperty(value = "城市", example = "拉萨市") -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantUpdateRequest.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantUpdateRequest.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantUpdateRequest.java -index 8b62d81..51eb13c 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantUpdateRequest.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/dto/RestaurantUpdateRequest.java -@@ -57,7 +57,7 @@ public class RestaurantUpdateRequest { - @Size(max = 30) - private String district; - -- @ApiModelProperty(value = "城市标签", example = "拉萨") -+ @ApiModelProperty(value = "城市名称(纯文本输入)", example = "拉萨") - @Size(max = 30) - private String cityName; - -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantListVO.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantListVO.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantListVO.java -index df37c80..f0d4d24 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantListVO.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantListVO.java -@@ -36,7 +36,7 @@ public class RestaurantListVO { - @ApiModelProperty("人均消费(元)") - private BigDecimal pricePerPerson; - -- @ApiModelProperty("城市标签") -+ @ApiModelProperty("城市名称(纯文本)") - private String cityName; - - @ApiModelProperty("亮点摘要") -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantVO.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantVO.java b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantVO.java -index acfd3d8..4396d6e 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantVO.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/restaurant/vo/RestaurantVO.java -@@ -54,7 +54,7 @@ public class RestaurantVO { - @ApiModelProperty("区县") - private String district; - -- @ApiModelProperty("城市标签") -+ @ApiModelProperty("城市名称(纯文本)") - private String cityName; - - @ApiModelProperty("详细地址") -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalMpScenicController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalMpScenicController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalMpScenicController.java -index dbe9f19..a28ef38 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalMpScenicController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalMpScenicController.java -@@ -17,7 +17,7 @@ import java.util.List; - /** - * C端景区内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - */ --@Api(tags = "【内部接口】小程序景区(Feign调用)") -+@Api(tags = "【内部接口】小程序景区(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/scenic") - @RequiredArgsConstructor -@@ -25,21 +25,21 @@ public class InternalMpScenicController { - - private final ScenicSpotService scenicSpotService; - -- @ApiOperation("C端景区列表") -+ @ApiOperation(value = "C端景区列表", notes = "【仅限内部Feign调用】供mp-service BFF聚合使用。强制status=1只返回已上架景区,支持分页、城市筛选和关键词搜索。C端用户通过小程序间接访问。\n\ncityName为纯文本筛选字段,非字典。") - @GetMapping("/list") - public Result> listScenic(ScenicSpotQueryRequest query) { - query.setStatus(1); - return Result.success(scenicSpotService.listSpots(query)); - } - -- @ApiOperation("C端景区详情") -+ @ApiOperation(value = "C端景区详情", notes = "【仅限内部Feign调用】供mp-service获取景区完整详情,包含封面、轮播图、标签、季节内容、富文本介绍、坐标等。注意:不限制status,由BFF层校验是否展示。") - @GetMapping("/{scenicId}") - public Result getScenicDetail(@PathVariable Long scenicId) { - ScenicSpotVO vo = scenicSpotService.getSpot(scenicId); - return Result.success(vo); - } - -- @ApiOperation("C端附近景区") -+ @ApiOperation(value = "C端附近景区", notes = "【仅限内部Feign调用】根据指定景区的坐标查询附近的景区列表。radius为搜索半径(km,默认50),limit为最大返回数(默认10)。按距离排序,返回名称、封面、距离等信息。") - @GetMapping("/{scenicId}/nearby") - public Result> getNearbyScenic( - @PathVariable Long scenicId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalScenicController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalScenicController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalScenicController.java -index a902ee1..9f47695 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalScenicController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/InternalScenicController.java -@@ -22,7 +22,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】景区(Feign调用)") -+@Api(tags = "【内部接口】景区(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/scenic") - @RequiredArgsConstructor -@@ -31,7 +31,7 @@ public class InternalScenicController { - private final ScenicSpotService spotService; - private final ScenicPriceCalendarService priceService; - -- @ApiOperation("获取景区简要信息") -+ @ApiOperation(value = "获取景区简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个景区的简要信息,返回ID、名称、荣誉称号、城市、状态。不存在时返回错误。\n\n**关联字典**:\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/spot/{scenicId}") - public Result> getSpotBrief(@PathVariable Long scenicId) { - ScenicSpot spot = spotService.getSpotEntity(scenicId); -@@ -47,7 +47,7 @@ public class InternalScenicController { - return Result.success(brief); - } - -- @ApiOperation("批量获取景区简要信息") -+ @ApiOperation(value = "批量获取景区简要信息", notes = "【仅限内部Feign调用】批量获取景区简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询行程节点绑定的景区资源。\n\n**关联字典**:\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/spots/batch") - public Result>> getSpotsBatch(@RequestParam @Size(max = 500) List scenicIds) { - List> results = scenicIds.stream() -@@ -67,7 +67,7 @@ public class InternalScenicController { - return Result.success(results); - } - -- @ApiOperation("查询某日价格") -+ @ApiOperation(value = "查询某日价格", notes = "【仅限内部Feign调用】查询景区指定日期的价格日历信息,包含成本价、售价、库存、状态。date格式为yyyy-MM-dd。供产品服务报价计算和库存校验使用。") - @GetMapping("/spot/{scenicId}/price/{date}") - public Result getPriceForDate( - @PathVariable Long scenicId, -@@ -76,7 +76,7 @@ public class InternalScenicController { - return Result.success(price); - } - -- @ApiOperation("判断某日是否可售") -+ @ApiOperation(value = "判断某日是否可售", notes = "【仅限内部Feign调用】判断景区指定日期是否可售(价格日历存在且状态为启用且库存>0)。供订单服务下单前校验使用。") - @GetMapping("/spot/{scenicId}/available/{date}") - public Result isAvailable( - @PathVariable Long scenicId, -@@ -84,7 +84,7 @@ public class InternalScenicController { - return Result.success(priceService.isAvailable(scenicId, LocalDate.parse(date))); - } - -- @ApiOperation("扣减库存") -+ @ApiOperation(value = "扣减库存", notes = "【仅限内部Feign调用】扣减景区指定日期的库存数量。下单成功时由订单服务调用。库存不足时返回false。使用乐观锁防止超卖。") - @PutMapping("/spot/{scenicId}/stock/deduct") - public Result deductStock( - @PathVariable Long scenicId, -@@ -94,7 +94,7 @@ public class InternalScenicController { - return Result.success(success); - } - -- @ApiOperation("恢复库存") -+ @ApiOperation(value = "恢复库存", notes = "【仅限内部Feign调用】恢复景区指定日期的库存数量。订单取消或退款时由订单服务调用,将之前扣减的库存加回。") - @PutMapping("/spot/{scenicId}/stock/restore") - public Result restoreStock( - @PathVariable Long scenicId, -@@ -104,9 +104,9 @@ public class InternalScenicController { - return Result.success(); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配景区并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - spotService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicPriceCalendarController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicPriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicPriceCalendarController.java -index 8e2b1cb..62d7de0 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicPriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicPriceCalendarController.java -@@ -25,7 +25,7 @@ public class ScenicPriceCalendarController { - - private final ScenicPriceCalendarService priceService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询景区的每日价格和可售状态。返回指定年月中所有已设置价格的日期,未设置的日期不返回。用于前端日历组件渲染。") - @GetMapping("/spot/{scenicId}/prices") - public Result getPriceCalendar( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -34,7 +34,7 @@ public class ScenicPriceCalendarController { - return Result.success(priceService.getPriceCalendar(scenicId, year, month)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", notes = "在指定日期范围内批量设置成本价、库存和可售状态。支持weekdayOnly/weekendOnly/selectedWeekdays过滤特定星期,支持excludeDates排除特定日期。已有价格的日期会被覆盖更新。") - @PutMapping("/spot/{scenicId}/prices") - public Result batchSetPrices( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -43,7 +43,7 @@ public class ScenicPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改可售状态") -+ @ApiOperation(value = "批量修改可售状态", notes = "批量修改指定日期范围内的可售状态,不影响价格和库存。status=0不可售,status=1可售。用于临时关闭/开放某些日期的售卖。") - @PutMapping("/spot/{scenicId}/prices/status") - public Result batchUpdateStatus( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -52,7 +52,7 @@ public class ScenicPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量清除价格") -+ @ApiOperation(value = "批量清除价格", notes = "删除指定日期范围内的所有价格记录。删除后该日期范围将显示为未设置状态。日期格式:yyyy-MM-dd。") - @DeleteMapping("/spot/{scenicId}/prices") - public Result deletePrices( - @ApiParam("景区ID") @PathVariable Long scenicId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSeasonController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSeasonController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSeasonController.java -index 8933ec2..ab7ad78 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSeasonController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSeasonController.java -@@ -22,13 +22,13 @@ public class ScenicSeasonController { - - private final ScenicSeasonService seasonService; - -- @ApiOperation("获取景区全部季节内容") -+ @ApiOperation(value = "获取景区全部季节内容", notes = "返回景区的所有季节内容列表(春/夏/秋/冬)。季节内容是景区独有功能,其他资源类型没有此概念。每个季节可设置独立的封面、轮播图、亮点描述和游玩攻略。") - @GetMapping("/spot/{scenicId}/seasons") - public Result> getSeasons(@ApiParam("景区ID") @PathVariable Long scenicId) { - return Result.success(seasonService.getSeasons(scenicId)); - } - -- @ApiOperation("保存/更新季节内容") -+ @ApiOperation(value = "保存/更新季节内容", notes = "创建或更新指定景区的季节内容。seasonType为季节标识(如spring/summer/autumn/winter)。如果该季节已存在则更新,不存在则创建。支持设置季节别名(如「樱花季」)、月份范围、独立封面和轮播图。") - @PutMapping("/spot/{scenicId}/season/{seasonType}") - public Result saveSeason( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -39,7 +39,7 @@ public class ScenicSeasonController { - return Result.success(seasonService.saveSeason(scenicId, seasonType, request, adminId)); - } - -- @ApiOperation("删除季节内容") -+ @ApiOperation(value = "删除季节内容", notes = "删除指定景区的某个季节内容,同时清理关联的素材引用。") - @DeleteMapping("/spot/{scenicId}/season/{seasonType}") - public Result deleteSeason( - @ApiParam("景区ID") @PathVariable Long scenicId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSpotController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSpotController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSpotController.java -index b8aff01..c2da355 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSpotController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicSpotController.java -@@ -26,7 +26,7 @@ public class ScenicSpotController { - - private final ScenicSpotService spotService; - -- @ApiOperation("创建景区") -+ @ApiOperation(value = "创建景区", notes = "新建一个景区资源,初始状态为草稿(status=0)。创建后需通过「提交启用审批」接口走企微OA审批流程才能上架。支持富文本字段(featureIntro/detailContent等),素材ID从素材库获取。\n\n**关联字典**:\n- scenic_facility:景区设施(表单多选)\n- scenic_honor:景区荣誉(表单多选)") - @PostMapping("/spot") - public Result createSpot( - @ApiParam("景区创建请求") @Valid @RequestBody ScenicSpotCreateRequest request, -@@ -35,19 +35,19 @@ public class ScenicSpotController { - return Result.success(spotService.createSpot(request, adminId)); - } - -- @ApiOperation("景区列表") -+ @ApiOperation(value = "景区列表", notes = "分页查询景区列表,支持按名称关键词、状态(0草稿/1上架/2下架)、城市等条件筛选。返回列表摘要信息(不含富文本详情),按sortOrder倒序+创建时间倒序排列。\n\n**关联字典**:\n- scenic_facility:景区设施(列表显示)\n- scenic_honor:景区荣誉(列表显示)") - @GetMapping("/spots") - public Result> listSpots(@ApiParam("景区查询请求") @Valid ScenicSpotQueryRequest query) { - return Result.success(spotService.listSpots(query)); - } - -- @ApiOperation("景区详情") -+ @ApiOperation(value = "景区详情", notes = "获取景区完整信息,包含富文本内容、素材URL、标签列表、季节内容等。素材ID会自动解析为OSS访问地址。\n\n**关联字典**:\n- scenic_facility:景区设施(详情显示)\n- scenic_honor:景区荣誉(详情显示)") - @GetMapping("/spot/{scenicId}") - public Result getSpot(@ApiParam("景区ID") @PathVariable Long scenicId) { - return Result.success(spotService.getSpot(scenicId)); - } - -- @ApiOperation("更新景区") -+ @ApiOperation(value = "更新景区", notes = "更新景区基本信息和富文本内容。更新不会改变当前状态。如果景区已上架,修改后仍保持上架状态,无需重新审批。\n\n**关联字典**:\n- scenic_facility:景区设施(表单多选)\n- scenic_honor:景区荣誉(表单多选)") - @PutMapping("/spot/{scenicId}") - public Result updateSpot( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -57,7 +57,7 @@ public class ScenicSpotController { - return Result.success(spotService.updateSpot(scenicId, request, adminId)); - } - -- @ApiOperation("删除景区") -+ @ApiOperation(value = "删除景区", notes = "软删除景区(设置deleted_at)。仅SUPER_ADMIN角色或创建者本人可删除。已上架的景区需先下架再删除。删除后会同时清理关联的素材引用。") - @DeleteMapping("/spot/{scenicId}") - public Result deleteSpot( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -68,7 +68,7 @@ public class ScenicSpotController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交审批申请。targetStatus=1表示申请上架,targetStatus=2表示申请下架。提交后景区进入PENDING_APPROVAL状态,企微审批通过/拒绝后通过回调自动更新状态。返回企微审批单号spNo。同一景区不可重复提交未完成的审批。") - @PostMapping("/spot/{scenicId}/submit-approval") - public Result> submitApproval( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -80,7 +80,7 @@ public class ScenicSpotController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("上下架切换") -+ @ApiOperation(value = "上下架切换", notes = "直接修改景区状态(跳过审批流程),仅限SUPER_ADMIN使用。普通管理员应使用「提交启用/禁用审批」接口。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/spot/{scenicId}/status") - public Result updateStatus( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -91,7 +91,7 @@ public class ScenicSpotController { - return Result.success(); - } - -- @ApiOperation("批量上下架") -+ @ApiOperation(value = "批量上下架", notes = "批量修改多个景区的状态。scenicIds为景区ID列表(字符串格式),status为目标状态。跳过审批流程,适用于批量管理场景。") - @PutMapping("/spots/batch/status") - public Result batchUpdateStatus( - @ApiParam("景区状态请求") @Valid @RequestBody ScenicStatusRequest request, -@@ -103,7 +103,7 @@ public class ScenicSpotController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个景区。权限校验同单个删除:仅SUPER_ADMIN或创建者可操作。部分失败不影响其他景区的删除。") - @DeleteMapping("/spots/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicTagController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicTagController.java -index eda0e91..1410edc 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/scenic/controller/ScenicTagController.java -@@ -27,7 +27,7 @@ public class ScenicTagController { - - private final ScenicTagService tagService; - -- @ApiOperation("获取管理标签列表(分页)") -+ @ApiOperation(value = "获取管理标签列表(分页)", notes = "分页查询景区标签库中的所有标签,支持按关键词搜索。标签分为预设标签(管理员创建)和自定义标签(adhoc接口创建),此接口返回全部类型。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class ScenicTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("获取全部标签") -+ @ApiOperation(value = "获取全部标签", notes = "不分页返回所有标签,用于景区编辑时的标签选择下拉列表。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建管理标签") -+ @ApiOperation(value = "创建管理标签", notes = "创建预设标签,标签名不可重复。可指定颜色(tagColor),默认为#409EFF。预设标签在标签管理页面展示和维护。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class ScenicTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "输入标签名称,如果已存在则直接返回,不存在则自动创建。用于景区编辑时快速输入新标签,避免先到标签管理页面创建。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class ScenicTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("编辑标签") -+ @ApiOperation(value = "编辑标签", notes = "修改标签名称或颜色。修改后所有关联此标签的景区会自动生效。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class ScenicTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并自动解除所有景区与该标签的关联关系。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("更新景区标签") -+ @ApiOperation(value = "更新景区标签", notes = "全量替换指定景区的标签列表。传入tagIds为该景区最终要关联的标签ID列表,为空则清除所有标签。") - @PutMapping("/spot/{scenicId}/tags") - public Result updateScenicTags( - @ApiParam("景区ID") @PathVariable Long scenicId, -@@ -87,7 +87,7 @@ public class ScenicTagController { - return Result.success(); - } - -- @ApiOperation("批量打标签") -+ @ApiOperation(value = "批量打标签", notes = "对多个景区批量添加或移除标签。addTagIds为要添加的标签,removeTagIds为要移除的标签,两者可同时使用。增量操作,不影响未指定的标签。") - @PutMapping("/spots/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/service/controller/InternalServiceController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/InternalServiceController.java b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/InternalServiceController.java -index 95c02bf..4125c0d 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/InternalServiceController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/InternalServiceController.java -@@ -17,7 +17,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】增值服务(Feign调用)") -+@Api(tags = "【内部接口】增值服务(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/service") - @RequiredArgsConstructor -@@ -25,7 +25,7 @@ public class InternalServiceController { - - private final ServiceItemService serviceItemService; - -- @ApiOperation("获取服务简要信息") -+ @ApiOperation(value = "获取服务简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个增值服务的简要信息,返回ID、名称、分类编码、计费类型、是否收费、状态。不存在时返回错误。\n\n**关联字典**:\n- service_unit(计费单位,返回字段billingType):PER_PERSON=元/人, PER_TIME=元/次, PER_DAY=元/天, PER_VEHICLE=元/台, FIXED=固定金额\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/item/{serviceId}") - public Result> getServiceBrief(@PathVariable Long serviceId) { - ServiceItem item = serviceItemService.getServiceItemEntity(serviceId); -@@ -42,7 +42,7 @@ public class InternalServiceController { - return Result.success(brief); - } - -- @ApiOperation("批量获取服务简要信息") -+ @ApiOperation(value = "批量获取服务简要信息", notes = "【仅限内部Feign调用】批量获取增值服务简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询产品关联的服务项。\n\n**关联字典**:\n- service_unit(计费单位,返回字段billingType):PER_PERSON=元/人, PER_TIME=元/次, PER_DAY=元/天, PER_VEHICLE=元/台, FIXED=固定金额\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/items/batch") - public Result>> getServiceBatch(@RequestParam @Size(max = 500) List serviceIds) { - List> results = serviceIds.stream() -@@ -63,9 +63,9 @@ public class InternalServiceController { - return Result.success(results); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配增值服务并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - serviceItemService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceItemController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceItemController.java b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceItemController.java -index 6750979..52e1bb9 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceItemController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceItemController.java -@@ -26,7 +26,7 @@ public class ServiceItemController { - - private final ServiceItemService serviceItemService; - -- @ApiOperation("创建服务") -+ @ApiOperation(value = "创建增值服务", notes = "新建增值服务项目(如保险、签证代办、接送机等),初始状态为草稿(status=0)。支持免费(isPaid=false)和付费两种模式,付费服务有独立的价格日历。需走企微审批上架。\n\n**关联字典**:\n- service_category:服务分类(表单选择)\n- billing_type_service:服务计费方式(表单选择)\n- service_unit:服务计量单位(表单选择)") - @PostMapping("/item") - public Result createServiceItem( - @ApiParam("服务创建请求") @Valid @RequestBody ServiceCreateRequest request, -@@ -35,19 +35,19 @@ public class ServiceItemController { - return Result.success(serviceItemService.createServiceItem(request, adminId)); - } - -- @ApiOperation("服务列表") -+ @ApiOperation(value = "增值服务列表", notes = "分页查询增值服务列表,支持按名称、状态、分类等条件筛选。\n\n**关联字典**:\n- service_category:服务分类(筛选+列表显示)\n- billing_type_service:服务计费方式(列表显示)\n- service_unit:服务计量单位(列表显示)") - @GetMapping("/items") - public Result> listServiceItems(@ApiParam("服务查询请求") @Valid ServiceQueryRequest query) { - return Result.success(serviceItemService.listServiceItems(query)); - } - -- @ApiOperation("服务详情") -+ @ApiOperation(value = "增值服务详情", notes = "获取增值服务完整信息,包含素材URL、标签、计费方式等。\n\n**关联字典**:\n- service_category:服务分类(详情显示)\n- billing_type_service:服务计费方式(详情显示)\n- service_unit:服务计量单位(详情显示)") - @GetMapping("/item/{serviceId}") - public Result getServiceItem(@ApiParam("服务ID") @PathVariable Long serviceId) { - return Result.success(serviceItemService.getServiceItem(serviceId)); - } - -- @ApiOperation("更新服务") -+ @ApiOperation(value = "更新增值服务", notes = "更新增值服务基本信息,不改变当前状态。\n\n**关联字典**:\n- service_category:服务分类(表单选择)\n- billing_type_service:服务计费方式(表单选择)\n- service_unit:服务计量单位(表单选择)") - @PutMapping("/item/{serviceId}") - public Result updateServiceItem( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -57,7 +57,7 @@ public class ServiceItemController { - return Result.success(serviceItemService.updateServiceItem(serviceId, request, adminId)); - } - -- @ApiOperation("删除服务") -+ @ApiOperation(value = "删除增值服务", notes = "软删除增值服务。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/item/{serviceId}") - public Result deleteServiceItem( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -68,7 +68,7 @@ public class ServiceItemController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交审批。targetStatus=1申请上架,targetStatus=2申请下架。返回审批单号spNo。") - @PostMapping("/item/{serviceId}/submit-approval") - public Result> submitApproval( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -80,7 +80,7 @@ public class ServiceItemController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("启用/禁用切换") -+ @ApiOperation(value = "启用/禁用切换", notes = "直接修改状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/item/{serviceId}/status") - public Result updateStatus( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -91,7 +91,7 @@ public class ServiceItemController { - return Result.success(); - } - -- @ApiOperation("批量启用/禁用") -+ @ApiOperation(value = "批量启用/禁用", notes = "批量修改多个增值服务的状态,跳过审批流程。") - @PutMapping("/items/batch/status") - public Result batchUpdateStatus( - @ApiParam("服务状态请求") @Valid @RequestBody ServiceStatusRequest request, -@@ -103,7 +103,7 @@ public class ServiceItemController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个增值服务。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/items/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServicePriceCalendarController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServicePriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServicePriceCalendarController.java -index e96654d..a2f52d3 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServicePriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServicePriceCalendarController.java -@@ -25,7 +25,7 @@ public class ServicePriceCalendarController { - - private final ServicePriceCalendarService priceService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询增值服务的每日价格和可售状态。仅付费服务(isPaid=true)需要设置价格日历。") - @GetMapping("/item/{serviceId}/prices") - public Result getPriceCalendar( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -34,7 +34,7 @@ public class ServicePriceCalendarController { - return Result.success(priceService.getPriceCalendar(serviceId, year, month)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", notes = "在指定日期范围内批量设置服务的成本价和可售状态。") - @PutMapping("/item/{serviceId}/prices") - public Result batchSetPrices( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -43,7 +43,7 @@ public class ServicePriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改可售状态") -+ @ApiOperation(value = "批量修改可售状态", notes = "批量修改日期范围内的可售状态,不影响价格。") - @PutMapping("/item/{serviceId}/prices/batch-status") - public Result batchUpdateStatus( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -52,7 +52,7 @@ public class ServicePriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量清除价格") -+ @ApiOperation(value = "批量清除价格", notes = "删除指定日期范围内的价格记录。日期格式:yyyy-MM-dd。") - @DeleteMapping("/item/{serviceId}/prices") - public Result deletePrices( - @ApiParam("服务ID") @PathVariable Long serviceId, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceTagController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceTagController.java -index cf3865a..5dca328 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/service/controller/ServiceTagController.java -@@ -27,7 +27,7 @@ public class ServiceTagController { - - private final ServiceTagService tagService; - -- @ApiOperation("获取管理标签列表(分页)") -+ @ApiOperation(value = "获取管理标签列表(分页)", notes = "分页查询增值服务标签库,支持按关键词搜索。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class ServiceTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("获取全部标签") -+ @ApiOperation(value = "获取全部标签", notes = "不分页返回所有标签,用于服务编辑时的标签选择。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建管理标签") -+ @ApiOperation(value = "创建管理标签", notes = "创建预设标签,标签名不可重复。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class ServiceTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "按名称查找或自动创建标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class ServiceTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("编辑标签") -+ @ApiOperation(value = "编辑标签", notes = "修改标签名称或颜色,所有关联服务自动生效。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class ServiceTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并解除所有服务与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("更新服务标签") -+ @ApiOperation(value = "更新服务标签", notes = "全量替换指定服务的标签列表。") - @PutMapping("/item/{serviceId}/tags") - public Result updateServiceTags( - @ApiParam("服务ID") @PathVariable Long serviceId, -@@ -87,7 +87,7 @@ public class ServiceTagController { - return Result.success(); - } - -- @ApiOperation("批量打标签") -+ @ApiOperation(value = "批量打标签", notes = "对多个服务批量添加/移除标签。增量操作。") - @PutMapping("/items/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/InternalStaffController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/InternalStaffController.java b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/InternalStaffController.java -index 7c8bb51..ce700da 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/InternalStaffController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/InternalStaffController.java -@@ -19,7 +19,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】服务人员(Feign调用)") -+@Api(tags = "【内部接口】服务人员(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/staff") - @RequiredArgsConstructor -@@ -28,7 +28,7 @@ public class InternalStaffController { - private final StaffService staffService; - private final StaffMapper staffMapper; - -- @ApiOperation("获取人员简要信息") -+ @ApiOperation(value = "获取人员简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个服务人员的简要信息,返回ID、姓名、人员类型、手机号、状态。不存在时返回错误。\n\n**关联字典**:\n- staff_type(人员类型,返回字段staffType):GUIDE=导游, DRIVER=司机, PHOTOGRAPHER=摄影师, CHEF=厨师\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/{staffId}") - public Result> getStaffBrief(@PathVariable Long staffId) { - Staff staff = staffService.getStaffEntity(staffId); -@@ -44,7 +44,7 @@ public class InternalStaffController { - return Result.success(brief); - } - -- @ApiOperation("批量获取人员简要信息") -+ @ApiOperation(value = "批量获取人员简要信息", notes = "【仅限内部Feign调用】批量获取服务人员简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询团批关联的服务人员。\n\n**关联字典**:\n- staff_type(人员类型,返回字段staffType):GUIDE=导游, DRIVER=司机, PHOTOGRAPHER=摄影师, CHEF=厨师\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/batch") - public Result>> getStaffBatch(@RequestParam @Size(max = 500) List staffIds) { - List> results = staffIds.stream() -@@ -64,7 +64,7 @@ public class InternalStaffController { - return Result.success(results); - } - -- @ApiOperation("按人员类型查询") -+ @ApiOperation(value = "按人员类型查询", notes = "【仅限内部Feign调用】按staffType查询第一个匹配的服务人员。staffType如:GUIDE(导游)、DRIVER(司机)、PHOTOGRAPHER(摄影师)等。未找到时返回null。\n\n**关联字典**:\n- staff_type(人员类型,请求参数+返回字段staffType):GUIDE=导游, DRIVER=司机, PHOTOGRAPHER=摄影师, CHEF=厨师\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/by-type/{staffType}") - public Result> getStaffByType(@PathVariable String staffType) { - Staff staff = staffService.getStaffByType(staffType); -@@ -80,9 +80,9 @@ public class InternalStaffController { - return Result.success(brief); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配服务人员并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - staffService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -@@ -91,7 +91,7 @@ public class InternalStaffController { - /** - * Batch get staff basic info by comma-separated IDs (for product-service batch staff snapshot). - */ -- @ApiOperation("批量获取人员基本信息(逗号分隔ID)") -+ @ApiOperation(value = "批量获取人员基本信息(逗号分隔ID)", notes = "【仅限内部Feign调用】通过逗号分隔的ID字符串批量获取人员基本信息(含staffId、name、phone、staffType、coverMaterialId)。供产品服务团批人员快照使用。与/batch接口不同,此接口接收逗号分隔字符串而非数组。\n\n**关联字典**:\n- staff_type(人员类型,返回字段staffType):GUIDE=导游, DRIVER=司机, PHOTOGRAPHER=摄影师, CHEF=厨师") - @GetMapping("/batch-basic") - public Result>> batchGetStaffBasic(@RequestParam String staffIds) { - List ids = Arrays.stream(staffIds.split(",")) -@@ -122,7 +122,7 @@ public class InternalStaffController { - * List available staff (status=1), optionally filter by staffType. - * Used by admin batch staff selection dropdown. - */ -- @ApiOperation("列出可用人员(用于下拉选择)") -+ @ApiOperation(value = "列出可用人员(用于下拉选择)", notes = "【仅限内部Feign调用】列出所有status=1的可用服务人员,可按staffType筛选。按sortOrder和staffId排序。供管理后台团批分配人员的下拉选择框使用。\n\n**关联字典**:\n- staff_type(人员类型,请求参数+返回字段staffType):GUIDE=导游, DRIVER=司机, PHOTOGRAPHER=摄影师, CHEF=厨师") - @GetMapping("/list-available") - public Result>> listAvailableStaff( - @RequestParam(required = false) String staffType) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffController.java b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffController.java -index f90638f..be01710 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffController.java -@@ -24,7 +24,7 @@ public class StaffController { - - private final StaffService staffService; - -- @ApiOperation("创建服务人员") -+ @ApiOperation(value = "创建服务人员", notes = "新建服务人员(导游/领队/摄影师/助理等)。人员类型(staffType)决定了其在价格日历中的归类。需走企微审批上架后才能被产品引用。\n\n**关联字典**:\n- staff_type:人员类型(表单选择)\n- guide_level:导游等级(表单选择)\n- driver_license_type:驾照类型(表单选择)\n- language:语言能力(表单多选)\n- guide_specialty:导游专长(表单多选)\n- guide_service_area:服务区域(表单多选)") - @PostMapping - public Result createStaff(@ApiParam("服务人员创建请求") @Valid @RequestBody StaffCreateRequest request, - HttpServletRequest httpRequest) { -@@ -32,19 +32,19 @@ public class StaffController { - return Result.success(staffService.createStaff(request, adminId)); - } - -- @ApiOperation("服务人员列表") -+ @ApiOperation(value = "服务人员列表", notes = "分页查询服务人员列表,支持按姓名、状态、人员类型等条件筛选。\n\n**关联字典**:\n- staff_type:人员类型(筛选+列表显示)\n- guide_level:导游等级(列表显示)\n- driver_license_type:驾照类型(列表显示)\n- language:语言能力(列表显示)\n- guide_specialty:导游专长(列表显示)\n- guide_service_area:服务区域(列表显示)") - @GetMapping("/list") - public Result> listStaff(@ApiParam("服务人员查询请求") @Valid StaffQueryRequest query) { - return Result.success(staffService.listStaff(query)); - } - -- @ApiOperation("服务人员详情") -+ @ApiOperation(value = "服务人员详情", notes = "获取服务人员完整信息,包含素材URL、标签、技能描述等。\n\n**关联字典**:\n- staff_type:人员类型(详情显示)\n- guide_level:导游等级(详情显示)\n- driver_license_type:驾照类型(详情显示)\n- language:语言能力(详情显示)\n- guide_specialty:导游专长(详情显示)\n- guide_service_area:服务区域(详情显示)") - @GetMapping("/{staffId}") - public Result getStaff(@ApiParam("人员ID") @PathVariable Long staffId) { - return Result.success(staffService.getStaff(staffId)); - } - -- @ApiOperation("更新服务人员") -+ @ApiOperation(value = "更新服务人员", notes = "更新服务人员基本信息,不改变当前状态。\n\n**关联字典**:\n- staff_type:人员类型(表单选择)\n- guide_level:导游等级(表单选择)\n- driver_license_type:驾照类型(表单选择)\n- language:语言能力(表单多选)\n- guide_specialty:导游专长(表单多选)\n- guide_service_area:服务区域(表单多选)") - @PutMapping("/{staffId}") - public Result updateStaff(@ApiParam("人员ID") @PathVariable Long staffId, - @ApiParam("服务人员更新请求") @Valid @RequestBody StaffUpdateRequest request, -@@ -53,7 +53,7 @@ public class StaffController { - return Result.success(staffService.updateStaff(staffId, request, adminId)); - } - -- @ApiOperation("删除服务人员") -+ @ApiOperation(value = "删除服务人员", notes = "软删除服务人员。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/{staffId}") - public Result deleteStaff(@ApiParam("人员ID") @PathVariable Long staffId, HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -@@ -62,7 +62,7 @@ public class StaffController { - return Result.success(); - } - -- @ApiOperation("提交审批") -+ @ApiOperation(value = "提交审批", notes = "向企微OA提交人员启用/禁用审批。targetStatus=1申请启用,targetStatus=2申请禁用。返回审批单号spNo。") - @PostMapping("/{staffId}/submit-approval") - public Result> submitApproval(@ApiParam("人员ID") @PathVariable Long staffId, - @ApiParam("审批提交请求体") @Valid @RequestBody ApprovalSubmitRequest request, -@@ -72,7 +72,7 @@ public class StaffController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("更新状态") -+ @ApiOperation(value = "更新状态", notes = "直接修改人员状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=启用,2=禁用。") - @PutMapping("/{staffId}/status") - public Result updateStatus(@ApiParam("人员ID") @PathVariable Long staffId, - @ApiParam("状态请求体") @Valid @RequestBody StaffStatusRequest request, -@@ -82,14 +82,14 @@ public class StaffController { - return Result.success(); - } - -- @ApiOperation("批量更新状态") -+ @ApiOperation(value = "批量更新状态", notes = "批量修改多个服务人员的状态,跳过审批流程。") - @PutMapping("/batch/status") - public Result batchUpdateStatus(@ApiParam("批量状态请求体") @Valid @RequestBody StaffStatusRequest request) { - staffService.batchUpdateStatus(request.getStaffIds(), request.getStatus()); - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个服务人员。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/batch") - public Result batchDelete(@ApiParam("批量删除请求体") @Valid @RequestBody StaffBatchDeleteRequest request, - HttpServletRequest httpRequest) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffPriceCalendarController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffPriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffPriceCalendarController.java -index 2993bef..a762de1 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffPriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffPriceCalendarController.java -@@ -27,7 +27,7 @@ public class StaffPriceCalendarController { - - private final StaffPriceCalendarService priceCalendarService; - -- @ApiOperation("查询价格日历(按人员类型)") -+ @ApiOperation(value = "查询价格日历(按人员类型)", notes = "按月查询指定人员类型的每日服务费用和可调度状态。注意:价格日历按人员类型维度管理,非按个人维度。同一类型的所有人员共享同一套价格。\n\n**关联字典**:\n- staff_type(人员类型)→ staffType路径参数") - @GetMapping("/type/{staffType}/prices") - public Result getPriceCalendar( - @ApiParam("人员类型: GUIDE/GUIDE_ASSISTANT/PHOTOGRAPHER/LEADER/OTHER") @PathVariable String staffType, -@@ -36,7 +36,7 @@ public class StaffPriceCalendarController { - return Result.success(priceCalendarService.getPriceCalendar(staffType, year, month)); - } - -- @ApiOperation("批量设置价格(按人员类型)") -+ @ApiOperation(value = "批量设置价格(按人员类型)", notes = "在指定日期范围内批量设置该类型人员的服务成本价和可调度状态。\n\n**关联字典**:\n- staff_type(人员类型)→ staffType路径参数") - @PutMapping("/type/{staffType}/prices") - public Result batchSetPrices( - @ApiParam("人员类型: GUIDE/GUIDE_ASSISTANT/PHOTOGRAPHER/LEADER/OTHER") @PathVariable String staffType, -@@ -45,7 +45,7 @@ public class StaffPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改调度状态(按人员类型)") -+ @ApiOperation(value = "批量修改调度状态(按人员类型)", notes = "批量修改日期范围内的可调度状态,不影响价格。\n\n**关联字典**:\n- staff_type(人员类型)→ staffType路径参数") - @PutMapping("/type/{staffType}/prices/batch-status") - public Result batchUpdateStatus( - @ApiParam("人员类型: GUIDE/GUIDE_ASSISTANT/PHOTOGRAPHER/LEADER/OTHER") @PathVariable String staffType, -@@ -54,7 +54,7 @@ public class StaffPriceCalendarController { - return Result.success(); - } - -- @ApiOperation("清除价格日历(按人员类型)") -+ @ApiOperation(value = "清除价格日历(按人员类型)", notes = "删除指定日期范围内该类型人员的价格记录。日期格式:yyyy-MM-dd。\n\n**关联字典**:\n- staff_type(人员类型)→ staffType路径参数") - @DeleteMapping("/type/{staffType}/prices") - public Result deletePrices( - @ApiParam("人员类型: GUIDE/GUIDE_ASSISTANT/PHOTOGRAPHER/LEADER/OTHER") @PathVariable String staffType, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffTagController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffTagController.java -index beceb5f..ff68d2c 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/staff/controller/StaffTagController.java -@@ -26,7 +26,7 @@ public class StaffTagController { - - private final StaffTagService tagService; - -- @ApiOperation("预设标签列表(分页)") -+ @ApiOperation(value = "预设标签列表(分页)", notes = "分页查询服务人员标签库,支持按关键词搜索。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -35,13 +35,13 @@ public class StaffTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("全部标签列表") -+ @ApiOperation(value = "全部标签列表", notes = "不分页返回所有标签,用于人员编辑时的标签选择。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建标签") -+ @ApiOperation(value = "创建标签", notes = "创建预设标签,标签名不可重复。") - @PostMapping("/tag") - public Result createTag(@ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, - HttpServletRequest httpRequest) { -@@ -49,7 +49,7 @@ public class StaffTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "按名称查找或自动创建标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag(@ApiParam("标签名称请求体") @Valid @RequestBody TagCreateRequest request, - HttpServletRequest httpRequest) { -@@ -57,21 +57,21 @@ public class StaffTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("更新标签") -+ @ApiOperation(value = "更新标签", notes = "修改标签名称或颜色。") - @PutMapping("/tag/{tagId}") - public Result updateTag(@ApiParam("标签ID") @PathVariable Long tagId, - @ApiParam("标签更新请求") @Valid @RequestBody TagUpdateRequest request) { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并解除所有人员与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("设置人员标签") -+ @ApiOperation(value = "设置人员标签", notes = "全量替换指定人员的标签列表。") - @PutMapping("/{staffId}/tags") - public Result updateStaffTags(@ApiParam("人员ID") @PathVariable Long staffId, - @ApiParam("标签ID列表请求") @Valid @RequestBody StaffTagUpdateRequest request) { -@@ -79,7 +79,7 @@ public class StaffTagController { - return Result.success(); - } - -- @ApiOperation("批量添加/移除标签") -+ @ApiOperation(value = "批量添加/移除标签", notes = "对多个人员批量添加/移除标签。增量操作。") - @PutMapping("/batch/tags") - public Result batchUpdateTags(@ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { - tagService.batchUpdateTags(request.getStaffIds(), request.getAddTagIds(), request.getRemoveTagIds()); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/InternalSuppliesController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/InternalSuppliesController.java b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/InternalSuppliesController.java -index 5467d19..e827b51 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/InternalSuppliesController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/InternalSuppliesController.java -@@ -17,7 +17,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】备品(Feign调用)") -+@Api(tags = "【内部接口】备品(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/supplies") - @RequiredArgsConstructor -@@ -25,7 +25,7 @@ public class InternalSuppliesController { - - private final SuppliesService suppliesService; - -- @ApiOperation("获取备品简要信息") -+ @ApiOperation(value = "获取备品简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个备品的简要信息,返回ID、名称、分类编码、计费类型、状态。不存在时返回错误。\n\n**关联字典**:\n- supplies_category(备品分类,返回字段categoryCode):CAMPING=露营, CLOTHING=服装, EQUIPMENT=装备, SAFETY=安全\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/item/{suppliesId}") - public Result> getSuppliesBrief(@PathVariable Long suppliesId) { - SuppliesItem item = suppliesService.getSuppliesEntity(suppliesId); -@@ -41,7 +41,7 @@ public class InternalSuppliesController { - return Result.success(brief); - } - -- @ApiOperation("批量获取备品简要信息") -+ @ApiOperation(value = "批量获取备品简要信息", notes = "【仅限内部Feign调用】批量获取备品简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询产品关联的备品资源。\n\n**关联字典**:\n- supplies_category(备品分类,返回字段categoryCode):CAMPING=露营, CLOTHING=服装, EQUIPMENT=装备, SAFETY=安全\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/items/batch") - public Result>> getSuppliesBatch(@RequestParam @Size(max = 500) List suppliesIds) { - List> results = suppliesIds.stream() -@@ -61,9 +61,9 @@ public class InternalSuppliesController { - return Result.success(results); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配备品并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - suppliesService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesController.java b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesController.java -index 435f28b..964e6fc 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesController.java -@@ -26,7 +26,7 @@ public class SuppliesController { - - private final SuppliesService suppliesService; - -- @ApiOperation("创建备品") -+ @ApiOperation(value = "创建备品", notes = "新建备品资源(帐篷、睡袋、炊具等物资),初始状态为草稿(status=0)。需走企微审批上架。支持按件(PER_ITEM)和按人(PER_PERSON)计费。\n\n**关联字典**:\n- supplies_category:备品分类(表单选择)\n- billing_type:计费方式(表单选择)") - @PostMapping("/item") - public Result createSupplies( - @ApiParam("备品创建请求") @Valid @RequestBody SuppliesCreateRequest request, -@@ -35,19 +35,19 @@ public class SuppliesController { - return Result.success(suppliesService.createSupplies(request, adminId)); - } - -- @ApiOperation("备品列表") -+ @ApiOperation(value = "备品列表", notes = "分页查询备品列表,支持按名称、状态、分类等条件筛选。\n\n**关联字典**:\n- supplies_category:备品分类(筛选+列表显示)\n- billing_type:计费方式(列表显示)") - @GetMapping("/items") - public Result> listSupplies(@ApiParam("备品查询请求") @Valid SuppliesQueryRequest query) { - return Result.success(suppliesService.listSupplies(query)); - } - -- @ApiOperation("备品详情") -+ @ApiOperation(value = "备品详情", notes = "获取备品完整信息,包含素材URL、标签等。\n\n**关联字典**:\n- supplies_category:备品分类(详情显示)\n- billing_type:计费方式(详情显示)") - @GetMapping("/item/{suppliesId}") - public Result getSupplies(@ApiParam("备品ID") @PathVariable Long suppliesId) { - return Result.success(suppliesService.getSupplies(suppliesId)); - } - -- @ApiOperation("更新备品") -+ @ApiOperation(value = "更新备品", notes = "更新备品基本信息,不改变当前状态。\n\n**关联字典**:\n- supplies_category:备品分类(表单选择)\n- billing_type:计费方式(表单选择)") - @PutMapping("/item/{suppliesId}") - public Result updateSupplies( - @ApiParam("备品ID") @PathVariable Long suppliesId, -@@ -57,7 +57,7 @@ public class SuppliesController { - return Result.success(suppliesService.updateSupplies(suppliesId, request, adminId)); - } - -- @ApiOperation("删除备品") -+ @ApiOperation(value = "删除备品", notes = "软删除备品。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/item/{suppliesId}") - public Result deleteSupplies( - @ApiParam("备品ID") @PathVariable Long suppliesId, -@@ -68,7 +68,7 @@ public class SuppliesController { - return Result.success(); - } - -- @ApiOperation("提交启用/禁用审批") -+ @ApiOperation(value = "提交启用/禁用审批", notes = "向企微OA提交审批。targetStatus=1申请上架,targetStatus=2申请下架。返回审批单号spNo。") - @PostMapping("/item/{suppliesId}/submit-approval") - public Result> submitApproval( - @ApiParam("备品ID") @PathVariable Long suppliesId, -@@ -80,7 +80,7 @@ public class SuppliesController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("上下架切换") -+ @ApiOperation(value = "上下架切换", notes = "直接修改状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/item/{suppliesId}/status") - public Result updateStatus( - @ApiParam("备品ID") @PathVariable Long suppliesId, -@@ -91,7 +91,7 @@ public class SuppliesController { - return Result.success(); - } - -- @ApiOperation("批量上下架") -+ @ApiOperation(value = "批量上下架", notes = "批量修改多个备品的状态,跳过审批流程。") - @PutMapping("/items/batch/status") - public Result batchUpdateStatus( - @ApiParam("备品状态请求") @Valid @RequestBody SuppliesStatusRequest request, -@@ -103,7 +103,7 @@ public class SuppliesController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个备品。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/items/batch") - public Result batchDelete( - @ApiParam("批量删除请求") @Valid @RequestBody BatchDeleteRequest request, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesTagController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesTagController.java -index 7529058..8095ade 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/supplies/controller/SuppliesTagController.java -@@ -27,7 +27,7 @@ public class SuppliesTagController { - - private final SuppliesTagService tagService; - -- @ApiOperation("获取管理标签列表(分页)") -+ @ApiOperation(value = "获取管理标签列表(分页)", notes = "分页查询备品标签库,支持按关键词搜索。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -36,13 +36,13 @@ public class SuppliesTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("获取全部标签") -+ @ApiOperation(value = "获取全部标签", notes = "不分页返回所有标签,用于备品编辑时的标签选择下拉。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建管理标签") -+ @ApiOperation(value = "创建管理标签", notes = "创建预设标签,标签名不可重复。") - @PostMapping("/tag") - public Result createTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -51,7 +51,7 @@ public class SuppliesTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "按名称查找或自动创建标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag( - @ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, -@@ -60,7 +60,7 @@ public class SuppliesTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("编辑标签") -+ @ApiOperation(value = "编辑标签", notes = "修改标签名称或颜色,所有关联备品自动生效。") - @PutMapping("/tag/{tagId}") - public Result updateTag( - @ApiParam("标签ID") @PathVariable Long tagId, -@@ -68,14 +68,14 @@ public class SuppliesTagController { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并解除所有备品与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("更新备品标签") -+ @ApiOperation(value = "更新备品标签", notes = "全量替换指定备品的标签列表。") - @PutMapping("/item/{suppliesId}/tags") - public Result updateSuppliesTags( - @ApiParam("备品ID") @PathVariable Long suppliesId, -@@ -87,7 +87,7 @@ public class SuppliesTagController { - return Result.success(); - } - -- @ApiOperation("批量打标签") -+ @ApiOperation(value = "批量打标签", notes = "对多个备品批量添加/移除标签。增量操作。") - @PutMapping("/items/batch/tags") - public Result batchUpdateTags( - @ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/InternalVehicleController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/InternalVehicleController.java b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/InternalVehicleController.java -index 4e672d1..a0dc396 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/InternalVehicleController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/InternalVehicleController.java -@@ -17,7 +17,7 @@ import java.util.stream.Collectors; - - @Slf4j - @Validated --@Api(tags = "【内部接口】车型(Feign调用)") -+@Api(tags = "【内部接口】车型(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/vehicle") - @RequiredArgsConstructor -@@ -25,7 +25,7 @@ public class InternalVehicleController { - - private final VehicleModelService vehicleModelService; - -- @ApiOperation("获取车型简要信息") -+ @ApiOperation(value = "获取车型简要信息", notes = "【仅限内部Feign调用】供产品服务获取单个车型的简要信息,返回ID、名称、车辆类型、品牌、座位数、状态。不存在时返回错误。\n\n**关联字典**:\n- vehicle_type(车辆类型,返回字段vehicleType):CAR=小轿车, SUV=越野车, VAN=商务车, BUS=大巴, MINIBUS=中巴\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/model/{vehicleId}") - public Result> getVehicleBrief(@PathVariable Long vehicleId) { - VehicleModel model = vehicleModelService.getVehicleEntity(vehicleId); -@@ -42,7 +42,7 @@ public class InternalVehicleController { - return Result.success(brief); - } - -- @ApiOperation("批量获取车型简要信息") -+ @ApiOperation(value = "批量获取车型简要信息", notes = "【仅限内部Feign调用】批量获取车型简要信息,最多500个ID。不存在的ID自动过滤。供产品服务批量查询行程关联的车辆资源。\n\n**关联字典**:\n- vehicle_type(车辆类型,返回字段vehicleType):CAR=小轿车, SUV=越野车, VAN=商务车, BUS=大巴, MINIBUS=中巴\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/models/batch") - public Result>> getVehicleBatch(@RequestParam @Size(max = 500) List vehicleIds) { - List> results = vehicleIds.stream() -@@ -63,7 +63,7 @@ public class InternalVehicleController { - return Result.success(results); - } - -- @ApiOperation("按车辆类型查询车辆") -+ @ApiOperation(value = "按车辆类型查询车辆", notes = "【仅限内部Feign调用】按vehicleType查询第一个匹配的车型。vehicleType如:SEDAN(轿车)、SUV、MPV、BUS(大巴)、MINIBUS(中巴)等。未找到时返回null。\n\n**关联字典**:\n- vehicle_type(车辆类型,请求参数+返回字段vehicleType):CAR=小轿车, SUV=越野车, VAN=商务车, BUS=大巴, MINIBUS=中巴\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/model/by-type/{vehicleType}") - public Result> getVehicleByType(@PathVariable String vehicleType) { - VehicleModel model = vehicleModelService.getVehicleByType(vehicleType); -@@ -80,7 +80,7 @@ public class InternalVehicleController { - return Result.success(brief); - } - -- @ApiOperation("按名称查询车辆") -+ @ApiOperation(value = "按名称查询车辆", notes = "【仅限内部Feign调用】按车型名称精确查询车辆信息。未找到时返回null。供产品服务通过名称关联车型使用。\n\n**关联字典**:\n- vehicle_type(车辆类型,返回字段vehicleType):CAR=小轿车, SUV=越野车, VAN=商务车, BUS=大巴, MINIBUS=中巴\n- common_status(状态,返回字段status):ACTIVE=启用, INACTIVE=停用") - @GetMapping("/model/by-name/{name}") - public Result> getVehicleByName(@PathVariable String name) { - VehicleModel model = vehicleModelService.getVehicleByName(name); -@@ -97,9 +97,9 @@ public class InternalVehicleController { - return Result.success(brief); - } - -- @ApiOperation("处理审批回调结果") -+ @ApiOperation(value = "处理审批回调结果", notes = "【仅限内部Feign调用】接收企微OA审批回调,按thirdNo匹配车型并更新启用/禁用状态。由hl-callback-service通过MQ消费后调用,幂等处理。\n\n**关联字典**:\n- approval_sp_status(审批状态,请求字段spStatus)") - @PostMapping("/approval-result") -- public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { -+ public Result handleApprovalResult(@RequestBody ApprovalResultDTO dto) { - log.info("Received approval result: thirdNo={}, spStatus={}", dto.getThirdNo(), dto.getSpStatus()); - vehicleModelService.handleApprovalResult(dto.getThirdNo(), dto.getSpStatus()); - return Result.success(); -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleModelController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleModelController.java b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleModelController.java -index de59d9f..37797fd 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleModelController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleModelController.java -@@ -25,7 +25,7 @@ public class VehicleModelController { - - private final VehicleModelService vehicleModelService; - -- @ApiOperation("创建车型") -+ @ApiOperation(value = "创建车型", notes = "新建车型资源(如7座商务车、14座中巴等),初始状态为草稿(status=0)。车型有独立的价格日历用于报价计算。需走企微审批上架。\n\n**关联字典**:\n- vehicle_type:车辆类型(表单选择)") - @PostMapping("/model") - public Result createVehicle(@ApiParam("车型创建请求") @Valid @RequestBody VehicleCreateRequest request, - HttpServletRequest httpRequest) { -@@ -33,26 +33,26 @@ public class VehicleModelController { - return Result.success(vehicleModelService.createVehicle(request, adminId)); - } - -- @ApiOperation("车型列表") -+ @ApiOperation(value = "车型列表", notes = "分页查询车型列表,支持按名称、状态、车辆类型等条件筛选。\n\n**关联字典**:\n- vehicle_type:车辆类型(筛选+列表显示)") - @GetMapping("/models") - public Result> listVehicles(@ApiParam("车型查询请求") @Valid VehicleQueryRequest query) { - return Result.success(vehicleModelService.listVehicles(query)); - } - -- @ApiOperation("车型全量列表(不分页,用于下拉选择)") -+ @ApiOperation(value = "车型全量列表(不分页,用于下拉选择)", notes = "返回所有车型列表,可选按状态筛选。适用于产品编排时选择车型的下拉选择框。不分页返回全部数据。\n\n**关联字典**:\n- vehicle_type:车辆类型(列表显示)") - @GetMapping("/models/all") - public Result> listAllVehicles( - @ApiParam("状态筛选:1=上架") @RequestParam(required = false) Integer status) { - return Result.success(vehicleModelService.listAllVehicles(status)); - } - -- @ApiOperation("车型详情") -+ @ApiOperation(value = "车型详情", notes = "获取车型完整信息,包含座位数、品牌、素材URL、标签等。\n\n**关联字典**:\n- vehicle_type:车辆类型(详情显示)") - @GetMapping("/model/{vehicleId}") - public Result getVehicle(@ApiParam("车型ID") @PathVariable Long vehicleId) { - return Result.success(vehicleModelService.getVehicle(vehicleId)); - } - -- @ApiOperation("更新车型") -+ @ApiOperation(value = "更新车型", notes = "更新车型基本信息,不改变当前状态。\n\n**关联字典**:\n- vehicle_type:车辆类型(表单选择)") - @PutMapping("/model/{vehicleId}") - public Result updateVehicle(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("车型更新请求") @Valid @RequestBody VehicleUpdateRequest request, -@@ -61,7 +61,7 @@ public class VehicleModelController { - return Result.success(vehicleModelService.updateVehicle(vehicleId, request, adminId)); - } - -- @ApiOperation("删除车型") -+ @ApiOperation(value = "删除车型", notes = "软删除车型。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/model/{vehicleId}") - public Result deleteVehicle(@ApiParam("车型ID") @PathVariable Long vehicleId, HttpServletRequest httpRequest) { - Long adminId = getAdminId(httpRequest); -@@ -70,7 +70,7 @@ public class VehicleModelController { - return Result.success(); - } - -- @ApiOperation("提交审批") -+ @ApiOperation(value = "提交审批", notes = "向企微OA提交车型启用/禁用审批。targetStatus=1申请上架,targetStatus=2申请下架。返回审批单号spNo。") - @PostMapping("/model/{vehicleId}/submit-approval") - public Result> submitApproval(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("审批提交请求体") @Valid @RequestBody ApprovalSubmitRequest request, -@@ -80,7 +80,7 @@ public class VehicleModelController { - return Result.success(Map.of("spNo", spNo)); - } - -- @ApiOperation("更新状态") -+ @ApiOperation(value = "更新状态", notes = "直接修改车型状态(跳过审批),仅限SUPER_ADMIN。状态值:0=草稿,1=上架,2=下架。") - @PutMapping("/model/{vehicleId}/status") - public Result updateStatus(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("状态请求体") @Valid @RequestBody VehicleStatusRequest request, -@@ -90,7 +90,7 @@ public class VehicleModelController { - return Result.success(); - } - -- @ApiOperation("批量更新状态") -+ @ApiOperation(value = "批量更新状态", notes = "批量修改多个车型的状态,跳过审批流程。") - @PutMapping("/models/batch/status") - public Result batchUpdateStatus(@ApiParam("批量状态请求体") @Valid @RequestBody VehicleStatusRequest request, - HttpServletRequest httpRequest) { -@@ -98,7 +98,7 @@ public class VehicleModelController { - return Result.success(); - } - -- @ApiOperation("批量删除") -+ @ApiOperation(value = "批量删除", notes = "批量软删除多个车型。仅SUPER_ADMIN或创建者可操作。") - @DeleteMapping("/models/batch") - public Result batchDelete(@ApiParam("批量删除请求体") @Valid @RequestBody VehicleBatchDeleteRequest request, - HttpServletRequest httpRequest) { -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehiclePriceCalendarController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehiclePriceCalendarController.java b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehiclePriceCalendarController.java -index 52a68eb..c1bcfba 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehiclePriceCalendarController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehiclePriceCalendarController.java -@@ -27,7 +27,7 @@ public class VehiclePriceCalendarController { - - private final VehiclePriceCalendarService priceCalendarService; - -- @ApiOperation("查询价格日历") -+ @ApiOperation(value = "查询价格日历", notes = "按月查询车型的每日租赁价格和可调度状态。") - @GetMapping("/model/{vehicleId}/prices") - public Result getPriceCalendar(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("年份") @RequestParam @Min(2020) @Max(2100) Integer year, -@@ -35,7 +35,7 @@ public class VehiclePriceCalendarController { - return Result.success(priceCalendarService.getPriceCalendar(vehicleId, year, month)); - } - -- @ApiOperation("批量设置价格") -+ @ApiOperation(value = "批量设置价格", notes = "在指定日期范围内批量设置车型的租赁成本价和可调度状态。") - @PutMapping("/model/{vehicleId}/prices") - public Result batchSetPrices(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("价格日历设置请求") @Valid @RequestBody PriceCalendarSetRequest request) { -@@ -43,7 +43,7 @@ public class VehiclePriceCalendarController { - return Result.success(); - } - -- @ApiOperation("批量修改调度状态") -+ @ApiOperation(value = "批量修改调度状态", notes = "批量修改日期范围内车型的可调度状态,不影响价格。") - @PutMapping("/model/{vehicleId}/prices/batch-status") - public Result batchUpdateStatus(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("价格日历状态请求") @Valid @RequestBody PriceCalendarStatusRequest request) { -@@ -51,7 +51,7 @@ public class VehiclePriceCalendarController { - return Result.success(); - } - -- @ApiOperation("清除价格日历") -+ @ApiOperation(value = "清除价格日历", notes = "删除指定日期范围内车型的价格记录。日期格式:yyyy-MM-dd。") - @DeleteMapping("/model/{vehicleId}/prices") - public Result deletePrices(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("开始日期") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate, -``` - -### `hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleTagController.java` (M) - -```diff -diff --git a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleTagController.java b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleTagController.java -index a7a1b49..b2ad988 100644 ---- a/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleTagController.java -+++ b/hl-resource-service/src/main/java/com/hulalv/resource/vehicle/controller/VehicleTagController.java -@@ -26,7 +26,7 @@ public class VehicleTagController { - - private final VehicleTagService tagService; - -- @ApiOperation("预设标签列表(分页)") -+ @ApiOperation(value = "预设标签列表(分页)", notes = "分页查询车型标签库,支持按关键词搜索。") - @GetMapping("/tags") - public Result> listManagedTags( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -35,13 +35,13 @@ public class VehicleTagController { - return Result.success(tagService.listManagedTags(page, pageSize, keyword)); - } - -- @ApiOperation("全部标签列表") -+ @ApiOperation(value = "全部标签列表", notes = "不分页返回所有标签,用于车型编辑时的标签选择。") - @GetMapping("/tags/all") - public Result> listAllTags() { - return Result.success(tagService.listAllTags()); - } - -- @ApiOperation("创建标签") -+ @ApiOperation(value = "创建标签", notes = "创建预设标签,标签名不可重复。") - @PostMapping("/tag") - public Result createTag(@ApiParam("标签创建请求") @Valid @RequestBody TagCreateRequest request, - HttpServletRequest httpRequest) { -@@ -49,7 +49,7 @@ public class VehicleTagController { - return Result.success(tagService.createTag(request, adminId)); - } - -- @ApiOperation("解析自定义标签") -+ @ApiOperation(value = "解析自定义标签", notes = "按名称查找或自动创建标签。") - @PostMapping("/tag/adhoc") - public Result resolveAdHocTag(@ApiParam("标签名称请求体") @Valid @RequestBody TagCreateRequest request, - HttpServletRequest httpRequest) { -@@ -57,21 +57,21 @@ public class VehicleTagController { - return Result.success(tagService.resolveAdHocTag(request.getTagName(), adminId)); - } - -- @ApiOperation("更新标签") -+ @ApiOperation(value = "更新标签", notes = "修改标签名称或颜色。") - @PutMapping("/tag/{tagId}") - public Result updateTag(@ApiParam("标签ID") @PathVariable Long tagId, - @ApiParam("标签更新请求") @Valid @RequestBody TagUpdateRequest request) { - return Result.success(tagService.updateTag(tagId, request)); - } - -- @ApiOperation("删除标签") -+ @ApiOperation(value = "删除标签", notes = "删除标签并解除所有车型与该标签的关联。") - @DeleteMapping("/tag/{tagId}") - public Result deleteTag(@ApiParam("标签ID") @PathVariable Long tagId) { - tagService.deleteTag(tagId); - return Result.success(); - } - -- @ApiOperation("设置车型标签") -+ @ApiOperation(value = "设置车型标签", notes = "全量替换指定车型的标签列表。") - @PutMapping("/model/{vehicleId}/tags") - public Result updateVehicleTags(@ApiParam("车型ID") @PathVariable Long vehicleId, - @ApiParam("标签ID列表请求") @Valid @RequestBody VehicleTagUpdateRequest request) { -@@ -79,7 +79,7 @@ public class VehicleTagController { - return Result.success(); - } - -- @ApiOperation("批量添加/移除标签") -+ @ApiOperation(value = "批量添加/移除标签", notes = "对多个车型批量添加/移除标签。增量操作。") - @PutMapping("/models/batch/tags") - public Result batchUpdateTags(@ApiParam("批量标签请求") @Valid @RequestBody BatchTagRequest request) { - tagService.batchUpdateTags(request.getVehicleIds(), request.getAddTagIds(), request.getRemoveTagIds()); -``` - -### `hl-review-service/src/main/java/com/hulalv/review/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-review-service/src/main/java/com/hulalv/review/config/Knife4jConfig.java b/hl-review-service/src/main/java/com/hulalv/review/config/Knife4jConfig.java -index fde29e7..d3131ce 100644 ---- a/hl-review-service/src/main/java/com/hulalv/review/config/Knife4jConfig.java -+++ b/hl-review-service/src/main/java/com/hulalv/review/config/Knife4jConfig.java -@@ -26,18 +26,4 @@ public class Knife4jConfig { - .build(); - } - -- @Bean -- public Docket internalReviewApi() { -- return new Docket(DocumentationType.SWAGGER_2) -- .groupName("2. 评价内部接口") -- .apiInfo(new ApiInfoBuilder() -- .title("评价内部 API") -- .description("评价内部接口(供BFF等服务调用)") -- .version("1.0") -- .build()) -- .select() -- .apis(RequestHandlerSelectors.basePackage("com.hulalv.review.controller")) -- .paths(PathSelectors.ant("/internal/**")) -- .build(); -- } - } -``` - -### `hl-review-service/src/main/java/com/hulalv/review/controller/AdminReviewController.java` (M) - -```diff -diff --git a/hl-review-service/src/main/java/com/hulalv/review/controller/AdminReviewController.java b/hl-review-service/src/main/java/com/hulalv/review/controller/AdminReviewController.java -index 1781646..ad503eb 100644 ---- a/hl-review-service/src/main/java/com/hulalv/review/controller/AdminReviewController.java -+++ b/hl-review-service/src/main/java/com/hulalv/review/controller/AdminReviewController.java -@@ -25,19 +25,19 @@ public class AdminReviewController { - - private final ReviewService reviewService; - -- @ApiOperation("评价列表(支持好中差评/有图/有视频筛选)") -+ @ApiOperation(value = "评价列表(支持好中差评/有图/有视频筛选)", notes = "分页查询全部评价(含待审核/已通过/已拒绝),支持按评价等级、是否有图/视频、目标类型筛选\n\n**关联字典**:\n- review_status:评价审核状态(列表筛选+显示)\n- rating_level:评价等级(列表筛选+显示)") - @GetMapping("/list") - public Result> listReviews(@ApiParam("评价查询条件") ReviewQueryRequest request) { - return Result.success(reviewService.listReviews(request)); - } - -- @ApiOperation("评价详情") -+ @ApiOperation(value = "评价详情", notes = "**关联字典**:\n- review_status:评价审核状态(显示)\n- rating_level:评价等级(显示)") - @GetMapping("/{reviewId}") - public Result getReviewDetail(@ApiParam("评价ID") @PathVariable Long reviewId) { - return Result.success(reviewService.getReviewDetail(reviewId)); - } - -- @ApiOperation("通过评价") -+ @ApiOperation(value = "通过评价", notes = "审核通过评价,通过后评价在小程序端公开展示。状态流转:PENDING_REVIEW → APPROVED") - @PostMapping("/{reviewId}/approve") - public Result approve(@ApiParam("评价ID") @PathVariable Long reviewId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -47,7 +47,7 @@ public class AdminReviewController { - return Result.success(); - } - -- @ApiOperation("拒绝评价") -+ @ApiOperation(value = "拒绝评价", notes = "审核拒绝评价,需填写拒绝原因。拒绝后评价不公开展示。状态流转:PENDING_REVIEW → REJECTED") - @PostMapping("/{reviewId}/reject") - public Result reject(@ApiParam("评价ID") @PathVariable Long reviewId, - @ApiParam("拒绝请求") @Valid @RequestBody RejectRequest body, -@@ -59,7 +59,7 @@ public class AdminReviewController { - return Result.success(); - } - -- @ApiOperation("覆盖通过(机器拒绝的)") -+ @ApiOperation(value = "覆盖通过(机器拒绝的)", notes = "对阿里云内容审核自动拒绝的评价进行人工覆盖通过。状态流转:AUTO_REJECTED → APPROVED") - @PostMapping("/{reviewId}/override-approve") - public Result overrideApprove(@ApiParam("评价ID") @PathVariable Long reviewId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -69,7 +69,8 @@ public class AdminReviewController { - return Result.success(); - } - -- @ApiOperation("回复评价(每条评价仅可回复一次)") -+ @ApiOperation(value = "回复评价(每条评价仅可回复一次)", -+ notes = "管理员回复用户评价,回复内容在小程序端公开展示。每条评价仅允许回复一次,不可修改。\n\n**权限**:需管理员登录。") - @PostMapping("/{reviewId}/reply") - public Result adminReply(@ApiParam("评价ID") @PathVariable Long reviewId, - @ApiParam("回复内容") @Valid @RequestBody AdminReplyRequest body, -``` - -### `hl-review-service/src/main/java/com/hulalv/review/controller/InternalMpReviewController.java` (M) - -```diff -diff --git a/hl-review-service/src/main/java/com/hulalv/review/controller/InternalMpReviewController.java b/hl-review-service/src/main/java/com/hulalv/review/controller/InternalMpReviewController.java -index b3dd6a3..62fb7d0 100644 ---- a/hl-review-service/src/main/java/com/hulalv/review/controller/InternalMpReviewController.java -+++ b/hl-review-service/src/main/java/com/hulalv/review/controller/InternalMpReviewController.java -@@ -19,7 +19,7 @@ import javax.validation.Valid; - import java.util.List; - import java.util.Map; - --@Api(tags = "【内部接口】小程序评价(Feign调用)") -+@Api(tags = "【内部接口】小程序评价(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/mp/review") - @RequiredArgsConstructor -@@ -27,7 +27,7 @@ public class InternalMpReviewController { - - private final ReviewService reviewService; - -- @ApiOperation("创建评价(仅针对产品,每个订单仅可评价一次)") -+ @ApiOperation(value = "创建评价(仅针对产品,每个订单仅可评价一次)", notes = "**关联字典**:\n- review_status:评价审核状态(返回字段)\n- rating_level:评价等级(返回字段)") - @PostMapping("/create") - public Result createReview(@Valid @RequestBody CreateReviewRequest body, - HttpServletRequest request) { -@@ -35,13 +35,14 @@ public class InternalMpReviewController { - return Result.success(reviewService.createReview(userId, body)); - } - -- @ApiOperation("检查订单是否已评价") -+ @ApiOperation(value = "检查订单是否已评价", -+ notes = "内部服务间调用。检查指定订单是否已有评价记录,用于小程序端订单详情页控制评价入口的显示。") - @GetMapping("/order/{orderId}/reviewed") - public Result isOrderReviewed(@PathVariable Long orderId) { - return Result.success(reviewService.isOrderReviewed(orderId)); - } - -- @ApiOperation("我的评价列表") -+ @ApiOperation(value = "我的评价列表", notes = "**关联字典**:\n- review_status:评价审核状态(显示)\n- rating_level:评价等级(显示)") - @GetMapping("/my") - public Result> getMyReviews(MpReviewQueryRequest query, - HttpServletRequest request) { -@@ -49,13 +50,13 @@ public class InternalMpReviewController { - return Result.success(reviewService.getMyReviews(userId, query)); - } - -- @ApiOperation("某目标的已通过评价(公开,支持好中差评/有图/有视频筛选)") -+ @ApiOperation(value = "某目标的已通过评价(公开,支持好中差评/有图/有视频筛选)", notes = "**关联字典**:\n- rating_level:评价等级(筛选+显示)") - @GetMapping("/target") - public Result> getTargetReviews(@Valid TargetReviewQueryRequest query) { - return Result.success(reviewService.getTargetReviews(query)); - } - -- @ApiOperation("关键词搜索评价(公开)") -+ @ApiOperation(value = "关键词搜索评价(公开)", notes = "**关联字典**:\n- rating_level:评价等级(显示)") - @GetMapping("/search") - public Result> searchReviews( - @ApiParam("搜索关键词") @RequestParam String keyword, -@@ -66,14 +67,15 @@ public class InternalMpReviewController { - return Result.success(reviewService.searchReviews(keyword, targetType, targetId, page, pageSize)); - } - -- @ApiOperation("首页精选评价") -+ @ApiOperation(value = "首页精选评价", notes = "**关联字典**:\n- rating_level:评价等级(显示)") - @GetMapping("/featured") - public Result> getFeaturedReviews( - @ApiParam("数量限制") @RequestParam(defaultValue = "5") Integer limit) { - return Result.success(reviewService.getFeaturedReviews(limit)); - } - -- @ApiOperation("订单可评价目标列表") -+ @ApiOperation(value = "订单可评价目标列表", -+ notes = "内部服务间调用。返回订单关联的可评价目标(产品、定制师等),用于评价页面选择评价对象。已评价的目标不会重复出现。") - @GetMapping("/order/{orderId}/reviewable-targets") - public Result>> getReviewableTargets( - @PathVariable Long orderId, HttpServletRequest request) { -@@ -81,7 +83,8 @@ public class InternalMpReviewController { - return Result.success(reviewService.getReviewableTargets(orderId, userId)); - } - -- @ApiOperation("点赞/取消点赞评价") -+ @ApiOperation(value = "点赞/取消点赞评价", -+ notes = "内部服务间调用。切换当前用户对评价的点赞状态(toggle),返回最新点赞状态和点赞总数。") - @PostMapping("/{reviewId}/like") - public Result> toggleLike(@PathVariable Long reviewId, - HttpServletRequest request) { -@@ -89,7 +92,8 @@ public class InternalMpReviewController { - return Result.success(reviewService.toggleLike(reviewId, userId)); - } - -- @ApiOperation("检查是否已点赞") -+ @ApiOperation(value = "检查是否已点赞", -+ notes = "内部服务间调用。检查当前用户是否已对指定评价点赞,用于小程序端渲染点赞按钮状态。") - @GetMapping("/{reviewId}/like/check") - public Result checkLiked(@PathVariable Long reviewId, - HttpServletRequest request) { -@@ -97,7 +101,8 @@ public class InternalMpReviewController { - return Result.success(reviewService.checkLiked(reviewId, userId)); - } - -- @ApiOperation("同步评价点赞数(供通用点赞服务回调)") -+ @ApiOperation(value = "同步评价点赞数(供通用点赞服务回调)", -+ notes = "内部服务间调用。通用点赞服务(user-service)发生点赞变化后回调此接口,同步更新评价表的点赞计数字段。") - @PostMapping("/{reviewId}/sync-like-count") - public Result syncLikeCount(@PathVariable Long reviewId, - @RequestParam int likeCount) { -``` - -### `hl-review-service/src/main/java/com/hulalv/review/controller/InternalReviewController.java` (M) - -```diff -diff --git a/hl-review-service/src/main/java/com/hulalv/review/controller/InternalReviewController.java b/hl-review-service/src/main/java/com/hulalv/review/controller/InternalReviewController.java -index 0567412..7e5f1cb 100644 ---- a/hl-review-service/src/main/java/com/hulalv/review/controller/InternalReviewController.java -+++ b/hl-review-service/src/main/java/com/hulalv/review/controller/InternalReviewController.java -@@ -21,7 +21,7 @@ import java.util.List; - import java.util.Map; - import java.util.stream.Collectors; - --@Api(tags = "【内部接口】评价统计(Feign调用)") -+@Api(tags = "【内部接口】评价统计(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/review") - @RequiredArgsConstructor -@@ -29,14 +29,14 @@ public class InternalReviewController { - - private final ReviewService reviewService; - -- @ApiOperation("目标评价统计(平均分,数量)") -+ @ApiOperation(value = "目标评价统计(平均分,数量)", notes = "**关联字典**:\n- rating_level:评价等级(统计维度)") - @GetMapping("/target-stats") - public Result getTargetStats(@RequestParam String targetType, - @RequestParam Long targetId) { - return Result.success(reviewService.getTargetStats(targetType, targetId)); - } - -- @ApiOperation("目标已通过评价列表") -+ @ApiOperation(value = "目标已通过评价列表", notes = "**关联字典**:\n- rating_level:评价等级(显示)") - @GetMapping("/target-list") - public Result> getTargetReviews( - @RequestParam String targetType, -@@ -46,7 +46,7 @@ public class InternalReviewController { - return Result.success(reviewService.getTargetReviewsInternal(targetType, targetId, page, pageSize)); - } - -- @ApiOperation("批量目标评价统计(聚合多个targetId)") -+ @ApiOperation(value = "批量目标评价统计(聚合多个targetId)", notes = "**关联字典**:\n- rating_level:评价等级(统计维度)") - @GetMapping("/stats-by-targets") - public Result getStatsByTargetIds( - @RequestParam String targetType, -@@ -55,7 +55,7 @@ public class InternalReviewController { - return Result.success(reviewService.getStatsByTargetIds(targetType, ids)); - } - -- @ApiOperation("批量目标已通过评价列表(聚合多个targetId)") -+ @ApiOperation(value = "批量目标已通过评价列表(聚合多个targetId)", notes = "**关联字典**:\n- rating_level:评价等级(显示)") - @GetMapping("/reviews-by-targets") - public Result> getReviewsByTargetIds( - @RequestParam String targetType, -@@ -66,13 +66,13 @@ public class InternalReviewController { - return Result.success(reviewService.getReviewsByTargetIds(targetType, ids, page, pageSize)); - } - -- @ApiOperation("产品精选评价(最高评分+最高点赞+统计)") -+ @ApiOperation(value = "产品精选评价(最高评分+最高点赞+统计)", notes = "**关联字典**:\n- rating_level:评价等级(显示)") - @GetMapping("/product-highlights") - public Result> getProductHighlights(@RequestParam Long productId) { - return Result.success(reviewService.getProductHighlightReviews(productId)); - } - -- @ApiOperation("定制师已通过评价列表") -+ @ApiOperation(value = "定制师已通过评价列表", notes = "**关联字典**:\n- rating_level:评价等级(筛选+显示)") - @GetMapping("/customizer-reviews") - public Result> getCustomizerReviews( - @RequestParam Long customizerId, -@@ -82,7 +82,8 @@ public class InternalReviewController { - return Result.success(reviewService.getCustomizerReviews(customizerId, page, pageSize, ratingLevel)); - } - -- @ApiOperation("定制师评价统计(总数/平均分/好评率)") -+ @ApiOperation(value = "定制师评价统计(总数/平均分/好评率)", -+ notes = "内部服务间调用。返回指定定制师的评价汇总统计:总评价数、平均评分、好评率等。用于定制师主页展示服务评价。") - @GetMapping("/customizer-review-stats") - public Result> getCustomizerReviewStats( - @RequestParam Long customizerId) { -``` - -### `hl-task-service/src/main/java/com/hulalv/task/controller/BoardController.java` (M) - -```diff -diff --git a/hl-task-service/src/main/java/com/hulalv/task/controller/BoardController.java b/hl-task-service/src/main/java/com/hulalv/task/controller/BoardController.java -index 75b6a7a..0629ed1 100644 ---- a/hl-task-service/src/main/java/com/hulalv/task/controller/BoardController.java -+++ b/hl-task-service/src/main/java/com/hulalv/task/controller/BoardController.java -@@ -33,7 +33,7 @@ public class BoardController { - - // ======================= Board CRUD ======================= - -- @ApiOperation("获取可见看板列表") -+ @ApiOperation(value = "获取可见看板列表", notes = "返回当前管理员可见的看板列表:超级管理员可见所有看板,普通管理员仅可见自己创建的或作为成员的看板") - @GetMapping("/boards") - public Result> getBoards(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -41,7 +41,7 @@ public class BoardController { - return Result.success(boardService.getVisibleBoards(adminId, role)); - } - -- @ApiOperation("看板详情") -+ @ApiOperation(value = "看板详情", notes = "返回看板基本信息(名称、描述、创建者),不含任务数据。查看任务请使用「获取看板任务」接口") - @GetMapping("/board/{boardId}") - public Result getBoardDetail(@ApiParam("看板ID") @PathVariable Long boardId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -49,7 +49,8 @@ public class BoardController { - return Result.success(boardService.getBoardDetail(boardId, adminId, role)); - } - -- @ApiOperation("创建自定义看板") -+ @ApiOperation(value = "创建自定义看板", -+ notes = "创建自定义看板,自动添加创建者为看板成员,并创建默认状态列(待办、进行中、已完成)。\n\n**权限**:需管理员登录。") - @OperationLog(value = "创建看板", module = "任务看板") - @PostMapping("/board") - public Result createBoard(@ApiParam("创建看板请求") @Valid @RequestBody CreateBoardRequest req, HttpServletRequest request) { -@@ -57,7 +58,8 @@ public class BoardController { - return Result.success(boardService.createBoard(req, adminId)); - } - -- @ApiOperation("更新看板") -+ @ApiOperation(value = "更新看板", -+ notes = "更新看板的名称和描述。仅看板创建者或超级管理员可操作。\n\n**权限**:需管理员登录,且为看板创建者或超级管理员。") - @OperationLog(value = "编辑看板", module = "任务看板") - @PutMapping("/board/{boardId}") - public Result updateBoard(@ApiParam("看板ID") @PathVariable Long boardId, -@@ -68,7 +70,7 @@ public class BoardController { - return Result.success(boardService.updateBoard(boardId, req, adminId, role)); - } - -- @ApiOperation("删除看板") -+ @ApiOperation(value = "删除看板", notes = "删除看板及其下所有状态列和任务(级联删除)。仅看板创建者或超级管理员可操作") - @OperationLog(value = "删除看板", module = "任务看板") - @DeleteMapping("/board/{boardId}") - public Result deleteBoard(@ApiParam("看板ID") @PathVariable Long boardId, HttpServletRequest request) { -@@ -80,13 +82,14 @@ public class BoardController { - - // ======================= Status columns ======================= - -- @ApiOperation("获取看板状态列") -+ @ApiOperation(value = "获取看板状态列", notes = "返回看板的所有状态列(如待办、进行中、已完成),按排序字段升序排列。拖拽任务到不同状态列实现状态流转") - @GetMapping("/board/{boardId}/statuses") - public Result> getStatuses(@ApiParam("看板ID") @PathVariable Long boardId) { - return Result.success(boardStatusService.getStatuses(boardId)); - } - -- @ApiOperation("创建状态列") -+ @ApiOperation(value = "创建状态列", -+ notes = "在看板中创建新的状态列(如测试中、待发布等),自动排到末尾。任务通过拖拽在不同状态列间流转。\n\n**权限**:需管理员登录且为看板成员。") - @OperationLog(value = "新增状态列", module = "任务看板") - @PostMapping("/board/{boardId}/status") - public Result createStatus(@ApiParam("看板ID") @PathVariable Long boardId, -@@ -97,7 +100,8 @@ public class BoardController { - return Result.success(boardStatusService.createStatus(boardId, req, adminId, role)); - } - -- @ApiOperation("更新状态列") -+ @ApiOperation(value = "更新状态列", -+ notes = "更新状态列的名称和颜色。\n\n**权限**:需管理员登录且为看板成员。") - @OperationLog(value = "编辑状态列", module = "任务看板") - @PutMapping("/status/{statusId}") - public Result updateStatus(@ApiParam("状态列ID") @PathVariable Long statusId, -@@ -108,7 +112,7 @@ public class BoardController { - return Result.success(boardStatusService.updateStatus(statusId, req, adminId, role)); - } - -- @ApiOperation("删除状态列") -+ @ApiOperation(value = "删除状态列", notes = "删除看板的状态列。如果状态列下有任务则不允许删除,需先移动或删除任务") - @OperationLog(value = "删除状态列", module = "任务看板") - @DeleteMapping("/status/{statusId}") - public Result deleteStatus(@ApiParam("状态列ID") @PathVariable Long statusId, -@@ -119,7 +123,7 @@ public class BoardController { - return Result.success(); - } - -- @ApiOperation("状态列排序") -+ @ApiOperation(value = "状态列排序", notes = "批量更新状态列的排序顺序。传入状态列ID数组,数组下标即为新的排序值。操作完成后通过WebSocket推送STATUS_REORDERED事件") - @PutMapping("/board/{boardId}/status/sort") - public Result sortStatuses(@ApiParam("看板ID") @PathVariable Long boardId, - @ApiParam("状态列排序请求") @Valid @RequestBody StatusSortRequest req, -@@ -133,13 +137,14 @@ public class BoardController { - - // ======================= Board Members ======================= - -- @ApiOperation("获取看板成员") -+ @ApiOperation(value = "获取看板成员", notes = "返回看板的所有成员列表,包含成员的管理员ID和姓名") - @GetMapping("/board/{boardId}/members") - public Result> getMembers(@ApiParam("看板ID") @PathVariable Long boardId) { - return Result.success(boardMemberService.getMembers(boardId)); - } - -- @ApiOperation("添加成员") -+ @ApiOperation(value = "添加成员", -+ notes = "批量添加管理员为看板成员,成为成员后可以查看看板、创建和操作任务。\n\n**权限**:需管理员登录,且为看板创建者或超级管理员。") - @OperationLog(value = "添加看板成员", module = "任务看板") - @PostMapping("/board/{boardId}/members") - public Result addMembers(@ApiParam("看板ID") @PathVariable Long boardId, -@@ -151,7 +156,7 @@ public class BoardController { - return Result.success(); - } - -- @ApiOperation("移除成员") -+ @ApiOperation(value = "移除成员", notes = "从看板中移除指定成员。仅看板创建者或超级管理员可操作,不能移除创建者自己") - @OperationLog(value = "移除看板成员", module = "任务看板") - @DeleteMapping("/board/{boardId}/member/{targetAdminId}") - public Result removeMember(@ApiParam("看板ID") @PathVariable Long boardId, -``` - -### `hl-task-service/src/main/java/com/hulalv/task/controller/TaskController.java` (M) - -```diff -diff --git a/hl-task-service/src/main/java/com/hulalv/task/controller/TaskController.java b/hl-task-service/src/main/java/com/hulalv/task/controller/TaskController.java -index 8593e4d..c85aeca 100644 ---- a/hl-task-service/src/main/java/com/hulalv/task/controller/TaskController.java -+++ b/hl-task-service/src/main/java/com/hulalv/task/controller/TaskController.java -@@ -31,7 +31,7 @@ public class TaskController { - - // ======================= Tasks ======================= - -- @ApiOperation("获取看板任务(按状态分组)") -+ @ApiOperation(value = "获取看板任务(按状态分组)", notes = "返回看板下所有任务,按状态列分组。支持按优先级(HIGH/MEDIUM/LOW)和负责人筛选,每组内按排序值升序排列\n\n**关联字典**:\n- task_priority:任务优先级(列表筛选+显示)") - @GetMapping("/board/{boardId}/tasks") - public Result> getBoardTasks(@ApiParam("看板ID") @PathVariable Long boardId, - @ApiParam("优先级") @RequestParam(required = false) String priority, -@@ -42,7 +42,7 @@ public class TaskController { - return Result.success(taskService.getBoardTasks(boardId, adminId, role, priority, assigneeId)); - } - -- @ApiOperation("任务详情") -+ @ApiOperation(value = "任务详情", notes = "返回任务完整信息,包含子任务列表、负责人信息、附件列表等\n\n**关联字典**:\n- task_priority:任务优先级(显示)") - @GetMapping("/{taskId}") - public Result getTaskDetail(@ApiParam("任务ID") @PathVariable Long taskId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -50,7 +50,7 @@ public class TaskController { - return Result.success(taskService.getTaskDetail(taskId, adminId, role)); - } - -- @ApiOperation("创建任务") -+ @ApiOperation(value = "创建任务", notes = "在指定看板和状态列下创建任务。创建成功后通过WebSocket推送TASK_CREATED事件,并通知被分配的负责人\n\n**关联字典**:\n- task_priority:任务优先级(创建时选择)") - @OperationLog(value = "创建任务", module = "任务看板") - @PostMapping - public Result createTask(@ApiParam("创建任务请求") @Valid @RequestBody CreateTaskRequest req, HttpServletRequest request) { -@@ -62,7 +62,8 @@ public class TaskController { - return Result.success(vo); - } - -- @ApiOperation("更新任务") -+ @ApiOperation(value = "更新任务", -+ notes = "更新任务的标题、描述、优先级、截止日期、负责人等信息。更新后通过WebSocket推送TASK_UPDATED事件,如果修改了负责人则额外通知新负责人。\n\n**权限**:需管理员登录且为看板成员。\n\n**关联字典**:\n- task_priority:任务优先级(编辑时选择)") - @OperationLog(value = "编辑任务", module = "任务看板") - @PutMapping("/{taskId}") - public Result updateTask(@ApiParam("任务ID") @PathVariable Long taskId, -@@ -78,7 +79,7 @@ public class TaskController { - return Result.success(vo); - } - -- @ApiOperation("变更任务状态") -+ @ApiOperation(value = "变更任务状态", notes = "将任务移动到指定状态列(拖拽操作),自动记录状态变更到时间线,并通过WebSocket推送TASK_STATUS_CHANGED事件") - @PutMapping("/{taskId}/status") - public Result changeStatus(@ApiParam("任务ID") @PathVariable Long taskId, - @ApiParam("变更状态请求") @Valid @RequestBody ChangeStatusRequest req, -@@ -91,7 +92,7 @@ public class TaskController { - return Result.success(); - } - -- @ApiOperation("任务排序") -+ @ApiOperation(value = "任务排序", notes = "更新任务在同一状态列内的排序位置,用于拖拽排序") - @PutMapping("/{taskId}/sort") - public Result sortTasks(@ApiParam("任务ID") @PathVariable Long taskId, - @ApiParam("任务排序请求") @Valid @RequestBody TaskSortRequest req, -@@ -102,7 +103,8 @@ public class TaskController { - return Result.success(); - } - -- @ApiOperation("删除任务") -+ @ApiOperation(value = "删除任务", -+ notes = "删除任务及其所有子任务、评论和时间线记录(级联删除)。删除后通过WebSocket推送TASK_DELETED事件。\n\n**权限**:需管理员登录且为看板成员。") - @OperationLog(value = "删除任务", module = "任务看板") - @DeleteMapping("/{taskId}") - public Result deleteTask(@ApiParam("任务ID") @PathVariable Long taskId, HttpServletRequest request) { -@@ -117,7 +119,8 @@ public class TaskController { - - // ======================= Subtasks ======================= - -- @ApiOperation("创建子任务") -+ @ApiOperation(value = "创建子任务", -+ notes = "在指定任务下创建子任务(待办项),用于拆分任务的执行步骤。子任务默认为未完成状态。\n\n**权限**:需管理员登录且为看板成员。") - @PostMapping("/{taskId}/subtask") - public Result createSubtask(@ApiParam("任务ID") @PathVariable Long taskId, - @ApiParam("创建子任务请求") @Valid @RequestBody CreateSubtaskRequest req, -@@ -128,7 +131,7 @@ public class TaskController { - return Result.success(vo); - } - -- @ApiOperation("切换子任务完成状态") -+ @ApiOperation(value = "切换子任务完成状态", notes = "切换子任务的完成/未完成状态(toggle),完成状态切换会自动记录到任务时间线") - @PutMapping("/subtask/{subtaskId}/toggle") - public Result toggleSubtask(@ApiParam("子任务ID") @PathVariable Long subtaskId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -137,7 +140,8 @@ public class TaskController { - return Result.success(); - } - -- @ApiOperation("删除子任务") -+ @ApiOperation(value = "删除子任务", -+ notes = "删除指定子任务。\n\n**权限**:需管理员登录且为看板成员。") - @DeleteMapping("/subtask/{subtaskId}") - public Result deleteSubtask(@ApiParam("子任务ID") @PathVariable Long subtaskId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -148,7 +152,7 @@ public class TaskController { - - // ======================= Timeline (comments + activities) ======================= - -- @ApiOperation("获取任务时间线") -+ @ApiOperation(value = "获取任务时间线", notes = "返回任务的完整操作记录,包含评论和系统自动记录的状态变更、人员分配等活动,按时间正序排列") - @GetMapping("/{taskId}/timeline") - public Result> getTimeline(@ApiParam("任务ID") @PathVariable Long taskId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -156,7 +160,7 @@ public class TaskController { - return Result.success(commentService.getTimeline(taskId, adminId, role)); - } - -- @ApiOperation("添加评论") -+ @ApiOperation(value = "添加评论", notes = "在任务时间线中添加评论,添加后自动通知任务负责人") - @PostMapping("/{taskId}/comment") - public Result addComment(@ApiParam("任务ID") @PathVariable Long taskId, - @ApiParam("创建评论请求") @Valid @RequestBody CreateCommentRequest req, -@@ -168,7 +172,7 @@ public class TaskController { - return Result.success(item); - } - -- @ApiOperation("删除评论") -+ @ApiOperation(value = "删除评论", notes = "仅评论作者本人可删除自己的评论,系统自动生成的活动记录不可删除") - @DeleteMapping("/comment/{commentId}") - public Result deleteComment(@ApiParam("评论ID") @PathVariable Long commentId, HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/config/Knife4jConfig.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/config/Knife4jConfig.java b/hl-user-service/src/main/java/com/hulalv/user/config/Knife4jConfig.java -index cf77842..eafa329 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/config/Knife4jConfig.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/config/Knife4jConfig.java -@@ -28,8 +28,7 @@ public class Knife4jConfig { - .select() - .apis(RequestHandlerSelectors.basePackage(BASE_PACKAGE)) - .paths(PathSelectors.ant("/user/**") -- .or(PathSelectors.ant("/dict/**")) -- .or(PathSelectors.ant("/internal/mp/**"))) -+ .or(PathSelectors.ant("/dict/**"))) - .build(); - } - -@@ -168,15 +167,6 @@ public class Knife4jConfig { - .build(); - } - -- @Bean -- public Docket internalApi() { -- return baseDocket("3. 内部接口(Feign)") -- .select() -- .apis(RequestHandlerSelectors.basePackage(BASE_PACKAGE)) -- .paths(PathSelectors.ant("/internal/**")) -- .build(); -- } -- - private Predicate pathsFor(String... basePaths) { - Predicate combined = s -> false; - for (String path : basePaths) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminAgreementController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminAgreementController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminAgreementController.java -index 10fe201..c012fce 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminAgreementController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminAgreementController.java -@@ -22,7 +22,9 @@ public class AdminAgreementController { - - private final AgreementService agreementService; - -- @ApiOperation("协议列表") -+ @ApiOperation(value = "协议列表", notes = "分页查询用户协议列表,支持按关键词和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):请求参数status和返回字段status(0=禁用, 1=启用)") - @GetMapping - public Result> listAgreements( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -32,20 +34,30 @@ public class AdminAgreementController { - return Result.success(agreementService.listAgreements(page, pageSize, keyword, status)); - } - -- @ApiOperation("协议详情") -+ @ApiOperation(value = "协议详情", -+ notes = "获取指定用户协议的详细信息,包括标题、内容(富文本)、版本号等。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- common_status(通用状态):返回字段status(0=禁用, 1=启用)") - @GetMapping("/{id}") - public Result getAgreement(@ApiParam("协议ID") @PathVariable Long id) { - return Result.success(agreementService.getAgreement(id)); - } - -- @ApiOperation("新增协议") -+ @ApiOperation(value = "新增协议", -+ notes = "创建新的用户协议,如用户服务协议、隐私政策等。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:协议类型(type)需唯一,同一类型不能重复创建。内容支持富文本。") - @OperationLog(value = "新增协议", module = "用户协议管理") - @PostMapping - public Result createAgreement(@Valid @RequestBody AgreementRequest request) { - return Result.success(agreementService.createAgreement(request)); - } - -- @ApiOperation("编辑协议") -+ @ApiOperation(value = "编辑协议", -+ notes = "更新指定用户协议的标题、内容、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:修改后小程序端会实时展示新内容。") - @OperationLog(value = "编辑协议", module = "用户协议管理") - @PutMapping("/{id}") - public Result updateAgreement(@ApiParam("协议ID") @PathVariable Long id, -@@ -53,7 +65,10 @@ public class AdminAgreementController { - return Result.success(agreementService.updateAgreement(id, request)); - } - -- @ApiOperation("删除协议") -+ @ApiOperation(value = "删除协议", -+ notes = "删除指定的用户协议记录(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序端将无法查看该协议。") - @OperationLog(value = "删除协议", module = "用户协议管理") - @DeleteMapping("/{id}") - public Result deleteAgreement(@ApiParam("协议ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminBannerController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminBannerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminBannerController.java -index 5c47fa0..eec06ab 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminBannerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminBannerController.java -@@ -23,7 +23,9 @@ public class AdminBannerController { - - private final BannerService bannerService; - -- @ApiOperation("Banner列表") -+ @ApiOperation(value = "Banner列表", notes = "分页查询Banner列表,支持按关键词和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):请求参数status和返回字段status(0=禁用, 1=启用)") - @GetMapping - public Result> listBanners( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -34,13 +36,20 @@ public class AdminBannerController { - return Result.success(result); - } - -- @ApiOperation("Banner详情") -+ @ApiOperation(value = "Banner详情", -+ notes = "获取指定Banner的详细信息,包括标题、图片、跳转链接、排序等。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- common_status(通用状态):返回字段status(0=禁用, 1=启用)") - @GetMapping("/{id}") - public Result getBanner(@ApiParam("轮播图ID") @PathVariable Long id) { - return Result.success(bannerService.getBanner(id)); - } - -- @ApiOperation("创建Banner") -+ @ApiOperation(value = "创建Banner", -+ notes = "创建新的首页轮播图,包括标题、封面图、跳转链接、排序等。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:创建后默认为启用状态,小程序端将按排序展示。") - @OperationLog(value = "创建Banner", module = "Banner管理") - @PostMapping - public Result createBanner(@ApiParam("轮播图创建请求") @Valid @RequestBody BannerRequest request, -@@ -49,7 +58,9 @@ public class AdminBannerController { - return Result.success(bannerService.createBanner(request, adminId)); - } - -- @ApiOperation("更新Banner") -+ @ApiOperation(value = "更新Banner", -+ notes = "更新指定Banner的标题、封面图、跳转链接、排序、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "更新Banner", module = "Banner管理") - @PutMapping("/{id}") - public Result updateBanner(@ApiParam("轮播图ID") @PathVariable Long id, -@@ -57,7 +68,10 @@ public class AdminBannerController { - return Result.success(bannerService.updateBanner(id, request)); - } - -- @ApiOperation("删除Banner") -+ @ApiOperation(value = "删除Banner", -+ notes = "删除指定的Banner记录(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序首页将不再展示该Banner。") - @OperationLog(value = "删除Banner", module = "Banner管理") - @DeleteMapping("/{id}") - public Result deleteBanner(@ApiParam("轮播图ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminContactController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminContactController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminContactController.java -index 6080439..786b6ad 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminContactController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminContactController.java -@@ -22,7 +22,10 @@ public class AdminContactController { - - private final ContactService contactService; - -- @ApiOperation("联系方式列表") -+ @ApiOperation(value = "联系方式列表", notes = "分页查询联系方式列表,支持按关键词和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- contact_channel_type(联系渠道类型):返回字段channelType(PHONE=电话, WECHAT=微信, EMAIL=邮箱等)\n" -+ + "- common_status(通用状态):请求参数status和返回字段status") - @GetMapping - public Result> listContacts( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -33,20 +36,27 @@ public class AdminContactController { - return Result.success(result); - } - -- @ApiOperation("联系方式详情") -+ @ApiOperation(value = "联系方式详情", notes = "获取指定联系方式的详细信息。" -+ + "\n\n**关联字典**:\n" -+ + "- contact_channel_type(联系渠道类型):返回字段channelType\n" -+ + "- common_status(通用状态):返回字段status") - @GetMapping("/{id}") - public Result getContact(@ApiParam("联系方式ID") @PathVariable Long id) { - return Result.success(contactService.getContact(id)); - } - -- @ApiOperation("创建联系方式") -+ @ApiOperation(value = "创建联系方式", notes = "新增一条联系方式记录。" -+ + "\n\n**关联字典**:\n" -+ + "- contact_channel_type(联系渠道类型):请求字段channelType") - @OperationLog(value = "创建联系方式", module = "联系我们管理") - @PostMapping - public Result createContact(@ApiParam("联系方式创建请求") @Valid @RequestBody ContactRequest request) { - return Result.success(contactService.createContact(request)); - } - -- @ApiOperation("更新联系方式") -+ @ApiOperation(value = "更新联系方式", notes = "更新指定联系方式记录。" -+ + "\n\n**关联字典**:\n" -+ + "- contact_channel_type(联系渠道类型):请求字段channelType") - @OperationLog(value = "更新联系方式", module = "联系我们管理") - @PutMapping("/{id}") - public Result updateContact(@ApiParam("联系方式ID") @PathVariable Long id, -@@ -54,7 +64,10 @@ public class AdminContactController { - return Result.success(contactService.updateContact(id, request)); - } - -- @ApiOperation("删除联系方式") -+ @ApiOperation(value = "删除联系方式", -+ notes = "删除指定的联系方式记录(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序端将不再展示该联系方式。") - @OperationLog(value = "删除联系方式", module = "联系我们管理") - @DeleteMapping("/{id}") - public Result deleteContact(@ApiParam("联系方式ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminCustomerController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminCustomerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminCustomerController.java -index 23ad20d..b5b5983 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminCustomerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminCustomerController.java -@@ -19,7 +19,14 @@ public class AdminCustomerController { - - private final UserService userService; - -- @ApiOperation("客户列表") -+ @ApiOperation(value = "客户列表", notes = "分页查询小程序注册的C端用户(客户)列表。" -+ + "支持按昵称/手机号/真实姓名关键词搜索,按状态筛选。" -+ + "status取值:ACTIVE=正常 BANNED=已封禁。" -+ + "需要管理员认证。" -+ + "\n\n**关联字典**:\n" -+ + "- user_status(用户状态):请求参数status和返回字段status(ACTIVE=正常, BANNED=已封禁)\n" -+ + "- gender(性别):返回字段gender(0=女, 1=男)\n" -+ + "- id_card_type(证件类型):返回字段idCardType") - @GetMapping - public Result> listCustomers( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -30,14 +37,21 @@ public class AdminCustomerController { - return Result.success(result); - } - -- @ApiOperation("客户详情") -+ @ApiOperation(value = "客户详情", notes = "获取指定客户的详细信息。" -+ + "\n\n**关联字典**:\n" -+ + "- user_status(用户状态):返回字段status\n" -+ + "- gender(性别):返回字段gender\n" -+ + "- id_card_type(证件类型):返回字段idCardType") - @GetMapping("/{userId}") - public Result getCustomer(@ApiParam("用户ID") @PathVariable Long userId) { - CustomerVO customer = userService.getCustomerDetail(userId); - return Result.success(customer); - } - -- @ApiOperation("封禁客户") -+ @ApiOperation(value = "封禁客户", notes = "封禁指定的C端用户,状态变为BANNED。" -+ + "封禁后该用户无法登录小程序,已有的Token将失效。" -+ + "封禁操作不会删除用户数据,可通过[解封客户]接口恢复。" -+ + "需要管理员认证。") - @OperationLog(value = "封禁客户", module = "客户管理") - @PostMapping("/{userId}/ban") - public Result banCustomer(@ApiParam("用户ID") @PathVariable Long userId) { -@@ -45,7 +59,9 @@ public class AdminCustomerController { - return Result.success(); - } - -- @ApiOperation("解封客户") -+ @ApiOperation(value = "解封客户", notes = "解封已封禁的C端用户,状态恢复为ACTIVE。" -+ + "解封后用户可正常登录小程序。" -+ + "需要管理员认证。") - @OperationLog(value = "解封客户", module = "客户管理") - @PostMapping("/{userId}/unban") - public Result unbanCustomer(@ApiParam("用户ID") @PathVariable Long userId) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminDesignerController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminDesignerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminDesignerController.java -index 5dfa05d..c76c659 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminDesignerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminDesignerController.java -@@ -30,14 +30,18 @@ public class AdminDesignerController { - private final DesignerProfileService designerProfileService; - private final DesignerDashboardService designerDashboardService; - -- @ApiOperation("获取我的个人资料(已废弃,请使用 /admin/profile/me)") -+ @ApiOperation(value = "获取我的个人资料(已废弃,请使用 /admin/profile/me)", notes = "已废弃接口。" -+ + "\n\n**关联字典**:\n" -+ + "- designer_cert_level(认证等级):返回字段certLevel(none/bronze/silver/gold/diamond)") - @GetMapping("/profile") - public Result getMyProfile(HttpServletRequest request) { - Long adminId = getAdminId(request); - return Result.success(designerProfileService.getMyProfile(adminId)); - } - -- @ApiOperation("更新我的个人资料(已废弃,请使用 PUT /admin/profile/me)") -+ @ApiOperation(value = "更新我的个人资料(已废弃,请使用 PUT /admin/profile/me)", -+ notes = "已废弃接口,请迁移至 PUT /admin/profile/me。\n\n" -+ + "**权限**:需要管理员登录。") - @PutMapping("/profile") - public Result updateMyProfile(HttpServletRequest request, - @Valid @RequestBody UpdateDesignerProfileRequest body) { -@@ -45,14 +49,18 @@ public class AdminDesignerController { - return Result.success(designerProfileService.updateMyProfile(adminId, body)); - } - -- @ApiOperation("工作台概览(已废弃,请使用 /admin/profile/dashboard)") -+ @ApiOperation(value = "工作台概览(已废弃,请使用 /admin/profile/dashboard)", -+ notes = "已废弃接口,请迁移至 GET /admin/profile/dashboard。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/dashboard") - public Result getDashboard(HttpServletRequest request) { - Long adminId = getAdminId(request); - return Result.success(designerDashboardService.getDashboard(adminId, "today")); - } - -- @ApiOperation("我的订单列表(已废弃,请使用 /admin/profile/orders)") -+ @ApiOperation(value = "我的订单列表(已废弃,请使用 /admin/profile/orders)", notes = "已废弃接口。" -+ + "\n\n**关联字典**:\n" -+ + "- order_status(订单状态):请求参数status和返回字段status") - @GetMapping("/orders") - public Result>> getMyOrders( - HttpServletRequest request, -@@ -64,7 +72,9 @@ public class AdminDesignerController { - return Result.success(designerDashboardService.getMyOrders(adminId, page, pageSize, status, keyword)); - } - -- @ApiOperation("我的产品列表(已废弃,请使用 /admin/profile/products)") -+ @ApiOperation(value = "我的产品列表(已废弃,请使用 /admin/profile/products)", notes = "已废弃接口。" -+ + "\n\n**关联字典**:\n" -+ + "- product_status(产品状态):请求参数status和返回字段status") - @GetMapping("/products") - public Result>> getMyProducts( - HttpServletRequest request, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminExploreCategoryController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminExploreCategoryController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminExploreCategoryController.java -index ebe2d88..f6fe95a 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminExploreCategoryController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminExploreCategoryController.java -@@ -24,7 +24,9 @@ public class AdminExploreCategoryController { - - private final ExploreCategoryService exploreCategoryService; - -- @ApiOperation("探索分类列表") -+ @ApiOperation(value = "探索分类列表", notes = "分页查询探索分类列表,支持按关键词和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):请求参数status和返回字段status(0=禁用, 1=启用)") - @GetMapping - public Result> listCategories( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -35,13 +37,20 @@ public class AdminExploreCategoryController { - return Result.success(result); - } - -- @ApiOperation("探索分类详情") -+ @ApiOperation(value = "探索分类详情", -+ notes = "获取指定探索分类的详细信息,包括标题、封面图、描述、关联的景区资源列表等。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- common_status(通用状态):返回字段status(0=禁用, 1=启用)") - @GetMapping("/{id}") - public Result getCategory(@ApiParam("分类ID") @PathVariable Long id) { - return Result.success(exploreCategoryService.getCategory(id)); - } - -- @ApiOperation("创建探索分类") -+ @ApiOperation(value = "创建探索分类", -+ notes = "创建新的探索分类,用于小程序探索页面的分类展示。\n" -+ + "可关联多个景区资源,设置封面图和描述文字。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "创建探索分类", module = "探索管理") - @PostMapping - public Result createCategory(@ApiParam("分类创建请求") @Valid @RequestBody ExploreCategoryRequest request, -@@ -51,7 +60,9 @@ public class AdminExploreCategoryController { - return Result.success(); - } - -- @ApiOperation("更新探索分类") -+ @ApiOperation(value = "更新探索分类", -+ notes = "更新指定探索分类的标题、封面图、描述、关联资源、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "更新探索分类", module = "探索管理") - @PutMapping("/{id}") - public Result updateCategory(@ApiParam("分类ID") @PathVariable Long id, -@@ -60,7 +71,10 @@ public class AdminExploreCategoryController { - return Result.success(); - } - -- @ApiOperation("删除探索分类") -+ @ApiOperation(value = "删除探索分类", -+ notes = "删除指定的探索分类(软删除),同时清除关联的资源绑定关系。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序探索页面将不再展示该分类。") - @OperationLog(value = "删除探索分类", module = "探索管理") - @DeleteMapping("/{id}") - public Result deleteCategory(@ApiParam("分类ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminFaqController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFaqController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFaqController.java -index 61a2dbb..11e1fdd 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFaqController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFaqController.java -@@ -26,20 +26,28 @@ public class AdminFaqController { - - // ==================== 分类 ==================== - -- @ApiOperation("分类列表") -+ @ApiOperation(value = "分类列表", -+ notes = "获取所有FAQ分类的完整列表(不分页)。\n" -+ + "每个分类包含名称、排序号、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/categories") - public Result> listCategories() { - return Result.success(faqService.listCategories()); - } - -- @ApiOperation("创建分类") -+ @ApiOperation(value = "创建分类", -+ notes = "创建新的FAQ分类,用于对常见问题进行归类。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:分类名称不能重复。") - @OperationLog(value = "创建FAQ分类", module = "常见问题管理") - @PostMapping("/categories") - public Result createCategory(@Valid @RequestBody FaqCategoryRequest request) { - return Result.success(faqService.createCategory(request)); - } - -- @ApiOperation("更新分类") -+ @ApiOperation(value = "更新分类", -+ notes = "更新指定FAQ分类的名称、排序号、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "更新FAQ分类", module = "常见问题管理") - @PutMapping("/categories/{id}") - public Result updateCategory(@ApiParam("分类ID") @PathVariable Long id, -@@ -47,7 +55,10 @@ public class AdminFaqController { - return Result.success(faqService.updateCategory(id, request)); - } - -- @ApiOperation("删除分类") -+ @ApiOperation(value = "删除分类", -+ notes = "删除指定的FAQ分类(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除分类不会删除其下的条目,但条目将变为无分类状态。") - @OperationLog(value = "删除FAQ分类", module = "常见问题管理") - @DeleteMapping("/categories/{id}") - public Result deleteCategory(@ApiParam("分类ID") @PathVariable Long id) { -@@ -57,21 +68,29 @@ public class AdminFaqController { - - // ==================== 条目 ==================== - -- @ApiOperation("条目列表") -+ @ApiOperation(value = "条目列表", -+ notes = "查询FAQ条目列表,支持按分类ID筛选。\n" -+ + "返回问题标题、回答内容(富文本)、排序号等。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/items") - public Result> listItems( - @ApiParam("分类ID(可选)") @RequestParam(required = false) Long categoryId) { - return Result.success(faqService.listItems(categoryId)); - } - -- @ApiOperation("创建条目") -+ @ApiOperation(value = "创建条目", -+ notes = "创建一条常见问题,包含问题标题和回答(支持富文本)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:需指定所属分类ID,排序号越小越靠前。") - @OperationLog(value = "创建FAQ条目", module = "常见问题管理") - @PostMapping("/items") - public Result createItem(@Valid @RequestBody FaqItemRequest request) { - return Result.success(faqService.createItem(request)); - } - -- @ApiOperation("更新条目") -+ @ApiOperation(value = "更新条目", -+ notes = "更新指定FAQ条目的问题标题、回答内容、排序号等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "更新FAQ条目", module = "常见问题管理") - @PutMapping("/items/{id}") - public Result updateItem(@ApiParam("条目ID") @PathVariable Long id, -@@ -79,7 +98,10 @@ public class AdminFaqController { - return Result.success(faqService.updateItem(id, request)); - } - -- @ApiOperation("删除条目") -+ @ApiOperation(value = "删除条目", -+ notes = "删除指定的FAQ条目(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序FAQ页面将不再展示该条目。") - @OperationLog(value = "删除FAQ条目", module = "常见问题管理") - @DeleteMapping("/items/{id}") - public Result deleteItem(@ApiParam("条目ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminFrontendConfigController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFrontendConfigController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFrontendConfigController.java -index e81218e..5f5117b 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFrontendConfigController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminFrontendConfigController.java -@@ -24,7 +24,9 @@ public class AdminFrontendConfigController { - - private final FrontendConfigService frontendConfigService; - -- @ApiOperation("配置列表") -+ @ApiOperation(value = "配置列表", notes = "分页查询前端配置列表,支持按关键词、分组和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):请求参数status和返回字段status(0=禁用, 1=启用)") - @GetMapping - public Result> listConfigs( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -35,7 +37,10 @@ public class AdminFrontendConfigController { - return Result.success(frontendConfigService.listConfigs(page, pageSize, keyword, configGroup, status)); - } - -- @ApiOperation("配置列表(不分页)") -+ @ApiOperation(value = "配置列表(不分页)", -+ notes = "获取所有前端配置项的完整列表(不分页),支持按分组和状态筛选。\n" -+ + "适用于需要一次性加载全部配置的场景。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/all") - public Result> listAllConfigs( - @ApiParam("配置分组") @RequestParam(required = false) String configGroup, -@@ -43,25 +48,37 @@ public class AdminFrontendConfigController { - return Result.success(frontendConfigService.listAllConfigs(configGroup, status)); - } - -- @ApiOperation("配置详情") -+ @ApiOperation(value = "配置详情", -+ notes = "根据配置ID获取指定前端配置项的详细信息,包括key、value、分组、描述等。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/{id}") - public Result getConfig(@ApiParam("配置ID") @PathVariable Long id) { - return Result.success(frontendConfigService.getConfig(id)); - } - -- @ApiOperation("按key查询配置") -+ @ApiOperation(value = "按key查询配置", -+ notes = "根据配置键(configKey)获取指定的前端配置项。\n" -+ + "configKey为全局唯一标识,如 app_name、primary_color 等。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/by-key/{key}") - public Result getConfigByKey(@ApiParam("配置键") @PathVariable String key) { - return Result.success(frontendConfigService.getConfigByKey(key)); - } - -- @ApiOperation("获取所有分组") -+ @ApiOperation(value = "获取所有分组", -+ notes = "获取前端配置中所有已使用的分组名称列表。\n" -+ + "用于配置管理页面的分组筛选下拉框。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/groups") - public Result> listGroups() { - return Result.success(frontendConfigService.listGroups()); - } - -- @ApiOperation("创建配置") -+ @ApiOperation(value = "创建配置", -+ notes = "创建新的前端配置项,用于控制前端页面的展示和行为。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:configKey 必须全局唯一,不能与已有配置重复。" -+ + "可通过 sensitive 字段标记是否为敏感配置(敏感配置不会通过公开接口暴露给小程序)。") - @OperationLog(value = "创建前端配置", module = "前端配置管理") - @PostMapping - public Result createConfig( -@@ -71,7 +88,10 @@ public class AdminFrontendConfigController { - return Result.success(frontendConfigService.createConfig(request, adminId)); - } - -- @ApiOperation("更新配置") -+ @ApiOperation(value = "更新配置", -+ notes = "更新指定前端配置项的值、分组、描述、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:修改后前端会实时使用新值(如有缓存需等待刷新)。") - @OperationLog(value = "更新前端配置", module = "前端配置管理") - @PutMapping("/{id}") - public Result updateConfig( -@@ -80,7 +100,10 @@ public class AdminFrontendConfigController { - return Result.success(frontendConfigService.updateConfig(id, request)); - } - -- @ApiOperation("删除配置") -+ @ApiOperation(value = "删除配置", -+ notes = "删除指定的前端配置项(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后前端将无法获取该配置,可能影响页面展示,请确认无引用后再删除。") - @OperationLog(value = "删除前端配置", module = "前端配置管理") - @DeleteMapping("/{id}") - public Result deleteConfig(@ApiParam("配置ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminProfileController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminProfileController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminProfileController.java -index e174243..6558bc2 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminProfileController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminProfileController.java -@@ -29,7 +29,12 @@ public class AdminProfileController { - private final FinanceDashboardService financeDashboardService; - private final MaterialDashboardService materialDashboardService; - -- @ApiOperation("获取我的个人资料") -+ @ApiOperation(value = "获取我的个人资料", -+ notes = "获取当前登录管理员的个人资料,根据角色返回不同的资料内容。\n" -+ + "定制师角色会返回认证等级、个人简介、擅长领域等附加信息。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- designer_cert_level(认证等级):返回字段certLevel(none/bronze/silver/gold/diamond)") - @GetMapping("/me") - public Result getMyProfile(HttpServletRequest request) { - Long adminId = getAdminId(request); -@@ -37,7 +42,10 @@ public class AdminProfileController { - return Result.success(profileService.getProfile(adminId, role)); - } - -- @ApiOperation("更新我的个人资料") -+ @ApiOperation(value = "更新我的个人资料", -+ notes = "更新当前登录管理员的个人资料,支持修改昵称、头像、个人简介等。\n" -+ + "定制师角色可额外更新擅长领域、服务区域等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @PutMapping("/me") - public Result updateMyProfile(HttpServletRequest request, - @Valid @RequestBody UpdateDesignerProfileRequest body) { -@@ -46,9 +54,19 @@ public class AdminProfileController { - return Result.success(profileService.updateProfile(adminId, role, body)); - } - -- @ApiOperation("工作台仪表盘(角色分发,支持时间范围)") -+ @ApiOperation(value = "工作台仪表盘(角色分发,支持时间范围)", notes = "根据当前管理员角色返回不同的仪表盘数据。" -+ + "CUSTOMIZER(定制师):待处理订单数、产品数、评价统计等。" -+ + "SUPER_ADMIN/ADMIN:全局概览(订单、收入、用户增长等)。" -+ + "ROOM_MANAGER(客房管理):房间分配概览。" -+ + "VEHICLE_MANAGER(车辆管理):车辆调度概览。" -+ + "FINANCE(财务):收支统计。" -+ + "MATERIAL_ADMIN(素材管理):素材库概览。" -+ + "period取值:today=今日 week=本周 month=本月。" -+ + "需要管理员认证。" -+ + "\n\n**关联字典**:\n" -+ + "- order_status(订单状态):仪表盘中订单统计按状态分组展示") - @GetMapping("/dashboard") -- public Result getDashboard( -+ public Result getDashboard( - HttpServletRequest request, - @ApiParam("时间范围: today/week/month") @RequestParam(defaultValue = "today") String period) { - Long adminId = getAdminId(request); -@@ -72,7 +90,9 @@ public class AdminProfileController { - } - } - -- @ApiOperation("我的评价列表") -+ @ApiOperation(value = "我的评价列表", notes = "查询当前定制师收到的评价列表,支持按评价等级筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- rating_level(评价等级):GOOD=好评, MEDIUM=中评, BAD=差评(筛选条件+列表展示)\n") - @GetMapping("/reviews") - public Result>> getReviews( - HttpServletRequest request, -@@ -83,7 +103,9 @@ public class AdminProfileController { - return Result.success(designerDashboardService.getMyReviews(adminId, page, pageSize, ratingLevel)); - } - -- @ApiOperation("订单列表") -+ @ApiOperation(value = "订单列表", notes = "查询当前定制师的订单列表,支持按状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- order_status(订单状态):请求参数status和返回字段status") - @GetMapping("/orders") - public Result>> getOrders( - HttpServletRequest request, -@@ -95,7 +117,9 @@ public class AdminProfileController { - return Result.success(designerDashboardService.getMyOrders(adminId, page, pageSize, status, keyword)); - } - -- @ApiOperation("产品列表") -+ @ApiOperation(value = "产品列表", notes = "查询当前定制师的产品列表,支持按状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- product_status(产品状态):请求参数status和返回字段status") - @GetMapping("/products") - public Result>> getProducts( - HttpServletRequest request, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminTopicController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminTopicController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminTopicController.java -index 7d2e9bc..e6766e3 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminTopicController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminTopicController.java -@@ -23,7 +23,9 @@ public class AdminTopicController { - - private final TopicService topicService; - -- @ApiOperation("专题列表") -+ @ApiOperation(value = "专题列表", notes = "分页查询探索专题列表,支持按关键词和状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):请求参数status和返回字段status(0=禁用, 1=启用)") - @GetMapping - public Result> listTopics( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -34,13 +36,20 @@ public class AdminTopicController { - return Result.success(result); - } - -- @ApiOperation("专题详情") -+ @ApiOperation(value = "专题详情", -+ notes = "获取指定探索专题的详细信息,包括标题、封面图、描述、关联资源等。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- common_status(通用状态):返回字段status(0=禁用, 1=启用)") - @GetMapping("/{id}") - public Result getTopic(@ApiParam("专题ID") @PathVariable Long id) { - return Result.success(topicService.getTopic(id)); - } - -- @ApiOperation("创建专题") -+ @ApiOperation(value = "创建专题", -+ notes = "创建新的探索专题,用于小程序探索页面展示主题推荐内容。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:创建时需设置标题、封面图等基本信息。") - @OperationLog(value = "创建专题", module = "探索专题管理") - @PostMapping - public Result createTopic(@ApiParam("专题创建请求") @Valid @RequestBody TopicRequest request, -@@ -49,7 +58,9 @@ public class AdminTopicController { - return Result.success(topicService.createTopic(request, adminId)); - } - -- @ApiOperation("更新专题") -+ @ApiOperation(value = "更新专题", -+ notes = "更新指定探索专题的标题、封面图、描述、状态等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @OperationLog(value = "更新专题", module = "探索专题管理") - @PutMapping("/{id}") - public Result updateTopic(@ApiParam("专题ID") @PathVariable Long id, -@@ -57,7 +68,10 @@ public class AdminTopicController { - return Result.success(topicService.updateTopic(id, request)); - } - -- @ApiOperation("删除专题") -+ @ApiOperation(value = "删除专题", -+ notes = "删除指定的探索专题(软删除)。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:删除后小程序探索页面将不再展示该专题。") - @OperationLog(value = "删除专题", module = "探索专题管理") - @DeleteMapping("/{id}") - public Result deleteTopic(@ApiParam("专题ID") @PathVariable Long id) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AdminUserController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminUserController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminUserController.java -index 2b3f74a..0344258 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AdminUserController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AdminUserController.java -@@ -26,7 +26,12 @@ public class AdminUserController { - - private final AdminUserService adminUserService; - -- @ApiOperation("创建管理员") -+ @ApiOperation(value = "创建管理员", notes = "创建新的后台管理员账号。" -+ + "默认密码为Admin@123456,管理员首次登录后建议修改密码。" -+ + "可通过roleIds分配多个角色,也兼容旧的单角色roleId参数。" -+ + "需要SUPER_ADMIN或ADMIN角色。" -+ + "\n\n**关联字典**:\n" -+ + "- admin_status(管理员状态):ACTIVE=启用, LOCKED=锁定, DISABLED=禁用\n") - @OperationLog(value = "创建管理员", module = "管理员管理") - @PostMapping - public Result createAdmin(@ApiParam("创建管理员请求") @Valid @RequestBody CreateAdminRequest request) { -@@ -34,7 +39,9 @@ public class AdminUserController { - return Result.success(admin); - } - -- @ApiOperation("更新管理员") -+ @ApiOperation(value = "更新管理员", notes = "更新管理员信息,包括用户名、状态、角色分配等。" -+ + "\n\n**关联字典**:\n" -+ + "- admin_status(管理员状态):ACTIVE=启用, LOCKED=锁定, DISABLED=禁用\n") - @OperationLog(value = "更新管理员", module = "管理员管理") - @PutMapping("/{adminId}") - public Result updateAdmin(@ApiParam("管理员ID") @PathVariable Long adminId, -@@ -43,7 +50,10 @@ public class AdminUserController { - return Result.success(admin); - } - -- @ApiOperation("删除管理员") -+ @ApiOperation(value = "删除管理员", notes = "删除指定管理员账号(软删除)。" -+ + "不能删除自己的账号,不能删除SUPER_ADMIN角色的账号(除非操作者也是SUPER_ADMIN)。" -+ + "删除后该管理员的登录状态自动失效。" -+ + "需要SUPER_ADMIN或ADMIN角色。") - @OperationLog(value = "删除管理员", module = "管理员管理") - @DeleteMapping("/{adminId}") - public Result deleteAdmin(@ApiParam("管理员ID") @PathVariable Long adminId, -@@ -54,7 +64,9 @@ public class AdminUserController { - return Result.success(); - } - -- @ApiOperation("解锁管理员") -+ @ApiOperation(value = "解锁管理员", notes = "解锁因登录失败次数过多而被锁定的管理员账号。" -+ + "管理员连续5次登录失败后账号自动锁定30分钟,此接口可立即解锁。" -+ + "需要SUPER_ADMIN或ADMIN角色。") - @OperationLog(value = "解锁管理员", module = "管理员管理") - @PostMapping("/{adminId}/unlock") - public Result unlockAdmin(@ApiParam("管理员ID") @PathVariable Long adminId, -@@ -65,7 +77,10 @@ public class AdminUserController { - return Result.success(); - } - -- @ApiOperation("重置密码") -+ @ApiOperation(value = "重置密码", notes = "将指定管理员的密码重置为默认密码(Admin@123456)。" -+ + "用于管理员忘记密码时由上级管理员操作重置。" -+ + "重置后管理员可用默认密码登录,建议立即修改。" -+ + "需要SUPER_ADMIN或ADMIN角色。") - @OperationLog(value = "重置密码", module = "管理员管理") - @PostMapping("/{adminId}/reset-password") - public Result resetPassword(@ApiParam("管理员ID") @PathVariable Long adminId, -@@ -76,7 +91,10 @@ public class AdminUserController { - return Result.success(); - } - -- @ApiOperation("修改企业微信绑定(支持换绑)") -+ @ApiOperation(value = "修改企业微信绑定(支持换绑)", notes = "为管理员绑定或更换企业微信账号。" -+ + "绑定后管理员可通过企业微信扫码登录,并可接收审批通知。" -+ + "如果目标企微ID已被其他管理员绑定,需设置forceRebind=true强制换绑。" -+ + "需要管理员认证。") - @OperationLog(value = "修改企业微信绑定", module = "管理员管理") - @PutMapping("/{adminId}/wechat-binding") - public Result> updateWechatBinding( -@@ -92,14 +110,21 @@ public class AdminUserController { - return Result.success(result); - } - -- @ApiOperation("获取管理员详情") -+ @ApiOperation(value = "获取管理员详情", notes = "获取指定管理员的完整信息。" -+ + "\n\n**关联字典**:\n" -+ + "- admin_status(管理员状态):ACTIVE=启用, LOCKED=锁定, DISABLED=禁用\n") - @GetMapping("/{adminId}") - public Result getAdmin(@ApiParam("管理员ID") @PathVariable Long adminId) { - AdminUser admin = adminUserService.getAdminById(adminId); - return Result.success(admin); - } - -- @ApiOperation("管理员列表") -+ @ApiOperation(value = "管理员列表", notes = "分页查询管理员列表,支持按角色、状态、企微绑定状态筛选。" -+ + "status取值:ACTIVE=正常 LOCKED=已锁定 DISABLED=已禁用。" -+ + "wechatBound:true=已绑定企业微信 false=未绑定。" -+ + "需要管理员认证。" -+ + "\n\n**关联字典**:\n" -+ + "- admin_status(管理员状态):ACTIVE=启用, LOCKED=锁定, DISABLED=禁用(筛选条件+列表展示)\n") - @GetMapping - public Result> listAdmins( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/AuthController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/AuthController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/AuthController.java -index bf6beb1..84bf6c9 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/AuthController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/AuthController.java -@@ -30,7 +30,10 @@ public class AuthController { - @Value("${auth.2fa-confirm-enabled:false}") - private boolean twoFaConfirmEnabled; - -- @ApiOperation("管理员登录") -+ @ApiOperation(value = "管理员登录", notes = "管理员通过用户名+密码登录后台管理系统。" -+ + "首次在新设备登录时需要进行企业微信扫码二次验证(2FA),返回needTwoFa=true。" -+ + "登录失败5次后账号将被锁定30分钟。" -+ + "无需认证即可调用。") - @PostMapping("/login") - public Result login(@ApiParam("管理员登录请求") @Valid @RequestBody AdminLoginRequest request, - HttpServletRequest httpRequest) { -@@ -41,7 +44,10 @@ public class AuthController { - return Result.success(response); - } - -- @ApiOperation("2FA验证") -+ @ApiOperation(value = "2FA验证", notes = "新设备登录时的企业微信二次验证。" -+ + "管理员登录返回needTwoFa=true后,前端调用此接口提交验证码完成登录。" -+ + "验证通过后设备将被标记为可信设备,后续登录不再需要2FA。" -+ + "无需认证即可调用。") - @PostMapping("/wechat/verify-2fa") - public Result verifyTwoFa(@ApiParam("管理员ID") @RequestParam Long adminId, - @ApiParam("2FA验证请求") @Valid @RequestBody TwoFaVerifyRequest request, -@@ -53,7 +59,10 @@ public class AuthController { - return Result.success(response); - } - -- @ApiOperation("修改密码") -+ @ApiOperation(value = "修改密码", notes = "管理员修改自己的登录密码。" -+ + "需验证旧密码正确后才能设置新密码,新密码须满足复杂度要求(8-128位,含大小写字母和数字)。" -+ + "修改成功后当前Token仍然有效,无需重新登录。" -+ + "需要管理员认证(Token中的adminId)。") - @OperationLog(value = "修改密码", module = "认证管理") - @PutMapping("/password") - public Result changePassword(HttpServletRequest request, -@@ -63,7 +72,9 @@ public class AuthController { - return Result.success(); - } - -- @ApiOperation("管理员登出") -+ @ApiOperation(value = "管理员登出", notes = "清除管理员的登录状态并使当前Token失效。" -+ + "前端应在登出后清除本地存储的Token和用户信息。" -+ + "需要管理员认证。") - @PostMapping("/logout") - public Result logout(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -@@ -71,14 +82,20 @@ public class AuthController { - return Result.success(); - } - -- @ApiOperation("生成2FA扫码会话") -+ @ApiOperation(value = "生成2FA扫码会话", notes = "生成企业微信扫码二维码的会话信息,用于新设备二次验证。" -+ + "返回包含qrcodeUrl(二维码链接)和state(会话标识)。" -+ + "前端展示二维码后通过轮询 /2fa/check 接口检查扫码状态。" -+ + "无需认证即可调用(登录流程中使用)。") - @GetMapping("/2fa/qrcode") - public Result> generate2FaQrcode(@ApiParam("管理员ID") @RequestParam Long adminId) { - Map data = adminAuthService.generate2FaQrSession(adminId); - return Result.success(data); - } - -- @ApiOperation("2FA企微扫码回调") -+ @ApiOperation(value = "2FA企微扫码回调", notes = "企业微信OAuth回调地址,用户扫码授权后微信服务器回调此接口。" -+ + "此接口由微信服务器调用,非前端直接调用。" -+ + "回调成功后将state对应的会话标记为已扫码,前端轮询 /2fa/check 即可获取结果。" -+ + "返回HTML页面(成功/失败提示),不返回JSON。") - @GetMapping(value = "/2fa/callback", produces = MediaType.TEXT_HTML_VALUE) - @ResponseBody - public String handle2FaCallback(@ApiParam("授权码") @RequestParam String code, @ApiParam("会话状态") @RequestParam String state) { -@@ -120,14 +137,19 @@ public class AuthController { - - // ==================== WeChat QR Direct Login ==================== - -- @ApiOperation("生成企业微信扫码登录会话") -+ @ApiOperation(value = "生成企业微信扫码登录会话", notes = "生成企业微信扫码直接登录的会话信息(非2FA验证,而是扫码替代密码登录)。" -+ + "返回包含qrcodeUrl和state。前端展示二维码后通过轮询 /wechat-qr/status 检查登录状态。" -+ + "无需认证即可调用。") - @GetMapping("/wechat-qr") - public Result> generateWechatLoginQr() { - Map data = adminAuthService.generateWechatLoginQrSession(); - return Result.success(data); - } - -- @ApiOperation("企业微信扫码登录回调") -+ @ApiOperation(value = "企业微信扫码登录回调", notes = "企业微信OAuth回调地址,扫码登录授权后微信服务器回调此接口。" -+ + "此接口由微信服务器调用,非前端直接调用。" -+ + "回调后标记会话为已扫码,前端通过轮询 /wechat-qr/status 获取登录结果。" -+ + "返回HTML页面,不返回JSON。") - @GetMapping(value = "/wechat-qr/callback", produces = MediaType.TEXT_HTML_VALUE) - @ResponseBody - public String handleWechatLoginCallback(@ApiParam("授权码") @RequestParam String code, @ApiParam("会话状态") @RequestParam String state) { -@@ -167,7 +189,10 @@ public class AuthController { - } - } - -- @ApiOperation("查询企业微信扫码登录状态") -+ @ApiOperation(value = "查询企业微信扫码登录状态", notes = "前端轮询此接口检查扫码登录是否完成。" -+ + "返回status字段:PENDING=等待扫码,SCANNED=已扫码登录成功(附带token和用户信息)。" -+ + "建议轮询间隔2秒,超过5分钟未扫码会话自动失效。" -+ + "无需认证即可调用。") - @GetMapping("/wechat-qr/status") - public Result> checkWechatLoginStatus(@ApiParam("会话状态") @RequestParam String state, - HttpServletRequest httpRequest) { -@@ -178,7 +203,11 @@ public class AuthController { - return Result.success(data); - } - -- @ApiOperation("手动确认扫码(内网穿透环境workaround,默认关闭)") -+ @ApiOperation(value = "手动确认扫码(内网穿透环境workaround,默认关闭)", -+ notes = "在内网穿透环境下,企微回调可能无法正常到达,此接口作为手动替代方案。\n" -+ + "需在Nacos配置中开启 auth.2fa-confirm-enabled=true 才可使用。\n\n" -+ + "**权限**:无需认证(登录流程中使用)。\n" -+ + "**注意**:生产环境应保持关闭,仅限开发/测试时使用。") - @PostMapping("/2fa/confirm") - public Result confirm2FaScan(@ApiParam("会话状态") @RequestParam String state, - @ApiParam("管理员ID") @RequestParam String adminId, -@@ -195,7 +224,10 @@ public class AuthController { - return Result.success(); - } - -- @ApiOperation("查询2FA扫码状态") -+ @ApiOperation(value = "查询2FA扫码状态", notes = "前端轮询此接口检查2FA扫码验证是否完成。" -+ + "返回status字段:PENDING=等待扫码,SCANNED=已完成验证(附带token和用户信息)。" -+ + "建议轮询间隔2秒,超过5分钟未扫码会话自动失效。" -+ + "无需认证即可调用(登录流程中使用)。") - @GetMapping("/2fa/check") - public Result> check2FaStatus(@ApiParam("会话状态") @RequestParam String state, - HttpServletRequest httpRequest) { -@@ -206,7 +238,10 @@ public class AuthController { - return Result.success(data); - } - -- @ApiOperation("切换当前角色") -+ @ApiOperation(value = "切换当前角色", notes = "多角色管理员切换当前活跃角色。" -+ + "切换后返回新的Token和角色对应的菜单权限,前端需更新本地Token并刷新菜单。" -+ + "只能切换到该管理员已分配的角色,否则报错。" -+ + "需要管理员认证。") - @OperationLog(value = "切换角色", module = "认证管理") - @PostMapping("/switch-role") - public Result switchRole(HttpServletRequest request, -@@ -216,7 +251,10 @@ public class AuthController { - return Result.success(response); - } - -- @ApiOperation("更新头像") -+ @ApiOperation(value = "更新头像", notes = "管理员更新自己的头像。" -+ + "需先通过文件服务上传图片获取OSS URL和fileId,再调用此接口绑定。" -+ + "旧头像的文件引用会自动解绑。" -+ + "需要管理员认证。") - @OperationLog(value = "更新头像", module = "认证管理") - @PutMapping("/avatar") - public Result updateAvatar(HttpServletRequest request, -@@ -226,7 +264,9 @@ public class AuthController { - return Result.success(); - } - -- @ApiOperation("获取当前管理员信息") -+ @ApiOperation(value = "获取当前管理员信息", notes = "获取当前登录管理员的完整信息,包括用户名、头像、角色列表、当前角色、菜单权限等。" -+ + "前端页面初始化时调用此接口获取用户信息和权限数据。" -+ + "需要管理员认证。") - @GetMapping("/info") - public Result getAdminInfo(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/FavoriteController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/FavoriteController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/FavoriteController.java -index 0b374f0..79a06b4 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/FavoriteController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/FavoriteController.java -@@ -22,7 +22,12 @@ public class FavoriteController { - - private final FavoriteService favoriteService; - -- @ApiOperation("添加收藏") -+ @ApiOperation(value = "添加收藏", notes = "将指定资源添加到当前用户的收藏列表。" -+ + "同一用户对同一资源不可重复收藏,重复收藏会报错。" -+ + "targetType取值:SCENIC_SPOT/ACTIVITY/HOTEL/PRODUCT/EXPLORE等。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品, EXPLORE=探索(请求参数targetType)\n") - @PostMapping - public Result addFavorite(HttpServletRequest request, - @ApiParam("收藏请求") @Valid @RequestBody FavoriteRequest favoriteRequest) { -@@ -31,7 +36,11 @@ public class FavoriteController { - return Result.success(favorite); - } - -- @ApiOperation("收藏列表") -+ @ApiOperation(value = "收藏列表", notes = "分页查询当前用户的所有收藏记录,按收藏时间倒序排列。" -+ + "返回收藏记录的基础信息(不包含资源详情),需前端根据targetType和targetId再查详情。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):返回字段targetType,前端据此判断跳转到哪种资源详情页\n") - @GetMapping - public Result> listFavorites(HttpServletRequest request, - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -41,7 +50,9 @@ public class FavoriteController { - return Result.success(result); - } - -- @ApiOperation("删除收藏") -+ @ApiOperation(value = "删除收藏", notes = "根据收藏记录ID取消收藏。" -+ + "只能删除自己的收藏记录,删除他人的收藏会报权限错误。" -+ + "需要小程序用户认证。") - @DeleteMapping("/{favoriteId}") - public Result deleteFavorite(HttpServletRequest request, - @ApiParam("收藏ID") @PathVariable Long favoriteId) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/FootprintController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/FootprintController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/FootprintController.java -index 2616fdc..a24102e 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/FootprintController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/FootprintController.java -@@ -22,7 +22,13 @@ public class FootprintController { - - private final FootprintService footprintService; - -- @ApiOperation("添加足迹") -+ @ApiOperation(value = "添加足迹", notes = "记录用户浏览资源的足迹。" -+ + "同一用户对同一资源多次浏览只保留最新一条记录(更新时间)。" -+ + "resourceType取值:SCENIC_SPOT/ACTIVITY/HOTEL/PRODUCT等。" -+ + "通常由前端在进入资源详情页时自动调用。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- footprint_resource_type(足迹资源类型):SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品(请求参数resourceType)\n") - @PostMapping - public Result addFootprint(HttpServletRequest request, - @ApiParam("足迹请求") @Valid @RequestBody FootprintRequest footprintRequest) { -@@ -31,7 +37,10 @@ public class FootprintController { - return Result.success(footprint); - } - -- @ApiOperation("足迹列表") -+ @ApiOperation(value = "足迹列表", notes = "分页查询当前用户的浏览足迹,按浏览时间倒序排列。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- footprint_resource_type(足迹资源类型):返回字段resourceType,前端据此判断跳转到哪种资源详情页\n") - @GetMapping - public Result> listFootprints(HttpServletRequest request, - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -41,7 +50,9 @@ public class FootprintController { - return Result.success(result); - } - -- @ApiOperation("删除足迹") -+ @ApiOperation(value = "删除足迹", notes = "根据足迹记录ID删除单条浏览足迹。" -+ + "只能删除自己的足迹记录。" -+ + "需要小程序用户认证。") - @DeleteMapping("/{footprintId}") - public Result deleteFootprint(HttpServletRequest request, - @ApiParam("足迹ID") @PathVariable Long footprintId) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalApprovalController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalApprovalController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalApprovalController.java -index 37a5069..bdd7f6d 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalApprovalController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalApprovalController.java -@@ -22,7 +22,7 @@ import java.util.*; - * Called by other services via Feign (not exposed via gateway). - */ - @Slf4j --@Api(tags = "【内部接口】审批(Feign调用)") -+@Api(tags = "【内部接口】审批(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/wechat") - @RequiredArgsConstructor -@@ -129,7 +129,11 @@ public class InternalApprovalController { - @Value("${approval.product.control-ids.reason:}") - private String controlIdProductReason; - -- @ApiOperation("Submit approval to enterprise WeChat OA") -+ @ApiOperation(value = "提交企业微信OA审批", notes = "内部接口,由其他服务通过Feign调用提交企微审批申请。" -+ + "根据templateId自动路由到对应的审批模板(资源上下架/产品上下架/退款申请/退款申诉)。" -+ + "需提供adminId(管理员提交)或wechatUserId(代理提交)。" -+ + "返回企微审批单号spNo,用于后续查询审批状态。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/submit-approval") - public Result submitApproval(@RequestBody ApprovalSubmitDTO dto) { - if (dto.getTemplateId() == null || dto.getTemplateId().isEmpty()) { -@@ -183,7 +187,10 @@ public class InternalApprovalController { - return Result.success(result); - } - -- @ApiOperation("Revoke a pending approval in enterprise WeChat OA") -+ @ApiOperation(value = "撤销企业微信OA审批", notes = "内部接口,撤销一个待审批的企微OA审批申请。" -+ + "仅PENDING状态的审批可以撤销,已审批的无法撤销。" -+ + "撤销失败不会抛异常(降级处理),业务侧需自行处理状态。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/revoke-approval/{spNo}") - public Result revokeApproval(@PathVariable String spNo) { - if (spNo == null || spNo.isEmpty()) { -@@ -200,7 +207,12 @@ public class InternalApprovalController { - return Result.success(); - } - -- @ApiOperation("Get approval status from enterprise WeChat OA") -+ @ApiOperation(value = "查询企业微信OA审批状态", notes = "内部接口,根据审批单号查询企微审批的详细状态。" -+ + "返回审批状态(spStatus:1=审批中 2=已通过 3=已驳回 4=已撤销)、申请人、表单数据等。" -+ + "用于审批轮询兜底方案(ApprovalPollingService)。" -+ + "不经过Gateway,仅服务间调用。" -+ + "\n\n**关联字典**:\n" -+ + "- approval_sp_status(审批状态):返回字段spStatus(1=审批中, 2=已通过, 3=已驳回, 4=已撤销)") - @GetMapping("/approval-status/{spNo}") - @SuppressWarnings("unchecked") - public Result> getApprovalStatus(@PathVariable String spNo) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalBadgeController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBadgeController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBadgeController.java -index c2204f9..df482d7 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBadgeController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBadgeController.java -@@ -13,7 +13,7 @@ import java.util.Map; - * 徽章内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/badge") - @RequiredArgsConstructor -@@ -21,7 +21,10 @@ public class InternalBadgeController { - - private final BadgeService badgeService; - -- @ApiOperation("获取用户徽章数据") -+ @ApiOperation(value = "获取用户徽章数据", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取指定用户的各类未读数和待处理徽章数据(如未读消息数、待付款订单数等)。\n" -+ + "用于小程序个人中心页面的红点/数字徽章展示。") - @GetMapping - public Result> getUserBadgeData(@RequestParam Long userId) { - return Result.success(badgeService.getUserBadgeData(userId)); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalBannerController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBannerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBannerController.java -index 4df5705..b339c1f 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBannerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalBannerController.java -@@ -16,7 +16,7 @@ import java.util.List; - * Banner内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/banner") - @RequiredArgsConstructor -@@ -24,7 +24,9 @@ public class InternalBannerController { - - private final BannerService bannerService; - -- @ApiOperation("获取当前有效Banner列表") -+ @ApiOperation(value = "获取当前有效Banner列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取所有状态为启用的Banner列表,按排序号排列,用于小程序首页轮播展示。") - @GetMapping("/active") - public Result> listActiveBanners() { - return Result.success(bannerService.listActiveBanners()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalContactController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalContactController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalContactController.java -index d38d4a3..dc412e7 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalContactController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalContactController.java -@@ -16,7 +16,7 @@ import java.util.List; - * 联系我们内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/contact") - @RequiredArgsConstructor -@@ -24,7 +24,10 @@ public class InternalContactController { - - private final ContactService contactService; - -- @ApiOperation("获取当前有效联系方式列表") -+ @ApiOperation(value = "获取当前有效联系方式列表", notes = "内部接口,获取所有状态为上线的联系方式。" -+ + "不经过Gateway,仅服务间调用。" -+ + "\n\n**关联字典**:\n" -+ + "- contact_channel_type(联系渠道类型):返回字段channelType(ABOUT=关于我们, ONLINE_CS=在线客服, PHONE=电话咨询)\n") - @GetMapping("/active") - public Result> listActiveContacts() { - return Result.success(contactService.listActiveContacts()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalDesignerController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalDesignerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalDesignerController.java -index 969a9d2..f96ec05 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalDesignerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalDesignerController.java -@@ -14,7 +14,7 @@ import java.util.List; - * C端定制师内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/designer") - @RequiredArgsConstructor -@@ -22,20 +22,28 @@ public class InternalDesignerController { - - private final DesignerService designerService; - -- @ApiOperation("定制师列表") -+ @ApiOperation(value = "定制师列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "分页获取已上线的定制师列表,用于小程序定制师展示页面。\n" -+ + "返回定制师头像、昵称、认证等级、擅长领域等信息。") - @GetMapping - public Result> listDesigners(@RequestParam(defaultValue = "1") int page, - @RequestParam(defaultValue = "10") int limit) { - return Result.success(designerService.listDesigners(page, limit)); - } - -- @ApiOperation("推荐定制师") -+ @ApiOperation(value = "推荐定制师", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取一位推荐定制师,用于小程序首页推荐位展示。\n" -+ + "推荐逻辑由后端按权重排序选取。") - @GetMapping("/featured") - public Result getFeaturedDesigner() { - return Result.success(designerService.getFeaturedDesigner()); - } - -- @ApiOperation("定制师详情") -+ @ApiOperation(value = "定制师详情", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取指定定制师的详细信息,包括个人简介、擅长领域、服务案例等。") - @GetMapping("/{id}") - public Result getDesignerDetail(@PathVariable Long id) { - return Result.success(designerService.getDesignerDetail(id)); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalExploreCategoryController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalExploreCategoryController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalExploreCategoryController.java -index 1e7bf8d..02ea651 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalExploreCategoryController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalExploreCategoryController.java -@@ -26,7 +26,7 @@ import java.util.stream.Collectors; - * 探索分类内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "探索分类小程序接口") -+@Api(tags = "探索分类小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/explore") - @RequiredArgsConstructor -@@ -38,7 +38,10 @@ public class InternalExploreCategoryController { - private final FavoriteService favoriteService; - private final UserLikeService userLikeService; - -- @ApiOperation("获取上线探索分类列表") -+ @ApiOperation(value = "获取上线探索分类列表", notes = "内部接口,获取已上线的探索分类列表,支持排序。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):仅返回status=1(启用)的分类\n" -+ + "- explore_sort_type(排序方式):请求参数sortType(comprehensive=综合, newest=最新, hottest=最热)") - @GetMapping("/active") - public Result> listActive( - @ApiParam("排序方式:comprehensive=综合 newest=最新 hottest=最热") @RequestParam(defaultValue = "comprehensive") String sortType, -@@ -47,7 +50,10 @@ public class InternalExploreCategoryController { - return Result.success(exploreCategoryService.listActive(sortType, page, pageSize)); - } - -- @ApiOperation("获取探索分类详情(自动增加浏览量)") -+ @ApiOperation(value = "获取探索分类详情(自动增加浏览量)", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取指定分类的详细信息,同时自动增加浏览量计数。\n" -+ + "如果传入 X-User-Id 请求头,还会返回当前用户的点赞和收藏状态。") - @GetMapping("/{id}") - public Result getActiveDetail( - @ApiParam("分类ID") @PathVariable Long id, -@@ -65,14 +71,19 @@ public class InternalExploreCategoryController { - return Result.success(exploreCategoryService.getActiveDetail(id, isLiked, isFavorited)); - } - -- @ApiOperation("增加浏览量") -+ @ApiOperation(value = "增加浏览量", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "手动增加指定探索分类的浏览量计数(+1)。") - @PostMapping("/{id}/view") - public Result incrementViewCount(@ApiParam("分类ID") @PathVariable Long id) { - exploreCategoryService.incrementViewCount(id); - return Result.success(); - } - -- @ApiOperation("切换收藏状态") -+ @ApiOperation(value = "切换收藏状态", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "切换用户对指定探索分类的收藏状态:已收藏则取消,未收藏则添加。\n" -+ + "返回 true=已收藏,false=已取消收藏。同时更新分类的收藏计数。") - @PostMapping("/{id}/favorite") - public Result toggleFavorite( - @ApiParam("分类ID") @PathVariable Long id, -@@ -101,7 +112,9 @@ public class InternalExploreCategoryController { - } - } - -- @ApiOperation("检查是否已收藏") -+ @ApiOperation(value = "检查是否已收藏", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "检查用户是否已收藏指定的探索分类,返回 true/false。") - @GetMapping("/{id}/favorite/check") - public Result checkFavorite( - @ApiParam("分类ID") @PathVariable Long id, -@@ -109,7 +122,10 @@ public class InternalExploreCategoryController { - return Result.success(favoriteService.checkFavorite(userId, TARGET_TYPE_EXPLORE, id)); - } - -- @ApiOperation("切换点赞状态") -+ @ApiOperation(value = "切换点赞状态", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "切换用户对指定探索分类的点赞状态:已点赞则取消,未点赞则添加。\n" -+ + "返回 true=已点赞,false=已取消。同时更新分类的点赞计数。") - @PostMapping("/{id}/like") - public Result toggleLike( - @ApiParam("分类ID") @PathVariable Long id, -@@ -119,7 +135,9 @@ public class InternalExploreCategoryController { - return Result.success(liked); - } - -- @ApiOperation("检查是否已点赞") -+ @ApiOperation(value = "检查是否已点赞", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "检查用户是否已点赞指定的探索分类,返回 true/false。") - @GetMapping("/{id}/like/check") - public Result checkLike( - @ApiParam("分类ID") @PathVariable Long id, -@@ -127,7 +145,10 @@ public class InternalExploreCategoryController { - return Result.success(userLikeService.checkLike(userId, TARGET_TYPE_EXPLORE, id)); - } - -- @ApiOperation("获取同分类的景区资源列表") -+ @ApiOperation(value = "获取同分类的景区资源列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "根据景区ID查找与其同一探索分类下的其他景区资源,用于'相关推荐'展示。\n" -+ + "返回资源ID、名称、描述、封面图等基本信息。") - @GetMapping("/related-scenic") - public Result>> getRelatedScenic( - @ApiParam("景区ID") @RequestParam Long scenicId, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalFaqController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFaqController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFaqController.java -index 90d24df..e00222c 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFaqController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFaqController.java -@@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RestController; - - import java.util.List; - --@Api(tags = "【内部接口】常见问题(Feign调用)") -+@Api(tags = "【内部接口】常见问题(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/faq") - @RequiredArgsConstructor -@@ -20,7 +20,9 @@ public class InternalFaqController { - - private final FaqService faqService; - -- @ApiOperation("获取所有启用的FAQ(含分类和条目)") -+ @ApiOperation(value = "获取所有启用的FAQ(含分类和条目)", -+ notes = "内部服务间调用接口,由其他微服务通过 Feign 调用。\n" -+ + "获取所有状态为启用的FAQ分类及其下属条目,按排序号排列。") - @GetMapping("/all") - public Result> getAllActiveFaq() { - return Result.success(faqService.getAllActiveFaq()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalFrontendConfigController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFrontendConfigController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFrontendConfigController.java -index 1f32c3b..4976f91 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFrontendConfigController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalFrontendConfigController.java -@@ -14,7 +14,7 @@ import java.util.List; - * 前端配置内部接口(仅供其他服务通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "【内部接口】前端配置(Feign调用)") -+@Api(tags = "【内部接口】前端配置(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/frontend-config") - @RequiredArgsConstructor -@@ -22,32 +22,42 @@ public class InternalFrontendConfigController { - - private final FrontendConfigService frontendConfigService; - -- @ApiOperation("获取所有启用的前端配置") -+ @ApiOperation(value = "获取所有启用的前端配置", -+ notes = "内部服务间调用接口,由其他微服务通过 Feign 调用。\n" -+ + "获取所有状态为启用的前端配置项列表(含敏感配置)。") - @GetMapping("/all") - public Result> listAllActiveConfigs() { - return Result.success(frontendConfigService.listAllActiveConfigs()); - } - -- @ApiOperation("按分组获取启用的配置") -+ @ApiOperation(value = "按分组获取启用的配置", -+ notes = "内部服务间调用接口,由其他微服务通过 Feign 调用。\n" -+ + "按配置分组名获取该分组下所有已启用的配置项。") - @GetMapping("/group/{group}") - public Result> listActiveConfigsByGroup(@PathVariable String group) { - return Result.success(frontendConfigService.listActiveConfigsByGroup(group)); - } - -- @ApiOperation("按key获取单个配置") -+ @ApiOperation(value = "按key获取单个配置", -+ notes = "内部服务间调用接口,由其他微服务通过 Feign 调用。\n" -+ + "根据 configKey 获取单个已启用的配置项,不存在则返回错误。") - @GetMapping("/key/{key}") - public Result getActiveConfigByKey(@PathVariable String key) { - FrontendConfigVO vo = frontendConfigService.getActiveConfigByKey(key); - return vo != null ? Result.success(vo) : Result.error("配置项不存在"); - } - -- @ApiOperation("获取所有非敏感的前端配置(供小程序使用)") -+ @ApiOperation(value = "获取所有非敏感的前端配置(供小程序使用)", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取所有已启用且非敏感(sensitive=false)的配置项,安全地暴露给小程序C端。") - @GetMapping("/public") - public Result> listPublicConfigs() { - return Result.success(frontendConfigService.listPublicConfigs()); - } - -- @ApiOperation("按分组获取非敏感配置(供小程序使用)") -+ @ApiOperation(value = "按分组获取非敏感配置(供小程序使用)", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "按分组获取非敏感配置,过滤掉标记为敏感的配置项。") - @GetMapping("/public/group/{group}") - public Result> listPublicConfigsByGroup(@PathVariable String group) { - return Result.success(frontendConfigService.listPublicConfigsByGroup(group)); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalLikeController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLikeController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLikeController.java -index aba407f..a14b558 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLikeController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLikeController.java -@@ -14,7 +14,7 @@ import java.util.*; - * 通用点赞内部接口(供 hl-mp-service BFF 通过 Feign 调用) - * 支持任意资源类型:REVIEW, EXPLORE, GUIDE 等 - */ --@Api(tags = "【内部接口】通用点赞(Feign调用)") -+@Api(tags = "【内部接口】通用点赞(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/like") - @RequiredArgsConstructor -@@ -22,7 +22,9 @@ public class InternalLikeController { - - private final UserLikeService userLikeService; - -- @ApiOperation("切换点赞状态(通用)") -+ @ApiOperation(value = "切换点赞状态(通用)", notes = "内部接口,切换用户对指定资源的点赞状态。" -+ + "\n\n**关联字典**:\n" -+ + "- like_target_type(点赞目标类型):请求参数targetType(REVIEW=评价, EXPLORE=探索, GUIDE=攻略)") - @PostMapping("/toggle") - public Result> toggleLike( - @ApiParam("目标类型") @RequestParam String targetType, -@@ -36,7 +38,9 @@ public class InternalLikeController { - return Result.success(data); - } - -- @ApiOperation("检查是否已点赞(通用)") -+ @ApiOperation(value = "检查是否已点赞(通用)", notes = "内部接口,检查用户是否已点赞指定资源。" -+ + "\n\n**关联字典**:\n" -+ + "- like_target_type(点赞目标类型):请求参数targetType(REVIEW=评价, EXPLORE=探索, GUIDE=攻略)") - @GetMapping("/check") - public Result checkLike( - @ApiParam("目标类型") @RequestParam String targetType, -@@ -45,7 +49,9 @@ public class InternalLikeController { - return Result.success(userLikeService.checkLike(userId, targetType, targetId)); - } - -- @ApiOperation("批量检查是否已点赞(接受字符串ID,避免JS大数精度丢失)") -+ @ApiOperation(value = "批量检查是否已点赞(接受字符串ID,避免JS大数精度丢失)", notes = "内部接口,批量检查用户是否已点赞指定资源列表。" -+ + "\n\n**关联字典**:\n" -+ + "- like_target_type(点赞目标类型):请求参数targetType(REVIEW=评价, EXPLORE=探索, GUIDE=攻略)") - @PostMapping("/batch-check") - public Result> batchCheckLiked( - @ApiParam("目标类型") @RequestParam String targetType, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalLoginLogController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLoginLogController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLoginLogController.java -index 124fb4f..179904b 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLoginLogController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalLoginLogController.java -@@ -24,7 +24,7 @@ import java.util.stream.Collectors; - * Internal endpoint for monitor-service to query login logs. - * NOT exposed via gateway. - */ --@Api(tags = "【内部接口】登录日志(Feign调用)") -+@Api(tags = "【内部接口】登录日志(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal") - @RequiredArgsConstructor -@@ -35,7 +35,14 @@ public class InternalLoginLogController { - - private static final DateTimeFormatter FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - -- @ApiOperation("Query login logs") -+ @ApiOperation(value = "查询登录日志", notes = "内部接口,供hl-monitor-service通过Feign查询管理员登录日志。" -+ + "支持按管理员ID、登录状态、时间范围筛选。" -+ + "status取值:SUCCESS=登录成功 FAILED=登录失败。" -+ + "时间格式:yyyy-MM-dd HH:mm:ss。" -+ + "不经过Gateway,仅服务间调用。" -+ + "\n\n**关联字典**:\n" -+ + "- login_status(登录状态):请求参数status和返回字段status(SUCCESS=成功, FAILED=失败)\n" -+ + "- login_method(登录方式):返回字段loginMethod(PASSWORD=密码, WECHAT_QR=企微扫码, TWO_FA=二次验证)") - @GetMapping("/login-logs") - public Result> queryLoginLogs( - @RequestParam(defaultValue = "1") int page, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpCommonController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpCommonController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpCommonController.java -index a8f1de8..8e53118 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpCommonController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpCommonController.java -@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.*; - import java.util.List; - import java.util.Map; - --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/common") - @RequiredArgsConstructor -@@ -19,19 +19,26 @@ public class InternalMpCommonController { - - private final CommonService commonService; - -- @ApiOperation("应用配置") -+ @ApiOperation(value = "应用配置", -+ notes = "内部服务间调用接口,由 hl-mp-service 调用。\n" -+ + "获取小程序应用的基础配置信息,如版本号、客服电话等。") - @GetMapping("/config") - public Result> getConfig() { - return Result.success(commonService.getConfig()); - } - -- @ApiOperation("FAQ列表") -+ @ApiOperation(value = "FAQ列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 调用。\n" -+ + "获取所有启用的FAQ分类及其条目,用于小程序帮助中心页面展示。") - @GetMapping("/faq") - public Result>> listFaq() { - return Result.success(commonService.listFaq()); - } - -- @ApiOperation("提交反馈") -+ @ApiOperation(value = "提交反馈", -+ notes = "内部服务间调用接口,由 hl-mp-service 调用。\n" -+ + "提交用户反馈意见,包括反馈内容、联系方式等。\n" -+ + "需传入 userId 参数标识提交反馈的用户。") - @PostMapping("/feedback") - public Result submitFeedback(@RequestParam Long userId, - @RequestBody UserFeedback feedback) { -@@ -39,13 +46,18 @@ public class InternalMpCommonController { - return Result.success(null); - } - -- @ApiOperation("获取协议文本") -+ @ApiOperation(value = "获取协议文本", -+ notes = "内部服务间调用接口,由 hl-mp-service 调用。\n" -+ + "根据协议类型(如 user_agreement、privacy_policy)获取协议的富文本内容。\n" -+ + "用于小程序协议详情页面展示。") - @GetMapping("/agreement/{type}") - public Result> getAgreement(@PathVariable String type) { - return Result.success(commonService.getAgreement(type)); - } - -- @ApiOperation("获取所有已上线协议列表") -+ @ApiOperation(value = "获取所有已上线协议列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 调用。\n" -+ + "获取所有状态为启用的协议列表,用于小程序注册/登录时展示需要同意的协议链接。") - @GetMapping("/agreement/list") - public Result>> listActiveAgreements() { - return Result.success(commonService.listActiveAgreements()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpDictController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpDictController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpDictController.java -index e634ded..6028ac3 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpDictController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpDictController.java -@@ -19,7 +19,7 @@ import java.util.stream.Collectors; - * C端字典内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/dict") - @RequiredArgsConstructor -@@ -27,7 +27,9 @@ public class InternalMpDictController { - - private final SysDictService sysDictService; - -- @ApiOperation("获取所有字典数据(C端小程序)") -+ @ApiOperation(value = "获取所有字典数据(C端小程序)", notes = "内部接口,供hl-mp-service通过Feign获取小程序可用的字典数据。" -+ + "返回格式:[{dictType, dictName, dataList}],与管理端字典数据格式一致。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/all") - public Result>> getAllDict() { - List dictList = sysDictService.getAllDictForMiniApp(); -@@ -44,7 +46,8 @@ public class InternalMpDictController { - return Result.success(result); - } - -- @ApiOperation("按字典类型获取字典数据列表") -+ @ApiOperation(value = "按字典类型获取字典数据列表", notes = "内部接口,根据字典类型编码(如order_status)获取该类型下的所有字典数据项。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/type/{dictType}") - public Result> getDictDataByType( - @ApiParam("字典类型编码") @PathVariable String dictType) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpMessageController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpMessageController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpMessageController.java -index 4921435..f32737c 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpMessageController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpMessageController.java -@@ -14,7 +14,7 @@ import java.util.HashMap; - import java.util.List; - import java.util.Map; - --@Api(tags = "小程序消息接口") -+@Api(tags = "小程序消息接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/message") - @RequiredArgsConstructor -@@ -22,19 +22,32 @@ public class InternalMpMessageController { - - private final UserMessageService userMessageService; - -- @ApiOperation("消息分类列表(含未读数和最新消息预览)") -+ @ApiOperation(value = "消息分类列表(含未读数和最新消息预览)", notes = "获取用户的消息分类汇总信息。" -+ + "每个分类返回:分类名称、未读消息数、最新一条消息的标题和时间。" -+ + "用于消息中心首页展示各分类入口。" -+ + "内部接口,由hl-mp-service通过Feign调用。" -+ + "\n\n**关联字典**:\n" -+ + "- message_category(消息分类):返回字段code(ORDER=订单消息, TRIP=行程消息, SYSTEM=系统消息, PROMO=营销消息)") - @GetMapping("/categories") - public Result> getCategories(@RequestParam("userId") Long userId) { - return Result.success(userMessageService.getCategorySummaries(userId)); - } - -- @ApiOperation("消息摘要(兼容旧接口)") -+ @ApiOperation(value = "消息摘要(兼容旧接口)", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "功能同 /categories 接口,保留用于向后兼容旧版本小程序。") - @GetMapping("/summary") - public Result> getSummary(@RequestParam("userId") Long userId) { - return Result.success(userMessageService.getCategorySummaries(userId)); - } - -- @ApiOperation("分类内消息列表(进入后自动标记已读)") -+ @ApiOperation(value = "分类内消息列表(进入后自动标记已读)", notes = "分页查询指定分类下的消息列表,按时间倒序排列。" -+ + "进入该分类后自动将该分类的所有消息标记为已读。" -+ + "categoryCode参数支持旧参数名category(向后兼容)。" -+ + "内部接口,由hl-mp-service通过Feign调用。" -+ + "\n\n**关联字典**:\n" -+ + "- message_category(消息分类):请求参数categoryCode(ORDER=订单消息, TRIP=行程消息, SYSTEM=系统消息, PROMO=营销消息)\n" -+ + "- message_biz_type(关联业务类型):返回字段bizType(ORDER=订单, REFUND=退款, CONTRACT=合同)") - @GetMapping("/list") - public Result> listMessages( - @RequestParam("userId") Long userId, -@@ -47,7 +60,9 @@ public class InternalMpMessageController { - return Result.success(userMessageService.listMessages(userId, code, page, pageSize)); - } - -- @ApiOperation("获取总未读数") -+ @ApiOperation(value = "获取总未读数", notes = "获取用户所有分类的未读消息总数。" -+ + "返回{count: N}格式,用于小程序Tab栏消息角标显示。" -+ + "内部接口,由hl-mp-service通过Feign调用。") - @GetMapping("/unread-count") - public Result> getUnreadCount(@RequestParam("userId") Long userId) { - Map result = new HashMap<>(); -@@ -55,7 +70,10 @@ public class InternalMpMessageController { - return Result.success(result); - } - -- @ApiOperation("全部标记已读") -+ @ApiOperation(value = "全部标记已读", notes = "将消息标记为已读。" -+ + "如果传入categoryCode,则只标记该分类下的消息为已读。" -+ + "如果不传categoryCode,则标记所有消息为已读。" -+ + "内部接口,由hl-mp-service通过Feign调用。") - @PutMapping("/read-all") - public Result markAllRead( - @RequestParam("userId") Long userId, -@@ -70,7 +88,9 @@ public class InternalMpMessageController { - return Result.success(null); - } - -- @ApiOperation("标记已读") -+ @ApiOperation(value = "标记已读", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "将单条消息标记为已读(兼容旧接口,实际已被分类级别标记替代)。") - @PutMapping("/{id}/read") - public Result markRead( - @RequestParam("userId") Long userId, -@@ -79,7 +99,9 @@ public class InternalMpMessageController { - return Result.success(null); - } - -- @ApiOperation("删除消息") -+ @ApiOperation(value = "删除消息", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "删除指定的用户消息记录,删除后不可恢复。") - @DeleteMapping("/{id}") - public Result deleteMessage( - @RequestParam("userId") Long userId, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpUserController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpUserController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpUserController.java -index 69c0674..67190a9 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpUserController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalMpUserController.java -@@ -22,7 +22,7 @@ import java.util.Map; - * C端用户内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/user") - @RequiredArgsConstructor -@@ -37,26 +37,37 @@ public class InternalMpUserController { - - // ==================== Auth ==================== - -- @ApiOperation("发送短信验证码") -+ @ApiOperation(value = "发送短信验证码", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "向指定手机号发送6位数字短信验证码,有效期5分钟,60秒内不可重复发送。") - @PostMapping("/sms/send") - public Result sendSmsCode(@Valid @RequestBody SendSmsRequest request) { - smsService.sendVerificationCode(request.getPhone()); - return Result.success(); - } - -- @ApiOperation("短信登录") -+ @ApiOperation(value = "短信登录", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "小程序用户通过手机号+短信验证码登录,首次登录自动注册。\n" -+ + "返回JWT Token和用户基本信息。") - @PostMapping("/login/sms") - public Result loginBySms(@Valid @RequestBody SmsLoginRequest request) { - return Result.success(userService.loginBySms(request)); - } - -- @ApiOperation("微信登录") -+ @ApiOperation(value = "微信登录", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "小程序用户通过微信授权码(wx.login获取的code)登录,首次登录自动注册。\n" -+ + "返回JWT Token和用户基本信息,含 needProfile 字段标识是否需要补全资料。") - @PostMapping("/login") - public Result login(@Valid @RequestBody LoginRequest request) { - return Result.success(userService.login(request)); - } - -- @ApiOperation("获取用户信息") -+ @ApiOperation(value = "获取用户信息", notes = "内部接口,获取用户个人资料,含真实手机号。" -+ + "\n\n**关联字典**:\n" -+ + "- gender(性别):返回字段gender\n" -+ + "- id_card_type(证件类型):返回字段idCardType") - @GetMapping("/profile") - public Result getProfile(@RequestParam Long userId) { - UserVO vo = userService.getProfile(userId); -@@ -65,21 +76,31 @@ public class InternalMpUserController { - return Result.success(vo); - } - -- @ApiOperation("更新用户信息") -+ @ApiOperation(value = "更新用户信息", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "更新用户个人资料,包括昵称、头像、性别、实名信息等。\n" -+ + "首次补全资料时 realName/idCardType/idCardNo 为必填。\n\n" -+ + "**关联字典**:\n" -+ + "- gender(性别):请求字段gender\n" -+ + "- id_card_type(证件类型):请求字段idCardType") - @PutMapping("/profile") - public Result updateProfile(@RequestParam Long userId, - @Valid @RequestBody UpdateProfileRequest request) { - return Result.success(userService.updateProfile(userId, request)); - } - -- @ApiOperation("用户登出") -+ @ApiOperation(value = "用户登出", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "清除指定用户的登录状态,使Token失效。") - @PostMapping("/logout") - public Result logout(@RequestParam Long userId) { - userService.logout(userId); - return Result.success(); - } - -- @ApiOperation("注销账号") -+ @ApiOperation(value = "注销账号", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "永久注销用户账号(软删除),注销后该手机号可重新注册。") - @DeleteMapping("/account") - public Result deleteAccount(@RequestParam Long userId) { - userService.deleteAccount(userId); -@@ -88,14 +109,18 @@ public class InternalMpUserController { - - // ==================== Favorite ==================== - -- @ApiOperation("添加收藏") -+ @ApiOperation(value = "添加收藏", notes = "内部接口,为用户添加收藏。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):请求参数targetType(SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品, EXPLORE=探索)") - @PostMapping("/favorite") - public Result addFavorite(@RequestParam Long userId, - @Valid @RequestBody FavoriteRequest request) { - return Result.success(favoriteService.addFavorite(userId, request)); - } - -- @ApiOperation("收藏列表") -+ @ApiOperation(value = "收藏列表", notes = "内部接口,获取用户收藏列表。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):请求参数targetType和返回字段targetType(SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品, EXPLORE=探索)") - @GetMapping("/favorite") - public Result> listFavorites(@RequestParam Long userId, - @RequestParam(required = false) String targetType, -@@ -104,7 +129,9 @@ public class InternalMpUserController { - return Result.success(favoriteService.listFavorites(userId, targetType, page, pageSize)); - } - -- @ApiOperation("检查是否已收藏") -+ @ApiOperation(value = "检查是否已收藏", notes = "内部接口,检查用户是否已收藏指定资源。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):请求参数targetType") - @GetMapping("/favorite/check") - public Result checkFavorite(@RequestParam Long userId, - @RequestParam String targetType, -@@ -112,7 +139,9 @@ public class InternalMpUserController { - return Result.success(favoriteService.checkFavorite(userId, targetType, targetId)); - } - -- @ApiOperation("批量删除收藏") -+ @ApiOperation(value = "批量删除收藏", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "根据收藏记录ID列表批量删除用户的收藏记录。") - @DeleteMapping("/favorite/batch") - public Result batchDeleteFavorites(@RequestParam Long userId, - @RequestBody List ids) { -@@ -120,7 +149,9 @@ public class InternalMpUserController { - return Result.success(); - } - -- @ApiOperation("按目标取消收藏") -+ @ApiOperation(value = "按目标取消收藏", notes = "内部接口,按目标类型和ID取消收藏。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):请求参数targetType") - @DeleteMapping("/favorite/by-target") - public Result deleteFavoriteByTarget(@RequestParam Long userId, - @RequestParam String targetType, -@@ -129,7 +160,9 @@ public class InternalMpUserController { - return Result.success(); - } - -- @ApiOperation("取消收藏") -+ @ApiOperation(value = "取消收藏", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "根据收藏记录ID删除单条收藏记录。") - @DeleteMapping("/favorite/{id}") - public Result deleteFavorite(@RequestParam Long userId, @PathVariable Long id) { - favoriteService.deleteFavorite(userId, id); -@@ -138,14 +171,18 @@ public class InternalMpUserController { - - // ==================== Footprint ==================== - -- @ApiOperation("记录足迹") -+ @ApiOperation(value = "记录足迹", notes = "内部接口,记录用户浏览足迹。" -+ + "\n\n**关联字典**:\n" -+ + "- footprint_resource_type(足迹资源类型):请求参数resourceType(SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品)") - @PostMapping("/footprint") - public Result addFootprint(@RequestParam Long userId, - @Valid @RequestBody FootprintRequest request) { - return Result.success(footprintService.addFootprint(userId, request)); - } - -- @ApiOperation("足迹列表") -+ @ApiOperation(value = "足迹列表", notes = "内部接口,获取用户足迹列表。" -+ + "\n\n**关联字典**:\n" -+ + "- footprint_resource_type(足迹资源类型):请求参数resourceType和返回字段resourceType(SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品)") - @GetMapping("/footprint") - public Result> listFootprints(@RequestParam Long userId, - @RequestParam(required = false) String resourceType, -@@ -154,7 +191,9 @@ public class InternalMpUserController { - return Result.success(footprintService.listFootprints(userId, resourceType, page, pageSize)); - } - -- @ApiOperation("批量删除足迹") -+ @ApiOperation(value = "批量删除足迹", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "根据足迹记录ID列表批量删除用户的浏览足迹。") - @DeleteMapping("/footprint/batch") - public Result batchDeleteFootprints(@RequestParam Long userId, - @RequestBody List ids) { -@@ -162,7 +201,9 @@ public class InternalMpUserController { - return Result.success(); - } - -- @ApiOperation("删除足迹") -+ @ApiOperation(value = "删除足迹", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "根据足迹记录ID删除单条浏览足迹。") - @DeleteMapping("/footprint/{id}") - public Result deleteFootprint(@RequestParam Long userId, @PathVariable Long id) { - footprintService.deleteFootprint(userId, id); -@@ -171,26 +212,45 @@ public class InternalMpUserController { - -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalOrderUserController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalOrderUserController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalOrderUserController.java -index df5bc72..581cc22 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalOrderUserController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalOrderUserController.java -@@ -17,7 +17,7 @@ import java.util.Map; - /** - * Internal API for order service - */ --@Api(tags = "【内部接口】订单用户(Feign调用)") -+@Api(tags = "【内部接口】订单用户(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/order/user") - @RequiredArgsConstructor -@@ -25,7 +25,10 @@ public class InternalOrderUserController { - - private final UserService userService; - -- @ApiOperation("获取用户基本信息(供订单服务查询使用)") -+ @ApiOperation(value = "获取用户基本信息(供订单服务查询使用)", -+ notes = "内部服务间调用接口,由 hl-order-service 通过 Feign 调用。\n" -+ + "根据 userId 获取用户基本信息(userId、realName、phone),用于订单详情展示。\n" -+ + "**注意**:返回的手机号为真实手机号(未脱敏)。") - @GetMapping("/info") - public Result> getUserInfo(@RequestParam Long userId) { - User user = userService.getById(userId); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalTopicController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalTopicController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalTopicController.java -index fba4363..e432e26 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalTopicController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalTopicController.java -@@ -16,7 +16,7 @@ import java.util.List; - * 探索专题内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/topic") - @RequiredArgsConstructor -@@ -24,7 +24,9 @@ public class InternalTopicController { - - private final TopicService topicService; - -- @ApiOperation("获取当前有效专题列表") -+ @ApiOperation(value = "获取当前有效专题列表", -+ notes = "内部服务间调用接口,由 hl-mp-service 通过 Feign 调用。\n" -+ + "获取所有状态为启用的探索专题列表,按排序号排列,用于小程序探索页面展示。") - @GetMapping("/active") - public Result> listActiveTopics() { - return Result.success(topicService.listActiveTopics()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalUserController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalUserController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalUserController.java -index 6e38f29..d41fb78 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalUserController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalUserController.java -@@ -29,7 +29,7 @@ import java.util.*; - import java.util.stream.Collectors; - - @Slf4j --@Api(tags = "【内部接口】用户信息(Feign调用)") -+@Api(tags = "【内部接口】用户信息(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/user") - @RequiredArgsConstructor -@@ -44,7 +44,8 @@ public class InternalUserController { - private final WechatMiniAppClient wechatMiniAppClient; - private final UserService userService; - -- @ApiOperation("Get admin basic info by ID") -+ @ApiOperation(value = "根据ID获取管理员基本信息", notes = "内部接口,供其他服务通过Feign查询管理员基础信息(ID、用户名、头像、企微姓名)。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/admin/info/{adminId}") - public Result getAdminInfo(@PathVariable Long adminId) { - AdminUser admin = adminUserMapper.selectById(adminId); -@@ -55,7 +56,9 @@ public class InternalUserController { - return Result.success(toBasicDTO(admin, wechatNameMap)); - } - -- @ApiOperation("Batch get admin basic info") -+ @ApiOperation(value = "批量获取管理员基本信息", notes = "内部接口,批量查询多个管理员的基础信息。" -+ + "传入adminId列表,返回对应的管理员信息列表。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/admin/batch-info") - public Result> batchGetAdminInfo(@RequestBody List adminIds) { - if (adminIds == null || adminIds.isEmpty()) { -@@ -69,7 +72,9 @@ public class InternalUserController { - return Result.success(result); - } - -- @ApiOperation("Get all departments") -+ @ApiOperation(value = "获取所有部门列表", notes = "内部接口,获取企业微信同步的所有部门数据。" -+ + "用于通知规则配置等场景中的部门选择。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/departments") - public Result> getDepartments() { - List depts = wechatDepartmentMapper.selectList(null); -@@ -85,7 +90,10 @@ public class InternalUserController { - return Result.success(result); - } - -- @ApiOperation("Get admin IDs belonging to a department") -+ @ApiOperation(value = "获取部门下的管理员ID列表", notes = "内部接口,查询指定部门下所有活跃管理员的ID。" -+ + "通过企微用户的部门归属关联到管理员账号。" -+ + "用于通知规则引擎按部门发送通知。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/admin/dept-members/{deptId}") - public Result> getDeptAdminIds(@PathVariable Long deptId) { - // Find wechat users in this department using FIND_IN_SET for exact match -@@ -113,7 +121,9 @@ public class InternalUserController { - return Result.success(adminIds); - } - -- @ApiOperation("Get admins by role key") -+ @ApiOperation(value = "根据角色标识获取管理员列表", notes = "内部接口,根据角色标识(如CUSTOMIZER、FINANCE等)查询该角色下所有活跃管理员。" -+ + "用于通知规则引擎按角色发送通知。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/admin/by-role-key") - public Result> getAdminsByRoleKey(@RequestParam String roleKey) { - if (roleKey == null || roleKey.isBlank()) { -@@ -148,7 +158,10 @@ public class InternalUserController { - return Result.success(result); - } - -- @ApiOperation("Find C-end user ID by phone number") -+ @ApiOperation(value = "根据手机号查找C端用户ID", notes = "内部接口,根据手机号查找活跃的小程序用户。" -+ + "用于订单绑定流程中通过联系人手机号匹配用户。" -+ + "找不到时返回null(不报错)。" -+ + "不经过Gateway,仅服务间调用。") - @GetMapping("/find-by-phone") - public Result findUserByPhone(@RequestParam String phone) { - if (phone == null || phone.isBlank()) { -@@ -162,7 +175,9 @@ public class InternalUserController { - return Result.success(user != null ? user.getUserId() : null); - } - -- @ApiOperation("Generate mini program URL Link for sharing") -+ @ApiOperation(value = "生成小程序URL Link", notes = "内部接口,生成小程序短链接用于分享。" -+ + "通过微信API生成URL Link,可在浏览器/短信中打开小程序指定页面。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/wechat/miniapp/generate-url-link") - public Result> generateUrlLink( - @RequestParam String path, @RequestParam String query) { -@@ -170,7 +185,10 @@ public class InternalUserController { - return Result.success(result); - } - -- @ApiOperation("Send WeChat message to users") -+ @ApiOperation(value = "发送企业微信消息", notes = "内部接口,向指定的企微用户发送文本消息。" -+ + "toUserIds为企微用户ID列表,支持一次发送给多人。" -+ + "用于审批通知、订单提醒等场景。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/wechat/send-message") - public Result sendWechatMessage(@RequestBody WechatMessageDTO dto) { - if (dto.getToUserIds() == null || dto.getToUserIds().isEmpty()) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalWechatController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWechatController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWechatController.java -index e0d5a6d..d192b76 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWechatController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWechatController.java -@@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.*; - * No JWT auth required (excluded from TokenInterceptor via /internal/** pattern). - */ - @Slf4j --@Api(tags = "【内部接口】企微同步(Feign调用)") -+@Api(tags = "【内部接口】企微同步(Feign调用)", hidden = true) - @RestController - @RequestMapping("/internal/wechat") - @RequiredArgsConstructor -@@ -27,9 +27,11 @@ public class InternalWechatController { - private final WechatSyncService wechatSyncService; - private final ExternalContactNotifyService externalContactNotifyService; - -- @ApiOperation("Sync single user from callback") -+ @ApiOperation(value = "同步单个企微用户(回调触发)", notes = "内部接口,由hl-callback-service在收到企微通讯录变更回调时调用。" -+ + "将单个用户的信息同步到本地wechat_user表。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/user/sync") -- public Result syncUser(@RequestBody WechatUserSyncDTO dto) { -+ public Result syncUser(@RequestBody WechatUserSyncDTO dto) { - log.info("Internal: sync user userid={}", dto.getUserid()); - try { - wechatSyncService.syncSingleUserFromDto(dto); -@@ -40,9 +42,11 @@ public class InternalWechatController { - } - } - -- @ApiOperation("Delete single user from callback") -+ @ApiOperation(value = "删除单个企微用户(回调触发)", notes = "内部接口,由hl-callback-service在收到企微成员离职回调时调用。" -+ + "从本地wechat_user表中删除该用户记录。" -+ + "不经过Gateway,仅服务间调用。") - @DeleteMapping("/user/{userid}") -- public Result deleteUser(@PathVariable("userid") String userid) { -+ public Result deleteUser(@PathVariable("userid") String userid) { - log.info("Internal: delete user userid={}", userid); - try { - wechatSyncService.deleteSingleUser(userid); -@@ -53,9 +57,11 @@ public class InternalWechatController { - } - } - -- @ApiOperation("Sync single department from callback") -+ @ApiOperation(value = "同步单个企微部门(回调触发)", notes = "内部接口,由hl-callback-service在收到企微部门变更回调时调用。" -+ + "将单个部门的信息同步到本地wechat_department表。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/department/sync") -- public Result syncDepartment(@RequestBody WechatDeptSyncDTO dto) { -+ public Result syncDepartment(@RequestBody WechatDeptSyncDTO dto) { - log.info("Internal: sync department deptId={}", dto.getId()); - try { - wechatSyncService.syncSingleDepartmentFromDto(dto); -@@ -66,18 +72,22 @@ public class InternalWechatController { - } - } - -- @ApiOperation("Receive external contact change event") -+ @ApiOperation(value = "接收外部联系人变更事件", notes = "内部接口,由hl-callback-service在收到企微外部联系人变更回调时调用。" -+ + "处理客户添加/删除等事件,异步执行通知逻辑。" -+ + "不经过Gateway,仅服务间调用。") - @PostMapping("/external-contact/event") -- public Result handleExternalContactEvent(@RequestBody ExternalContactEventDTO dto) { -+ public Result handleExternalContactEvent(@RequestBody ExternalContactEventDTO dto) { - log.info("Internal: external contact event changeType={}, userId={}, externalUserId={}", - dto.getChangeType(), dto.getUserId(), dto.getExternalUserId()); - externalContactNotifyService.processEventAsync(dto); - return Result.success(); - } - -- @ApiOperation("Delete single department from callback") -+ @ApiOperation(value = "删除单个企微部门(回调触发)", notes = "内部接口,由hl-callback-service在收到企微部门删除回调时调用。" -+ + "从本地wechat_department表中删除该部门记录。" -+ + "不经过Gateway,仅服务间调用。") - @DeleteMapping("/department/{deptId}") -- public Result deleteDepartment(@PathVariable("deptId") Long deptId) { -+ public Result deleteDepartment(@PathVariable("deptId") Long deptId) { - log.info("Internal: delete department deptId={}", deptId); - try { - wechatSyncService.deleteSingleDepartment(deptId); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/InternalWishController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWishController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWishController.java -index 44641ef..e3cf403 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWishController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/InternalWishController.java -@@ -15,7 +15,7 @@ import java.util.Map; - * 祈愿内部接口(仅供 hl-mp-service BFF 通过 Feign 调用) - * 不经过认证拦截器(/internal/** 已排除) - */ --@Api(tags = "小程序接口") -+@Api(tags = "小程序接口", hidden = true) - @RestController - @RequestMapping("/internal/mp/wish") - @RequiredArgsConstructor -@@ -23,13 +23,17 @@ public class InternalWishController { - - private final WishService wishService; - -- @ApiOperation("获取用户祈愿列表") -+ @ApiOperation(value = "获取用户祈愿列表", notes = "内部接口,获取用户的祈愿列表。" -+ + "\n\n**关联字典**:\n" -+ + "- wish_type(心愿类型):返回字段wishType(1=想去的地方, 2=想做的事, 3=其他)") - @GetMapping - public Result> listWishes(@RequestParam Long userId) { - return Result.success(wishService.listWishes(userId)); - } - -- @ApiOperation("创建祈愿") -+ @ApiOperation(value = "创建祈愿", notes = "内部接口,创建用户祈愿。" -+ + "\n\n**关联字典**:\n" -+ + "- wish_type(心愿类型):请求参数wishType(1=想去的地方, 2=想做的事, 3=其他)") - @PostMapping - public Result createWish(@RequestParam Long userId, - @RequestBody Map request) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/OfficialAccountCallbackController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/OfficialAccountCallbackController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/OfficialAccountCallbackController.java -index 5acc247..753577c 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/OfficialAccountCallbackController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/OfficialAccountCallbackController.java -@@ -24,7 +24,7 @@ import java.util.Map; - @RestController - @RequestMapping("/oa/callback") - @RequiredArgsConstructor --@Api(tags = "【回调接口】公众号回调") -+@Api(tags = "【回调接口】公众号回调", hidden = true) - public class OfficialAccountCallbackController { - - private final WechatOfficialAccountClient oaClient; -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/PublicDictController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/PublicDictController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/PublicDictController.java -index 6d1ec31..38f0ad6 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/PublicDictController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/PublicDictController.java -@@ -24,7 +24,12 @@ public class PublicDictController { - - private final SysDictService sysDictService; - -- @ApiOperation("获取所有字典数据") -+ @ApiOperation(value = "获取所有字典数据(公开接口)", notes = "获取系统全部字典类型及其字典数据,供小程序C端使用。" -+ + "无需认证即可调用。返回格式与管理端 /admin/dict/all 一致。" -+ + "\n\n**字典层级说明**:\n" -+ + "- 每个元素包含 dictType(编码)、dictName(名称)、dataList(字典数据列表)\n" -+ + "- 前端通过 dictType 匹配业务字段,用 dataList 中的 dictValue/dictLabel 做翻译展示\n" -+ + "- 常用字典:order_status、product_status、id_card_type、gender、traveler_type、favorite_resource_type、footprint_resource_type\n") - @GetMapping("/all") - public Result> getAllDict() { - return Result.success(sysDictService.getAllDictForPublic()); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/SysDictController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/SysDictController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/SysDictController.java -index 5be6ee7..260eadd 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/SysDictController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/SysDictController.java -@@ -26,7 +26,14 @@ public class SysDictController { - - // ======================== All Dict ======================== - -- @ApiOperation("获取所有字典数据") -+ @ApiOperation(value = "获取所有字典数据", notes = "获取系统全部字典类型及其字典数据,按字典类型分组返回。" -+ + "用于后台管理系统初始化时一次性加载所有下拉选项。" -+ + "返回结果包含dictType编码、dictName名称、dataList数据列表。" -+ + "需要管理员认证。" -+ + "\n\n**字典层级说明**:\n" -+ + "- 字典类型(SysDictType):一级分类,如 admin_status、order_status、id_card_type 等\n" -+ + "- 字典数据(SysDictData):二级选项,归属于某个字典类型,如 admin_status 下的 ACTIVE/LOCKED/DISABLED\n" -+ + "- 前端通过 dictType 编码查找对应的 dataList,用 dictValue 匹配实际数据进行翻译展示\n") - @GetMapping("/all") - public Result> getAllDict() { - return Result.success(sysDictService.getAllDictForPublic()); -@@ -34,14 +41,21 @@ public class SysDictController { - - // ======================== Dict Type ======================== - -- @ApiOperation("创建字典类型") -+ @ApiOperation(value = "创建字典类型", notes = "新建一个字典类型(如:订单状态、证件类型等)。" -+ + "字典类型编码(dictType)全局唯一,创建后不可修改。" -+ + "需要管理员认证,建议仅SUPER_ADMIN/ADMIN角色操作。" -+ + "\n\n**已有字典类型示例**:\n" -+ + "- admin_status(管理员状态)、common_status(通用状态)、login_status(登录状态)\n" -+ + "- order_status(订单状态)、product_status(产品状态)、rating_level(评价等级)\n" -+ + "- id_card_type(证件类型)、gender(性别)、traveler_type(出行人类型)\n" -+ + "- contact_channel_type(联系方式渠道类型)、favorite_resource_type(收藏资源类型)、footprint_resource_type(足迹资源类型)\n") - @OperationLog(value = "创建字典类型", module = "字典管理") - @PostMapping("/type") - public Result createDictType(@ApiParam("创建字典类型请求") @Valid @RequestBody CreateDictTypeRequest request) { - return Result.success(sysDictService.createDictType(request)); - } - -- @ApiOperation("更新字典类型") -+ @ApiOperation(value = "更新字典类型", notes = "更新字典类型的名称、分类、备注等信息。字典类型编码(dictType)不可修改。") - @OperationLog(value = "更新字典类型", module = "字典管理") - @PutMapping("/type/{id}") - public Result updateDictType(@ApiParam("字典类型ID") @PathVariable Long id, -@@ -49,7 +63,9 @@ public class SysDictController { - return Result.success(sysDictService.updateDictType(id, request)); - } - -- @ApiOperation("删除字典类型") -+ @ApiOperation(value = "删除字典类型", notes = "删除字典类型及其下所有字典数据(软删除)。" -+ + "如果该字典类型已被业务引用,删除后不影响已有数据,但新的表单将无法选择该字典值。" -+ + "需要管理员认证。") - @OperationLog(value = "删除字典类型", module = "字典管理") - @DeleteMapping("/type/{id}") - public Result deleteDictType(@ApiParam("字典类型ID") @PathVariable Long id) { -@@ -57,7 +73,8 @@ public class SysDictController { - return Result.success(); - } - -- @ApiOperation("分页查询字典类型") -+ @ApiOperation(value = "分页查询字典类型", notes = "分页查询字典类型列表,支持按分类(category)筛选。" -+ + "字典类型是字典数据的上级分组,管理字典类型即管理有哪些可供前端使用的下拉选项组。") - @GetMapping("/type") - public Result> listDictTypes( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -66,7 +83,7 @@ public class SysDictController { - return Result.success(sysDictService.listDictTypes(page, pageSize, category)); - } - -- @ApiOperation("根据ID获取字典类型详情") -+ @ApiOperation(value = "根据ID获取字典类型详情", notes = "获取单个字典类型的详细信息,包括编码、名称、分类、状态等。") - @GetMapping("/type/{dictTypeId}") - public Result getDictTypeById(@ApiParam("字典类型ID") @PathVariable Long dictTypeId) { - return Result.success(sysDictService.getDictTypeById(dictTypeId)); -@@ -74,14 +91,16 @@ public class SysDictController { - - // ======================== Dict Data ======================== - -- @ApiOperation("创建字典数据") -+ @ApiOperation(value = "创建字典数据", notes = "在指定字典类型下新增一条字典数据项。" -+ + "dictValue为前端匹配的值(如ACTIVE),dictLabel为前端展示的标签(如'启用')。" -+ + "支持树形字典数据(通过parentId设置父级)。") - @OperationLog(value = "创建字典数据", module = "字典管理") - @PostMapping("/data") - public Result createDictData(@ApiParam("创建字典数据请求") @Valid @RequestBody CreateDictDataRequest request) { - return Result.success(sysDictService.createDictData(request)); - } - -- @ApiOperation("更新字典数据") -+ @ApiOperation(value = "更新字典数据", notes = "更新字典数据项的标签、样式类型、排序号等。dictValue建议不修改以免影响已有业务数据。") - @OperationLog(value = "更新字典数据", module = "字典管理") - @PutMapping("/data/{id}") - public Result updateDictData(@ApiParam("字典数据ID") @PathVariable Long id, -@@ -89,7 +108,7 @@ public class SysDictController { - return Result.success(sysDictService.updateDictData(id, request)); - } - -- @ApiOperation("删除字典数据") -+ @ApiOperation(value = "删除字典数据", notes = "删除指定字典数据项(软删除)。删除后不影响已引用该字典值的业务数据。") - @OperationLog(value = "删除字典数据", module = "字典管理") - @DeleteMapping("/data/{id}") - public Result deleteDictData(@ApiParam("字典数据ID") @PathVariable Long id) { -@@ -97,19 +116,23 @@ public class SysDictController { - return Result.success(); - } - -- @ApiOperation("根据ID获取字典数据详情") -+ @ApiOperation(value = "根据ID获取字典数据详情", notes = "获取单个字典数据项的详细信息,包括dictValue、dictLabel、cssClass等。") - @GetMapping("/data/detail/{dictDataId}") - public Result getDictDataById(@ApiParam("字典数据ID") @PathVariable Long dictDataId) { - return Result.success(sysDictService.getDictDataById(dictDataId)); - } - -- @ApiOperation("按类型查询字典数据(树形结构)") -+ @ApiOperation(value = "按类型查询字典数据(树形结构)", notes = "根据字典类型ID查询其下所有字典数据,以树形结构返回(支持父子级字典数据)。" -+ + "用于多级联动下拉框场景(如省市区)。" -+ + "需要管理员认证。") - @GetMapping("/data/tree/{dictTypeId}") - public Result> getDictDataTree(@ApiParam("字典类型ID") @PathVariable Long dictTypeId) { - return Result.success(sysDictService.getDictDataTree(dictTypeId)); - } - -- @ApiOperation("按类型查询字典数据") -+ @ApiOperation(value = "按类型查询字典数据", notes = "根据字典类型编码(如order_status)查询其下所有字典数据(平铺列表)。" -+ + "用于单层下拉框场景。" -+ + "需要管理员认证。") - @GetMapping("/data/{dictType}") - public Result> getDictDataByType(@ApiParam("字典类型编码") @PathVariable String dictType) { - return Result.success(sysDictService.getDictDataByType(dictType)); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/SysJobController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/SysJobController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/SysJobController.java -index 22b99cb..d58905e 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/SysJobController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/SysJobController.java -@@ -5,9 +5,9 @@ import com.hulalv.common.result.PageResult; - import com.hulalv.common.result.Result; - import com.hulalv.user.dto.CreateJobRequest; - import com.hulalv.user.dto.UpdateJobRequest; --import com.hulalv.user.entity.SysJob; --import com.hulalv.user.entity.SysJobLog; - import com.hulalv.user.service.SysJobService; -+import com.hulalv.user.vo.SysJobLogVO; -+import com.hulalv.user.vo.SysJobVO; - import io.swagger.annotations.Api; - import io.swagger.annotations.ApiOperation; - import io.swagger.annotations.ApiParam; -@@ -24,22 +24,39 @@ public class SysJobController { - - private final SysJobService sysJobService; - -- @ApiOperation("创建定时任务") -+ @ApiOperation(value = "创建定时任务", notes = "创建新的定时任务。" -+ + "invokeTarget格式为'Bean名称.方法名'(如wechatSyncService.syncAll),方法必须是无参公开方法。" -+ + "cronExpression为标准6位Cron表达式(秒 分 时 日 月 周)。" -+ + "创建后任务默认为暂停状态(PAUSED),需手动调用[恢复任务]接口启用。" -+ + "\n\n**关联字典**:\n" -+ + "- job_group(任务分组):DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步\n" -+ + "- job_misfire_policy(执行策略):DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发\n" -+ + "- job_status(任务状态):ACTIVE=启用, PAUSED=已暂停\n\n" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "创建定时任务", module = "定时任务") - @PostMapping -- public Result createJob(@ApiParam("创建定时任务请求") @Valid @RequestBody CreateJobRequest request) { -+ public Result createJob(@ApiParam("创建定时任务请求") @Valid @RequestBody CreateJobRequest request) { - return Result.success(sysJobService.createJob(request)); - } - -- @ApiOperation("更新定时任务") -+ @ApiOperation(value = "更新定时任务", -+ notes = "更新指定定时任务的名称、Cron表达式、调用目标等信息。\n" -+ + "修改Cron表达式后任务将按新的计划执行。\n\n" -+ + "**关联字典**:\n" -+ + "- job_group(任务分组):DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步\n" -+ + "- job_misfire_policy(执行策略):DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发\n\n" -+ + "**权限**:需要SUPER_ADMIN角色。") - @OperationLog(value = "更新定时任务", module = "定时任务") - @PutMapping("/{jobId}") -- public Result updateJob(@ApiParam("定时任务ID") @PathVariable Long jobId, -+ public Result updateJob(@ApiParam("定时任务ID") @PathVariable Long jobId, - @ApiParam("更新定时任务请求") @Valid @RequestBody UpdateJobRequest request) { - return Result.success(sysJobService.updateJob(jobId, request)); - } - -- @ApiOperation("删除定时任务") -+ @ApiOperation(value = "删除定时任务", -+ notes = "删除指定的定时任务(软删除),同时从调度器中移除该任务。\n\n" -+ + "**权限**:需要SUPER_ADMIN角色。\n" -+ + "**注意**:删除后任务将不再执行,但历史执行日志仍可查看。") - @OperationLog(value = "删除定时任务", module = "定时任务") - @DeleteMapping("/{jobId}") - public Result deleteJob(@ApiParam("定时任务ID") @PathVariable Long jobId) { -@@ -47,15 +64,22 @@ public class SysJobController { - return Result.success(); - } - -- @ApiOperation("分页查询定时任务") -+ @ApiOperation(value = "分页查询定时任务", notes = "分页查询定时任务列表。" -+ + "\n\n**关联字典**:\n" -+ + "- job_group(任务分组):DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步\n" -+ + "- job_misfire_policy(执行策略):DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发\n" -+ + "- job_status(任务状态):ACTIVE=启用, PAUSED=已暂停") - @GetMapping -- public Result> listJobs( -+ public Result> listJobs( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, - @ApiParam("每页条数") @RequestParam(defaultValue = "20") int pageSize) { - return Result.success(sysJobService.listJobs(page, pageSize)); - } - -- @ApiOperation("暂停任务") -+ @ApiOperation(value = "暂停任务", notes = "暂停指定的定时任务,任务状态变为PAUSED。" -+ + "暂停后任务不再按Cron计划执行,但可通过[恢复任务]接口重新启用。" -+ + "\n\n**关联字典**:job_status(任务状态):ACTIVE=启用, PAUSED=已暂停\n\n" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "暂停任务", module = "定时任务") - @PostMapping("/{jobId}/pause") - public Result pauseJob(@ApiParam("定时任务ID") @PathVariable Long jobId) { -@@ -63,7 +87,10 @@ public class SysJobController { - return Result.success(); - } - -- @ApiOperation("恢复任务") -+ @ApiOperation(value = "恢复任务", notes = "恢复已暂停的定时任务,任务状态变为ACTIVE。" -+ + "恢复后任务按Cron计划继续执行。" -+ + "\n\n**关联字典**:job_status(任务状态):ACTIVE=启用, PAUSED=已暂停\n\n" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "恢复任务", module = "定时任务") - @PostMapping("/{jobId}/resume") - public Result resumeJob(@ApiParam("定时任务ID") @PathVariable Long jobId) { -@@ -71,7 +98,10 @@ public class SysJobController { - return Result.success(); - } - -- @ApiOperation("立即执行一次") -+ @ApiOperation(value = "立即执行一次", notes = "立即触发一次定时任务的执行,不影响原有的Cron计划。" -+ + "无论任务当前状态是ACTIVE还是PAUSED,都可以手动触发。" -+ + "执行结果可在任务日志中查看。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "立即执行任务", module = "定时任务") - @PostMapping("/{jobId}/trigger") - public Result triggerJob(@ApiParam("定时任务ID") @PathVariable Long jobId) { -@@ -79,9 +109,12 @@ public class SysJobController { - return Result.success(); - } - -- @ApiOperation("查询任务日志") -+ @ApiOperation(value = "查询任务日志", notes = "分页查询指定定时任务的执行日志,按执行时间倒序排列。" -+ + "日志包含执行状态(成功/失败)、执行耗时、异常信息等。" -+ + "\n\n**关联字典**:job_log_status(日志状态):SUCCESS=成功, FAIL=失败\n\n" -+ + "需要管理员认证。") - @GetMapping("/{jobId}/logs") -- public Result> listJobLogs( -+ public Result> listJobLogs( - @ApiParam("定时任务ID") @PathVariable Long jobId, - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, - @ApiParam("每页条数") @RequestParam(defaultValue = "20") int pageSize) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/SysMenuController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/SysMenuController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/SysMenuController.java -index 46e8615..44e4293 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/SysMenuController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/SysMenuController.java -@@ -24,14 +24,27 @@ public class SysMenuController { - - private final SysMenuService sysMenuService; - -- @ApiOperation("创建菜单") -+ @ApiOperation(value = "创建菜单", notes = "创建新的菜单/目录/按钮。" -+ + "menuType取值:DIRECTORY=目录(含子菜单) MENU=页面菜单 BUTTON=操作按钮。" -+ + "目录和菜单需设置path路由路径,菜单还需设置component组件路径。" -+ + "按钮类型需设置permissionCode权限标识(如system:user:add)。" -+ + "需要SUPER_ADMIN角色。" -+ + "\n\n**关联字典**:\n" -+ + "- menu_type(菜单类型):请求/返回字段menuType(DIRECTORY=目录, MENU=菜单, BUTTON=按钮)\n" -+ + "- common_status(通用状态):返回字段status") - @OperationLog(value = "创建菜单", module = "菜单管理") - @PostMapping - public Result createMenu(@ApiParam("创建菜单请求") @Valid @RequestBody CreateMenuRequest request) { - return Result.success(sysMenuService.createMenu(request)); - } - -- @ApiOperation("更新菜单") -+ @ApiOperation(value = "更新菜单", -+ notes = "更新指定菜单的名称、路径、组件、图标、排序、状态等信息。\n\n" -+ + "**权限**:需要SUPER_ADMIN角色。\n" -+ + "**注意**:修改后需清除 Redis 菜单缓存才能生效。\n\n" -+ + "**关联字典**:\n" -+ + "- menu_type(菜单类型):请求字段menuType(DIRECTORY=目录, MENU=菜单, BUTTON=按钮)\n" -+ + "- common_status(通用状态):请求字段status") - @OperationLog(value = "更新菜单", module = "菜单管理") - @PutMapping("/{menuId}") - public Result updateMenu(@ApiParam("菜单ID") @PathVariable Long menuId, -@@ -39,7 +52,11 @@ public class SysMenuController { - return Result.success(sysMenuService.updateMenu(menuId, request)); - } - -- @ApiOperation("删除菜单") -+ @ApiOperation(value = "删除菜单", -+ notes = "删除指定的菜单/目录/按钮(软删除)。\n\n" -+ + "**权限**:需要SUPER_ADMIN角色。\n" -+ + "**注意**:如果该菜单有子菜单,需先删除子菜单才能删除父菜单。" -+ + "删除后需清除 Redis 菜单缓存才能生效。") - @OperationLog(value = "删除菜单", module = "菜单管理") - @DeleteMapping("/{menuId}") - public Result deleteMenu(@ApiParam("菜单ID") @PathVariable Long menuId) { -@@ -47,25 +64,42 @@ public class SysMenuController { - return Result.success(); - } - -- @ApiOperation("获取菜单详情") -+ @ApiOperation(value = "获取菜单详情", -+ notes = "获取指定菜单的详细信息,包括名称、路径、组件、图标、排序、权限标识等。\n\n" -+ + "**权限**:需要管理员登录。\n\n" -+ + "**关联字典**:\n" -+ + "- menu_type(菜单类型):返回字段menuType(DIRECTORY=目录, MENU=菜单, BUTTON=按钮)\n" -+ + "- common_status(通用状态):返回字段status") - @GetMapping("/{menuId}") - public Result getMenu(@ApiParam("菜单ID") @PathVariable Long menuId) { - return Result.success(sysMenuService.getMenuById(menuId)); - } - -- @ApiOperation("获取完整菜单树") -+ @ApiOperation(value = "获取完整菜单树", notes = "获取系统所有菜单的完整树形结构。" -+ + "用于角色权限配置页面展示完整的菜单树供勾选。" -+ + "仅SUPER_ADMIN可查看完整菜单树。" -+ + "需要管理员认证。" -+ + "\n\n**关联字典**:\n" -+ + "- menu_type(菜单类型):返回字段menuType\n" -+ + "- common_status(通用状态):返回字段status") - @GetMapping("/tree") - public Result> getMenuTree() { - return Result.success(sysMenuService.getMenuTree()); - } - -- @ApiOperation("获取角色菜单树") -+ @ApiOperation(value = "获取角色菜单树", -+ notes = "获取指定角色已分配的菜单树形结构。\n" -+ + "用于角色权限配置页面,展示该角色已拥有的菜单权限。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/tree/role/{roleId}") - public Result> getMenuTreeByRoleId(@ApiParam("角色ID") @PathVariable Long roleId) { - return Result.success(sysMenuService.getMenuTreeByRoleId(roleId)); - } - -- @ApiOperation("获取当前管理员菜单") -+ @ApiOperation(value = "获取当前管理员菜单", notes = "获取当前登录管理员的菜单树(基于其当前角色的权限)。" -+ + "SUPER_ADMIN角色返回完整菜单树,其他角色返回已授权的菜单子集。" -+ + "前端登录后调用此接口动态生成路由和侧边栏菜单。" -+ + "需要管理员认证。") - @GetMapping("/my") - public Result> getMyMenus(HttpServletRequest request) { - Long adminId = (Long) request.getAttribute("adminId"); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/SysRoleController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/SysRoleController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/SysRoleController.java -index 1e4979d..52f6507 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/SysRoleController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/SysRoleController.java -@@ -25,14 +25,19 @@ public class SysRoleController { - - private final SysRoleService sysRoleService; - -- @ApiOperation("创建角色") -+ @ApiOperation(value = "创建角色", notes = "创建新的系统角色。" -+ + "角色标识(roleKey)全局唯一,创建后不可修改,用于代码中的权限判断。" -+ + "创建后需通过[分配菜单权限]接口为角色授权菜单。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "创建角色", module = "角色管理") - @PostMapping - public Result createRole(@ApiParam("创建角色请求") @Valid @RequestBody CreateRoleRequest request) { - return Result.success(sysRoleService.createRole(request)); - } - -- @ApiOperation("更新角色") -+ @ApiOperation(value = "更新角色", notes = "更新角色名称、状态等信息。角色标识(roleKey)不可修改。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):ACTIVE=启用, DISABLED=禁用\n") - @OperationLog(value = "更新角色", module = "角色管理") - @PutMapping("/{roleId}") - public Result updateRole(@ApiParam("角色ID") @PathVariable Long roleId, -@@ -40,7 +45,10 @@ public class SysRoleController { - return Result.success(sysRoleService.updateRole(roleId, request)); - } - -- @ApiOperation("删除角色") -+ @ApiOperation(value = "删除角色", notes = "删除指定角色(软删除)。" -+ + "如果该角色下还有关联的管理员,将无法删除,需先解除绑定关系。" -+ + "内置角色(SUPER_ADMIN等)不可删除。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "删除角色", module = "角色管理") - @DeleteMapping("/{roleId}") - public Result deleteRole(@ApiParam("角色ID") @PathVariable Long roleId) { -@@ -48,13 +56,17 @@ public class SysRoleController { - return Result.success(); - } - -- @ApiOperation("获取角色详情(含菜单ID)") -+ @ApiOperation(value = "获取角色详情(含菜单ID)", notes = "获取角色基本信息及其已分配的菜单ID列表。" -+ + "返回role对象和menuIds数组,用于角色编辑页面回显已勾选的菜单。" -+ + "需要管理员认证。") - @GetMapping("/{roleId}") - public Result> getRoleDetail(@ApiParam("角色ID") @PathVariable Long roleId) { - return Result.success(sysRoleService.getRoleDetail(roleId)); - } - -- @ApiOperation("分页查询角色") -+ @ApiOperation(value = "分页查询角色", notes = "分页查询系统角色列表,支持按状态筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- common_status(通用状态):ACTIVE=启用, DISABLED=禁用(筛选条件+列表展示)\n") - @GetMapping - public Result> listRoles( - @ApiParam("页码") @RequestParam(defaultValue = "1") int page, -@@ -63,13 +75,19 @@ public class SysRoleController { - return Result.success(sysRoleService.listRoles(page, pageSize, status)); - } - -- @ApiOperation("获取所有角色(下拉)") -+ @ApiOperation(value = "获取所有角色(下拉)", notes = "获取所有状态正常的角色列表,用于下拉选择框。" -+ + "不分页,返回全部角色。创建管理员、筛选管理员列表时使用。" -+ + "需要管理员认证。") - @GetMapping("/all") - public Result> getAllRoles() { - return Result.success(sysRoleService.getAllRoles()); - } - -- @ApiOperation("分配菜单权限") -+ @ApiOperation(value = "分配菜单权限", notes = "为指定角色分配菜单权限(全量覆盖模式)。" -+ + "传入的menuIds将完全替换该角色原有的菜单权限。" -+ + "分配后该角色的所有在线管理员下次请求 /admin/menu/my 时会获取到新的菜单树。" -+ + "注意:需同步清除Redis中的菜单缓存,否则前端拿到的是旧菜单。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "分配菜单权限", module = "角色管理") - @PutMapping("/{roleId}/menus") - public Result assignMenus(@ApiParam("角色ID") @PathVariable Long roleId, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/TravelerController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/TravelerController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/TravelerController.java -index 5f71654..ac3f257 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/TravelerController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/TravelerController.java -@@ -22,7 +22,15 @@ public class TravelerController { - - private final TravelerService travelerService; - -- @ApiOperation("新增出行人") -+ @ApiOperation(value = "新增出行人", notes = "为当前用户添加一位出行人信息,用于下单时选择。" -+ + "出行人类型(成人/儿童/婴儿)根据出生日期自动判断,无需手动传入。" -+ + "如果传入身份证号,后端自动校验格式并解析性别。" -+ + "每个用户最多可添加20位出行人。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- gender(性别):请求/返回字段gender(0=女, 1=男)\n" -+ + "- id_card_type(证件类型):请求/返回字段idCardType(ID_CARD=身份证, PASSPORT=护照等)\n" -+ + "- traveler_type(出行人类型):返回字段travelerType(ADULT=成人, CHILD=儿童, INFANT=婴儿,自动计算)") - @PostMapping - public Result addTraveler(HttpServletRequest request, - @ApiParam("出行人信息") @Valid @RequestBody TravelerRequest travelerRequest) { -@@ -31,7 +39,14 @@ public class TravelerController { - return Result.success(traveler); - } - -- @ApiOperation("出行人列表") -+ @ApiOperation(value = "出行人列表", notes = "获取当前用户的所有出行人列表。" -+ + "如果用户已完成实名认证(realName不为空),列表首项会自动注入一个'本人'虚拟出行人(travelerId=0)。" -+ + "默认出行人排在前面,其余按创建时间排序。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- gender(性别):返回字段gender\n" -+ + "- id_card_type(证件类型):返回字段idCardType\n" -+ + "- traveler_type(出行人类型):返回字段travelerType") - @GetMapping - public Result> listTravelers(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -@@ -39,7 +54,11 @@ public class TravelerController { - return Result.success(travelers); - } - -- @ApiOperation("出行人详情") -+ @ApiOperation(value = "出行人详情", notes = "获取指定出行人的详细信息。" -+ + "\n\n**关联字典**:\n" -+ + "- gender(性别):返回字段gender\n" -+ + "- id_card_type(证件类型):返回字段idCardType\n" -+ + "- traveler_type(出行人类型):返回字段travelerType") - @GetMapping("/{travelerId}") - public Result getTraveler(HttpServletRequest request, - @ApiParam("出行人ID") @PathVariable Long travelerId) { -@@ -48,7 +67,11 @@ public class TravelerController { - return Result.success(traveler); - } - -- @ApiOperation("更新出行人") -+ @ApiOperation(value = "更新出行人", notes = "更新指定出行人的信息。" -+ + "\n\n**关联字典**:\n" -+ + "- gender(性别):请求/返回字段gender\n" -+ + "- id_card_type(证件类型):请求/返回字段idCardType\n" -+ + "- traveler_type(出行人类型):返回字段travelerType(自动计算)") - @PutMapping("/{travelerId}") - public Result updateTraveler(HttpServletRequest request, - @ApiParam("出行人ID") @PathVariable Long travelerId, -@@ -58,7 +81,10 @@ public class TravelerController { - return Result.success(traveler); - } - -- @ApiOperation("删除出行人") -+ @ApiOperation(value = "删除出行人", -+ notes = "删除指定的出行人记录(软删除)。\n\n" -+ + "**权限**:需要小程序用户认证。\n" -+ + "**注意**:如果该出行人已关联到未完成的订单,删除不影响订单中的出行人快照数据。") - @DeleteMapping("/{travelerId}") - public Result deleteTraveler(HttpServletRequest request, - @ApiParam("出行人ID") @PathVariable Long travelerId) { -@@ -67,7 +93,10 @@ public class TravelerController { - return Result.success(); - } - -- @ApiOperation("设为默认出行人") -+ @ApiOperation(value = "设为默认出行人", notes = "将指定出行人设为默认。" -+ + "每个用户只能有一个默认出行人,设置新的默认会自动取消原来的默认。" -+ + "默认出行人在下单时会被自动选中。" -+ + "需要小程序用户认证。") - @PutMapping("/{travelerId}/default") - public Result setDefault(HttpServletRequest request, - @ApiParam("出行人ID") @PathVariable Long travelerId) { -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/UserController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/UserController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/UserController.java -index f5d5dc0..24ecd04 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/UserController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/UserController.java -@@ -29,28 +29,42 @@ public class UserController { - private final SmsService smsService; - private final FavoriteService favoriteService; - -- @ApiOperation("发送短信验证码") -+ @ApiOperation(value = "发送短信验证码", notes = "向指定手机号发送6位数字短信验证码,用于小程序手机号登录。" -+ + "同一手机号60秒内不可重复发送,每日最多发送10次。" -+ + "验证码有效期5分钟。" -+ + "无需认证即可调用。") - @PostMapping("/sms/send") - public Result sendSmsCode(@ApiParam("发送短信验证码请求") @Valid @RequestBody SendSmsRequest request) { - smsService.sendVerificationCode(request.getPhone()); - return Result.success(); - } - -- @ApiOperation("手机号验证码登录") -+ @ApiOperation(value = "手机号验证码登录", notes = "小程序用户通过手机号+短信验证码登录。" -+ + "首次登录自动注册账号,返回JWT Token。" -+ + "登录成功后若needProfile=true,表示需要补充个人信息(实名认证),前端应跳转到信息补充页。" -+ + "无需认证即可调用。") - @PostMapping("/login/sms") - public Result loginBySms(@ApiParam("短信验证码登录请求") @Valid @RequestBody SmsLoginRequest request) { - LoginResponse response = userService.loginBySms(request); - return Result.success(response); - } - -- @ApiOperation("微信登录") -+ @ApiOperation(value = "微信登录", notes = "小程序用户通过微信授权码(wx.login获取的code)登录。" -+ + "可选传入phoneCode用于获取手机号绑定,avatar和nickname用于设置头像昵称。" -+ + "首次登录自动注册,返回JWT Token。needProfile=true表示需补充实名信息。" -+ + "无需认证即可调用。") - @PostMapping("/login") - public Result login(@ApiParam("微信登录请求") @Valid @RequestBody LoginRequest request) { - LoginResponse response = userService.login(request); - return Result.success(response); - } - -- @ApiOperation("获取用户信息") -+ @ApiOperation(value = "获取用户信息", notes = "获取当前登录用户的个人资料,包括昵称、头像、手机号(脱敏)、实名信息等。" -+ + "手机号返回脱敏格式(如138****0000),证件号同样脱敏处理。" -+ + "需要小程序用户认证(Token中的userId)。" -+ + "\n\n**关联字典**:\n" -+ + "- id_card_type(证件类型):ID_CARD=身份证, PASSPORT=护照\n" -+ + "- gender(性别):0=女, 1=男\n") - @GetMapping("/profile") - public Result getProfile(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -@@ -58,7 +72,14 @@ public class UserController { - return Result.success(user); - } - -- @ApiOperation("更新用户信息") -+ @ApiOperation(value = "更新用户信息", notes = "更新当前用户的个人资料。" -+ + "首次登录补充信息时realName/idCardType/idCardNo为必填(使用ProfileCompletion验证组)。" -+ + "如果传入身份证号,后端自动解析性别和出生日期。" -+ + "更新手机号后会自动绑定匹配的待绑定订单。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- id_card_type(证件类型):ID_CARD=身份证, PASSPORT=护照(请求参数idCardType)\n" -+ + "- gender(性别):0=女, 1=男\n") - @PutMapping("/profile") - public Result updateProfile(HttpServletRequest request, - @ApiParam("更新用户信息请求") @Valid @RequestBody UpdateProfileRequest updateRequest) { -@@ -67,7 +88,8 @@ public class UserController { - return Result.success(user); - } - -- @ApiOperation("用户登出") -+ @ApiOperation(value = "用户登出", notes = "清除当前用户的登录状态并使Token失效。" -+ + "需要小程序用户认证。") - @PostMapping("/logout") - public Result logout(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -@@ -75,7 +97,10 @@ public class UserController { - return Result.success(); - } - -- @ApiOperation("注销账号") -+ @ApiOperation(value = "注销账号", notes = "永久注销当前用户账号(软删除)。" -+ + "注销后该账号的openid和手机号将被释放,可用于重新注册。" -+ + "注销操作不可撤销,请谨慎调用。" -+ + "需要小程序用户认证。") - @DeleteMapping("/account") - public Result deleteAccount(HttpServletRequest request) { - Long userId = (Long) request.getAttribute("userId"); -@@ -83,7 +108,12 @@ public class UserController { - return Result.success(); - } - -- @ApiOperation("检查是否已收藏") -+ @ApiOperation(value = "检查是否已收藏", notes = "检查当前用户是否已收藏指定类型的资源。" -+ + "返回true=已收藏,false=未收藏。" -+ + "targetType取值:SCENIC_SPOT/ACTIVITY/HOTEL/PRODUCT/EXPLORE等。" -+ + "需要小程序用户认证。" -+ + "\n\n**关联字典**:\n" -+ + "- favorite_resource_type(收藏资源类型):SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品, EXPLORE=探索(请求参数targetType)\n") - @GetMapping("/favorite/check") - public Result checkFavorite(HttpServletRequest request, - @ApiParam("目标类型") @RequestParam String targetType, -``` - -### `hl-user-service/src/main/java/com/hulalv/user/controller/WechatSyncController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/controller/WechatSyncController.java b/hl-user-service/src/main/java/com/hulalv/user/controller/WechatSyncController.java -index 2b68e9c..03cca6a 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/controller/WechatSyncController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/controller/WechatSyncController.java -@@ -23,7 +23,10 @@ public class WechatSyncController { - - private final WechatSyncService wechatSyncService; - -- @ApiOperation("手动同步部门") -+ @ApiOperation(value = "手动同步部门", notes = "从企业微信拉取最新的部门列表并同步到本地数据库。" -+ + "通常在企业微信后台调整组织架构后手动触发。" -+ + "也可通过定时任务自动执行。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "手动同步部门", module = "企业微信同步") - @PostMapping("/sync/departments") - public Result syncDepartments() { -@@ -31,7 +34,10 @@ public class WechatSyncController { - return Result.success(); - } - -- @ApiOperation("手动同步用户") -+ @ApiOperation(value = "手动同步用户", notes = "从企业微信拉取所有部门的成员列表并同步到本地数据库。" -+ + "包括姓名、手机号、职位、部门归属等信息。" -+ + "需先同步部门再同步用户,或直接使用[同步全部]接口。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "手动同步用户", module = "企业微信同步") - @PostMapping("/sync/users") - public Result syncUsers() { -@@ -39,7 +45,10 @@ public class WechatSyncController { - return Result.success(); - } - -- @ApiOperation("手动同步全部(部门+用户)") -+ @ApiOperation(value = "手动同步全部(部门+用户)", notes = "一键同步企业微信的部门和用户数据,先同步部门再同步用户。" -+ + "推荐使用此接口而非单独同步,确保部门和用户数据一致性。" -+ + "同步过程为异步执行,接口立即返回成功。" -+ + "需要SUPER_ADMIN角色。") - @OperationLog(value = "手动同步全部", module = "企业微信同步") - @PostMapping("/sync/all") - public Result syncAll() { -@@ -47,7 +56,13 @@ public class WechatSyncController { - return Result.success(); - } - -- @ApiOperation("查询企业微信用户(分页+搜索)") -+ @ApiOperation(value = "查询企业微信用户(分页+搜索)", notes = "分页查询已同步的企业微信用户列表。" -+ + "支持按姓名/手机号/职位关键词搜索,按部门ID和状态筛选。" -+ + "status取值:1=已激活 2=已禁用 4=未关注。" -+ + "用于管理员绑定企微账号时选择企微用户。" -+ + "需要管理员认证。" -+ + "\n\n**关联字典**:\n" -+ + "- wechat_user_status(企微用户状态):请求参数status和返回字段status(1=已激活, 2=已禁用, 4=未关注)") - @GetMapping("/users") - public Result> listWechatUsers( - @ApiParam("页码") @RequestParam(defaultValue = "1") Integer page, -@@ -58,21 +73,29 @@ public class WechatSyncController { - return Result.success(wechatSyncService.listWechatUsers(page, pageSize, keyword, deptId, status)); - } - -- @ApiOperation("部门列表(部门管理页面)") -+ @ApiOperation(value = "部门列表(部门管理页面)", -+ notes = "获取已同步的所有企业微信部门列表(平铺结构),用于部门管理页面展示。\n" -+ + "包含部门ID、名称、上级部门ID、排序等信息。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/departments") - public Result> listAllDepartments() { - List departments = wechatSyncService.listAllDepartments(); - return Result.success(departments); - } - -- @ApiOperation("部门树(下拉筛选)") -+ @ApiOperation(value = "部门树(下拉筛选)", notes = "以树形结构返回企业微信部门数据。" -+ + "用于部门筛选下拉框,每个节点包含id/label/children。" -+ + "需要管理员认证。") - @GetMapping("/departments/tree") - public Result>> listDepartmentsTree() { - List> tree = wechatSyncService.listDepartmentsTree(); - return Result.success(tree); - } - -- @ApiOperation("同步状态(最后同步时间)") -+ @ApiOperation(value = "同步状态(最后同步时间)", -+ notes = "获取企业微信数据的最后同步时间和状态。\n" -+ + "返回部门和用户各自的最后同步时间,用于管理页面展示同步状态。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/sync/status") - public Result> getSyncStatus() { - Map status = wechatSyncService.getSyncStatus(); -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/AdminLoginRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/AdminLoginRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/AdminLoginRequest.java -index 3dcbbb3..3bde0cd 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/AdminLoginRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/AdminLoginRequest.java -@@ -6,13 +6,15 @@ import lombok.Data; - import javax.validation.constraints.NotBlank; - - @Data --@ApiModel("管理员登录请求") -+@ApiModel(value = "管理员登录请求", description = "后台管理员通过用户名+密码登录,新设备首次登录需2FA验证") - public class AdminLoginRequest { -- @ApiModelProperty(value = "用户名", required = true, example = "admin") -+ @ApiModelProperty(value = "用户名", required = true, example = "admin", -+ notes = "管理员账号的用户名,由SUPER_ADMIN创建时指定") - @NotBlank(message = "用户名不能为空") - private String username; - -- @ApiModelProperty(value = "密码", required = true, example = "Admin@2026") -+ @ApiModelProperty(value = "密码", required = true, example = "Admin@2026", -+ notes = "须包含大小写字母和数字,长度8-128位。默认密码为Admin@123456") - @NotBlank(message = "密码不能为空") - private String password; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/ContactRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/ContactRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/ContactRequest.java -index 9c59721..160c8c7 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/ContactRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/ContactRequest.java -@@ -9,7 +9,7 @@ import javax.validation.constraints.NotBlank; - @Data - @ApiModel("联系我们请求") - public class ContactRequest { -- @ApiModelProperty(value = "渠道类型:ABOUT=关于我们 ONLINE_CS=在线客服 PHONE=电话咨询", required = true, example = "PHONE") -+ @ApiModelProperty(value = "渠道类型,关联字典contact_channel_type:ABOUT=关于我们, ONLINE_CS=在线客服, PHONE=电话咨询", required = true, example = "PHONE") - @NotBlank(message = "渠道类型不能为空") - private String channelType; - -@@ -32,6 +32,6 @@ public class ContactRequest { - @ApiModelProperty(value = "排序号(越小越靠前)", example = "1") - private Integer sortOrder; - -- @ApiModelProperty(value = "状态:0=下线 1=上线", example = "1") -+ @ApiModelProperty(value = "状态,关联字典common_status:0=下线, 1=上线", example = "1") - private Integer status; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/CreateAdminRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/CreateAdminRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/CreateAdminRequest.java -index 5d0ffe3..72f20fd 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/CreateAdminRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/CreateAdminRequest.java -@@ -7,17 +7,20 @@ import javax.validation.constraints.NotBlank; - import java.util.List; - - @Data --@ApiModel("创建管理员请求") -+@ApiModel(value = "创建管理员请求", description = "创建后台管理员账号,默认密码Admin@123456") - public class CreateAdminRequest { -- @ApiModelProperty(value = "用户名", required = true, example = "zhangsan") -+ @ApiModelProperty(value = "用户名", required = true, example = "zhangsan", -+ notes = "全局唯一的登录用户名,创建后不可修改") - @NotBlank(message = "用户名不能为空") - private String username; - - /** 角色ID列表(多角色),兼容旧的单角色 roleId */ -- @ApiModelProperty(value = "角色ID列表(多角色)", example = "[1,2]") -+ @ApiModelProperty(value = "角色ID列表(多角色)", example = "[1,2]", -+ notes = "支持分配多个角色,管理员登录后可通过切换角色接口切换当前活跃角色") - private List roleIds; - - /** @deprecated 兼容旧接口,优先使用 roleIds */ -- @ApiModelProperty(value = "角色ID(已废弃,请使用roleIds)", example = "1") -+ @ApiModelProperty(value = "角色ID(已废弃,请使用roleIds)", example = "1", -+ notes = "兼容旧接口的单角色参数,优先使用roleIds") - private Long roleId; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/CreateJobRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/CreateJobRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/CreateJobRequest.java -index dff93b6..5d8d05b 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/CreateJobRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/CreateJobRequest.java -@@ -12,18 +12,18 @@ public class CreateJobRequest { - @NotBlank(message = "任务名称不能为空") - private String jobName; - -- @ApiModelProperty(value = "任务分组", example = "SYSTEM") -+ @ApiModelProperty(value = "任务分组,字典类型:job_group(DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步)", example = "SYSTEM") - private String jobGroup; - -- @ApiModelProperty(value = "调用目标(Bean名称.方法名)", required = true, example = "wechatSyncService.syncDepartments") -+ @ApiModelProperty(value = "调用目标(Bean名称.方法名),方法必须是无参公开方法", required = true, example = "wechatSyncService.syncDepartments") - @NotBlank(message = "调用目标不能为空") - private String invokeTarget; - -- @ApiModelProperty(value = "Cron表达式", required = true, example = "0 0 2 * * ?") -+ @ApiModelProperty(value = "Cron表达式,标准6位(秒 分 时 日 月 周)", required = true, example = "0 0 2 * * ?") - @NotBlank(message = "Cron表达式不能为空") - private String cronExpression; - -- @ApiModelProperty(value = "计划执行策略:0=默认 1=立即触发 2=触发一次 3=不触发", example = "0") -+ @ApiModelProperty(value = "计划执行策略,字典类型:job_misfire_policy(DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发)", example = "DEFAULT") - private String misfirePolicy; - - @ApiModelProperty(value = "是否允许并发执行", example = "false") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/FavoriteRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/FavoriteRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/FavoriteRequest.java -index cbb0455..b7b4fbb 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/FavoriteRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/FavoriteRequest.java -@@ -7,13 +7,15 @@ import javax.validation.constraints.NotBlank; - import javax.validation.constraints.NotNull; - - @Data --@ApiModel("收藏请求") -+@ApiModel(value = "收藏请求", description = "添加收藏时的请求体,指定收藏的资源类型和ID") - public class FavoriteRequest { -- @ApiModelProperty(value = "收藏类型", required = true, example = "SCENIC_SPOT") -+ @ApiModelProperty(value = "收藏类型,关联字典favorite_resource_type", required = true, example = "SCENIC_SPOT", -+ notes = "可选值:SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品, EXPLORE=探索分类") - @NotBlank(message = "目标类型不能为空") - private String targetType; - -- @ApiModelProperty(value = "收藏目标ID", required = true, example = "1") -+ @ApiModelProperty(value = "收藏目标ID", required = true, example = "1", -+ notes = "对应资源的ID,如景区ID、活动ID等") - @NotNull(message = "目标ID不能为空") - private Long targetId; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/FootprintRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/FootprintRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/FootprintRequest.java -index 6a9905c..a700a4d 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/FootprintRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/FootprintRequest.java -@@ -7,13 +7,15 @@ import javax.validation.constraints.NotBlank; - import javax.validation.constraints.NotNull; - - @Data --@ApiModel("足迹请求") -+@ApiModel(value = "足迹请求", description = "记录用户浏览足迹时的请求体") - public class FootprintRequest { -- @ApiModelProperty(value = "资源类型", required = true, example = "SCENIC_SPOT") -+ @ApiModelProperty(value = "资源类型,关联字典footprint_resource_type", required = true, example = "SCENIC_SPOT", -+ notes = "可选值:SCENIC_SPOT=景区, ACTIVITY=活动, HOTEL=酒店, PRODUCT=产品") - @NotBlank(message = "资源类型不能为空") - private String resourceType; - -- @ApiModelProperty(value = "资源ID", required = true, example = "1") -+ @ApiModelProperty(value = "资源ID", required = true, example = "1", -+ notes = "对应资源的ID,同一用户同一资源只保留最新一条足迹") - @NotNull(message = "资源ID不能为空") - private Long resourceId; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/LoginRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/LoginRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/LoginRequest.java -index e8ff874..bdc2f40 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/LoginRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/LoginRequest.java -@@ -6,18 +6,22 @@ import lombok.Data; - import javax.validation.constraints.NotBlank; - - @Data --@ApiModel("微信小程序登录请求") -+@ApiModel(value = "微信小程序登录请求", description = "通过wx.login获取code进行登录,首次登录自动注册") - public class LoginRequest { -- @ApiModelProperty(value = "微信登录授权码", required = true, example = "0c3NKj000...") -+ @ApiModelProperty(value = "微信登录授权码", required = true, example = "0c3NKj000...", -+ notes = "通过wx.login()获取的临时授权码,后端用此code换取openid/unionid") - @NotBlank(message = "微信code不能为空") - private String code; - -- @ApiModelProperty(value = "手机号授权码(用于获取手机号)", example = "0c3NKj000...") -+ @ApiModelProperty(value = "手机号授权码(用于获取手机号)", example = "0c3NKj000...", -+ notes = "通过getPhoneNumber按钮获取的code,后端用此code换取用户手机号并绑定") - private String phoneCode; - -- @ApiModelProperty(value = "用户头像URL", example = "https://thirdwx.qlogo.cn/xxx") -+ @ApiModelProperty(value = "用户头像URL", example = "https://thirdwx.qlogo.cn/xxx", -+ notes = "微信头像地址,首次登录时传入用于设置用户头像") - private String avatar; - -- @ApiModelProperty(value = "用户昵称", example = "微信用户") -+ @ApiModelProperty(value = "用户昵称", example = "微信用户", -+ notes = "微信昵称,首次登录时传入用于设置用户昵称") - private String nickname; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/SwitchRoleRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/SwitchRoleRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/SwitchRoleRequest.java -index 48d700d..945424d 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/SwitchRoleRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/SwitchRoleRequest.java -@@ -7,10 +7,11 @@ import lombok.Data; - import javax.validation.constraints.NotNull; - - @Data --@ApiModel("角色切换请求") -+@ApiModel(value = "角色切换请求", description = "多角色管理员切换当前活跃角色") - public class SwitchRoleRequest { - - @NotNull(message = "角色ID不能为空") -- @ApiModelProperty(value = "目标角色ID", required = true) -+ @ApiModelProperty(value = "目标角色ID", required = true, -+ notes = "只能切换到当前管理员已分配的角色,切换后返回新Token和对应菜单权限") - private Long roleId; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/TravelerRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/TravelerRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/TravelerRequest.java -index f8d33c8..1c67bb6 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/TravelerRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/TravelerRequest.java -@@ -15,10 +15,10 @@ public class TravelerRequest { - @Size(max = 50, message = "姓名长度不能超过50个字符") - private String name; - -- @ApiModelProperty(value = "出行人类型(无需传入,后端根据出生日期自动判断)", hidden = true) -+ @ApiModelProperty(value = "出行人类型,关联字典traveler_type:ADULT=成人, CHILD=儿童, INFANT=婴儿(无需传入,后端根据birthday自动判断)", hidden = true) - private String travelerType; // auto-resolved from birthday - -- @ApiModelProperty(value = "证件类型:ID_CARD=身份证 PASSPORT=护照", example = "ID_CARD") -+ @ApiModelProperty(value = "证件类型,关联字典id_card_type:ID_CARD=身份证, PASSPORT=护照", example = "ID_CARD") - private String idCardType; // Default: ID_CARD - - @ApiModelProperty(value = "证件号码", example = "110101199001011234") -@@ -29,7 +29,7 @@ public class TravelerRequest { - @Size(max = 20, message = "手机号长度不能超过20个字符") - private String phone; - -- @ApiModelProperty(value = "性别:0=女 1=男", example = "1") -+ @ApiModelProperty(value = "性别,关联字典gender:0=女, 1=男", example = "1") - private Integer gender; // 0=female, 1=male - - @ApiModelProperty(value = "出生日期(必填,后端根据此字段自动判断人员类型)", required = true, example = "1990-01-01") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/UpdateAvatarRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateAvatarRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateAvatarRequest.java -index 273a9bc..1e4c1f4 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateAvatarRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateAvatarRequest.java -@@ -7,13 +7,15 @@ import lombok.Data; - import javax.validation.constraints.NotBlank; - - @Data --@ApiModel("头像更新请求") -+@ApiModel(value = "头像更新请求", description = "更新管理员头像,需先通过文件服务上传图片") - public class UpdateAvatarRequest { - - @NotBlank(message = "头像URL不能为空") -- @ApiModelProperty(value = "头像URL", required = true) -+ @ApiModelProperty(value = "头像URL", required = true, -+ notes = "文件服务返回的OSS URL地址") - private String avatar; - -- @ApiModelProperty("文件ID") -+ @ApiModelProperty(value = "文件ID", -+ notes = "文件服务返回的fileId,用于建立文件引用关系,传入后旧头像引用自动解绑") - private Long fileId; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/dto/UpdateJobRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateJobRequest.java b/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateJobRequest.java -index a42399c..4e85a2a 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateJobRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/dto/UpdateJobRequest.java -@@ -10,16 +10,16 @@ public class UpdateJobRequest { - @ApiModelProperty(value = "任务名称", example = "同步企微通讯录") - private String jobName; - -- @ApiModelProperty(value = "任务分组", example = "SYSTEM") -+ @ApiModelProperty(value = "任务分组,字典类型:job_group(DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步)", example = "SYSTEM") - private String jobGroup; - -- @ApiModelProperty(value = "调用目标(Bean名称.方法名)", example = "wechatSyncService.syncDepartments") -+ @ApiModelProperty(value = "调用目标(Bean名称.方法名),方法必须是无参公开方法", example = "wechatSyncService.syncDepartments") - private String invokeTarget; - -- @ApiModelProperty(value = "Cron表达式", example = "0 0 2 * * ?") -+ @ApiModelProperty(value = "Cron表达式,标准6位(秒 分 时 日 月 周)", example = "0 0 2 * * ?") - private String cronExpression; - -- @ApiModelProperty(value = "计划执行策略:0=默认 1=立即触发 2=触发一次 3=不触发", example = "0") -+ @ApiModelProperty(value = "计划执行策略,字典类型:job_misfire_policy(DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发)", example = "DEFAULT") - private String misfirePolicy; - - @ApiModelProperty(value = "是否允许并发执行", example = "false") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/controller/AdminNotificationController.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/controller/AdminNotificationController.java b/hl-user-service/src/main/java/com/hulalv/user/notification/controller/AdminNotificationController.java -index d2b7b8d..aa20c4b 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/controller/AdminNotificationController.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/controller/AdminNotificationController.java -@@ -45,7 +45,10 @@ public class AdminNotificationController { - - // ==================== 事件配置 ==================== - -- @ApiOperation("获取通知配置列表(按分类分组)") -+ @ApiOperation(value = "获取通知配置列表(按分类分组)", notes = "获取所有通知事件配置,按消息分类(categoryCode)分组返回。" -+ + "每个事件配置包含各通知渠道的开关状态(smsEnabled/inappEnabled/weworkEnabled等)。" -+ + "\n\n**关联字典**:\n" -+ + "- notification_channel(通知渠道):sms=短信, inapp=站内信, wework=企业微信, miniapp_subscribe=小程序订阅消息, official_account=公众号模板消息\n") - @GetMapping("/config") - public Result>> listConfigs() { - Map> grouped = configService.listGroupedByCategory(); -@@ -66,7 +69,9 @@ public class AdminNotificationController { - return Result.success(result); - } - -- @ApiOperation("切换通道开关") -+ @ApiOperation(value = "切换通道开关", notes = "切换指定通知事件的某个渠道开关。" -+ + "channel取值:sms/inapp/wework/miniapp_subscribe/official_account。" -+ + "注意:只允许开启渠道,不建议关闭已有渠道。") - @PutMapping("/config/{id}/toggle") - public Result toggleChannel(@PathVariable Long id, - @Valid @RequestBody ChannelToggleRequest request) { -@@ -74,7 +79,10 @@ public class AdminNotificationController { - return Result.success(); - } - -- @ApiOperation("编辑事件配置详情") -+ @ApiOperation(value = "编辑事件配置详情", -+ notes = "更新指定通知事件配置的详细信息,包括模板内容、接收人规则等。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:修改模板内容后会立即影响后续的通知发送。") - @PutMapping("/config/{id}") - public Result updateConfig(@PathVariable Long id, - @Valid @RequestBody EventConfigUpdateRequest request) { -@@ -84,7 +92,11 @@ public class AdminNotificationController { - return Result.success(); - } - -- @ApiOperation("测试发送") -+ @ApiOperation(value = "测试发送", -+ notes = "使用测试数据触发一次通知发送,验证通知配置是否正确。\n" -+ + "会使用预设的测试参数(订单号、产品名等)填充模板。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:需指定 testUserId 或 testAdminId 作为接收人,发送结果可在发送日志中查看。") - @PostMapping("/config/{id}/test") - public Result testSend(@PathVariable Long id, - @Valid @RequestBody TestSendRequest request) { -@@ -125,7 +137,10 @@ public class AdminNotificationController { - - // ==================== 消息分类 ==================== - -- @ApiOperation("获取消息分类列表") -+ @ApiOperation(value = "获取消息分类列表", -+ notes = "获取所有通知消息分类,包括分类编码、名称、图标、描述等。\n" -+ + "消息分类用于将通知事件归组管理(如订单消息、系统消息等)。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/categories") - public Result> listCategories() { - List categories = categoryService.listAll(); -@@ -135,7 +150,10 @@ public class AdminNotificationController { - return Result.success(voList); - } - -- @ApiOperation("创建消息分类") -+ @ApiOperation(value = "创建消息分类", -+ notes = "创建新的通知消息分类,用于归组管理通知事件。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:分类编码(code)必须唯一,创建后不可修改。") - @PostMapping("/categories") - public Result createCategory(@Valid @RequestBody CategoryRequest request) { - MessageCategory category = new MessageCategory(); -@@ -148,7 +166,10 @@ public class AdminNotificationController { - return Result.success(); - } - -- @ApiOperation("更新消息分类") -+ @ApiOperation(value = "更新消息分类", -+ notes = "更新指定消息分类的名称、图标、描述、排序等信息。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:分类编码(code)不可修改。") - @PutMapping("/categories/{id}") - public Result updateCategory(@PathVariable Long id, - @Valid @RequestBody CategoryRequest request) { -@@ -161,7 +182,10 @@ public class AdminNotificationController { - return Result.success(); - } - -- @ApiOperation("删除消息分类") -+ @ApiOperation(value = "删除消息分类", -+ notes = "删除指定的消息分类。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:如果该分类下有关联的通知事件配置,需先移除关联后才能删除。") - @DeleteMapping("/categories/{id}") - public Result deleteCategory(@PathVariable Long id) { - categoryService.delete(id); -@@ -170,13 +194,18 @@ public class AdminNotificationController { - - // ==================== 发送日志 ==================== - -- @ApiOperation("查询发送日志") -+ @ApiOperation(value = "查询发送日志", notes = "分页查询通知发送日志,支持按事件编码、渠道、状态等筛选。" -+ + "\n\n**关联字典**:\n" -+ + "- notification_channel(通知渠道):返回字段channel\n" -+ + "- notification_send_status(发送状态):返回字段status(SUCCESS=成功, FAILED=失败, SKIPPED=跳过)\n") - @GetMapping("/logs") - public Result> queryLogs(LogQueryRequest request) { - return Result.success(sendLogService.queryLogs(request)); - } - -- @ApiOperation("获取发送统计") -+ @ApiOperation(value = "获取发送统计", -+ notes = "获取通知发送的统计数据,包括总发送数、成功数、失败数、各渠道发送量等。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/logs/stats") - public Result getLogStats() { - return Result.success(sendLogService.getStats()); -@@ -184,7 +213,11 @@ public class AdminNotificationController { - - // ==================== 自定义推送 ==================== - -- @ApiOperation("自定义推送") -+ @ApiOperation(value = "自定义推送", -+ notes = "向指定用户发送自定义通知消息,支持选择推送渠道和目标用户。\n" -+ + "用于运营人员手动推送活动通知、系统公告等。\n\n" -+ + "**权限**:需要管理员登录。\n" -+ + "**注意**:推送记录会记入发送日志。") - @PostMapping("/custom-push") - public Result customPush(@Valid @RequestBody CustomPushRequest request, - HttpServletRequest httpRequest) { -@@ -193,7 +226,10 @@ public class AdminNotificationController { - return Result.success(result); - } - -- @ApiOperation("搜索用户(自定义推送选择目标)") -+ @ApiOperation(value = "搜索用户(自定义推送选择目标)", -+ notes = "按关键词搜索C端用户,用于自定义推送时选择推送目标。\n" -+ + "支持按真实姓名或手机号模糊搜索,最多返回20条结果。\n\n" -+ + "**权限**:需要管理员登录。") - @GetMapping("/custom-push/users") - public Result> searchUsersForPush(@RequestParam(required = false) String keyword) { - LambdaQueryWrapper wrapper = new LambdaQueryWrapper() -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/dto/CustomPushRequest.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/dto/CustomPushRequest.java b/hl-user-service/src/main/java/com/hulalv/user/notification/dto/CustomPushRequest.java -index 228bb27..2a3ee4f 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/dto/CustomPushRequest.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/dto/CustomPushRequest.java -@@ -1,5 +1,7 @@ - package com.hulalv.user.notification.dto; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - import javax.validation.constraints.NotBlank; -@@ -10,28 +12,31 @@ import java.util.List; - * 自定义推送请求 - */ - @Data -+@ApiModel("自定义推送请求") - public class CustomPushRequest { - -+ @ApiModelProperty("推送标题") - @NotBlank(message = "推送标题不能为空") - private String title; - -+ @ApiModelProperty("推送内容") - @NotBlank(message = "推送内容不能为空") - private String content; - -- /** 推送通道: INAPP, SMS, WECHAT_WORK */ -+ @ApiModelProperty("推送通道: INAPP/SMS/WECHAT_WORK") - @NotNull(message = "请选择推送通道") - private String channel; - -- /** 目标类型: ALL_USERS, SPECIFIC_USERS */ -+ @ApiModelProperty("目标类型: ALL_USERS/SPECIFIC_USERS") - @NotNull(message = "请选择目标类型") - private String targetType; - -- /** targetType=SPECIFIC_USERS时必填 */ -+ @ApiModelProperty("目标用户ID列表(目标类型为SPECIFIC_USERS时必填)") - private List userIds; - -- /** 消息分类编码,默认SYSTEM */ -+ @ApiModelProperty("消息分类编码,默认SYSTEM") - private String categoryCode; - -- /** 跳转链接(站内信时使用) */ -+ @ApiModelProperty("跳转链接(站内信时使用)") - private String link; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/vo/CustomPushResultVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/CustomPushResultVO.java b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/CustomPushResultVO.java -index e3cdaf2..495cb3d 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/CustomPushResultVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/CustomPushResultVO.java -@@ -1,19 +1,22 @@ - package com.hulalv.user.notification.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - /** - * 自定义推送结果 - */ - @Data -+@ApiModel("自定义推送结果VO") - public class CustomPushResultVO { - -- /** 推送总数 */ -+ @ApiModelProperty("推送总数") - private int totalCount; - -- /** 成功数 */ -+ @ApiModelProperty("成功数") - private int successCount; - -- /** 失败数 */ -+ @ApiModelProperty("失败数") - private int failCount; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/vo/EventConfigVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/EventConfigVO.java b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/EventConfigVO.java -index 8b7e7d1..7434992 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/EventConfigVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/EventConfigVO.java -@@ -21,7 +21,7 @@ public class EventConfigVO { - @ApiModelProperty("所属分类名称") - private String categoryName; - -- @ApiModelProperty("站内信开关") -+ @ApiModelProperty("站内信开关(0=关闭, 1=开启)") - private Integer inappEnabled; - - @ApiModelProperty("站内信标题模板") -@@ -33,7 +33,7 @@ public class EventConfigVO { - @ApiModelProperty("站内信跳转路径模板") - private String inappLinkTemplate; - -- @ApiModelProperty("短信开关") -+ @ApiModelProperty("短信开关(0=关闭, 1=开启)") - private Integer smsEnabled; - - @ApiModelProperty("阿里云短信模板编号") -@@ -42,7 +42,7 @@ public class EventConfigVO { - @ApiModelProperty("短信签名") - private String smsSignName; - -- @ApiModelProperty("小程序订阅消息开关") -+ @ApiModelProperty("小程序订阅消息开关(0=关闭, 1=开启)") - private Integer miniappEnabled; - - @ApiModelProperty("微信订阅消息模板ID") -@@ -54,7 +54,7 @@ public class EventConfigVO { - @ApiModelProperty("小程序字段映射JSON") - private String miniappFieldMapping; - -- @ApiModelProperty("公众号模板消息开关") -+ @ApiModelProperty("公众号模板消息开关(0=关闭, 1=开启)") - private Integer oaEnabled; - - @ApiModelProperty("公众号模板ID") -@@ -66,10 +66,10 @@ public class EventConfigVO { - @ApiModelProperty("公众号字段映射JSON") - private String oaFieldMapping; - -- @ApiModelProperty("企微通知开关") -+ @ApiModelProperty("企微通知开关(0=关闭, 1=开启)") - private Integer weworkEnabled; - -- @ApiModelProperty("企微接收人类型") -+ @ApiModelProperty("企微接收人类型(ROLE=按角色, DEPT=按部门, SPECIFIC=指定人员)") - private String weworkReceiverType; - - @ApiModelProperty("企微消息内容模板") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/vo/SendLogVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/SendLogVO.java b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/SendLogVO.java -index 8e44260..52c307c 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/SendLogVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/SendLogVO.java -@@ -14,7 +14,7 @@ public class SendLogVO { - @ApiModelProperty("事件编码") - private String eventCode; - -- @ApiModelProperty("通道: INAPP/SMS/MINIAPP/OA/WEWORK") -+ @ApiModelProperty("通道,关联字典notification_channel:INAPP=站内信, SMS=短信, MINIAPP=小程序订阅, OA=公众号模板, WEWORK=企业微信") - private String channel; - - @ApiModelProperty("用户ID") -@@ -38,7 +38,7 @@ public class SendLogVO { - @ApiModelProperty("关联业务类型") - private String bizType; - -- @ApiModelProperty("发送状态: 0成功 1失败 2跳过") -+ @ApiModelProperty("发送状态,关联字典notification_send_status:0=成功, 1=失败, 2=跳过") - private Integer status; - - @ApiModelProperty("失败原因") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/notification/vo/UserSimpleVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/UserSimpleVO.java b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/UserSimpleVO.java -index 448b5df..9ad4b62 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/notification/vo/UserSimpleVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/notification/vo/UserSimpleVO.java -@@ -1,18 +1,25 @@ - package com.hulalv.user.notification.vo; - -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; - import lombok.Data; - - /** - * 用户简要信息(自定义推送选择目标用户时使用) - */ - @Data -+@ApiModel("用户简要信息VO") - public class UserSimpleVO { - -+ @ApiModelProperty("用户ID") - private Long id; - -+ @ApiModelProperty("真实姓名") - private String realName; - -+ @ApiModelProperty("手机号") - private String phone; - -+ @ApiModelProperty("头像URL") - private String avatarUrl; - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/service/SysJobService.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/service/SysJobService.java b/hl-user-service/src/main/java/com/hulalv/user/service/SysJobService.java -index a969c76..3572ae2 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/service/SysJobService.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/service/SysJobService.java -@@ -13,12 +13,17 @@ import com.hulalv.user.entity.SysJob; - import com.hulalv.user.entity.SysJobLog; - import com.hulalv.user.mapper.SysJobLogMapper; - import com.hulalv.user.mapper.SysJobMapper; -+import com.hulalv.user.vo.SysJobLogVO; -+import com.hulalv.user.vo.SysJobVO; - import lombok.RequiredArgsConstructor; - import lombok.extern.slf4j.Slf4j; - import org.quartz.*; -+import org.springframework.beans.BeanUtils; - import org.springframework.stereotype.Service; - import org.springframework.transaction.annotation.Transactional; - -+import java.util.stream.Collectors; -+ - @Slf4j - @Service - @RequiredArgsConstructor -@@ -28,7 +33,7 @@ public class SysJobService extends ServiceImpl { - private final Scheduler scheduler; - - @Transactional -- public SysJob createJob(CreateJobRequest request) { -+ public SysJobVO createJob(CreateJobRequest request) { - SysJob job = new SysJob(); - job.setJobName(request.getJobName()); - job.setJobGroup(request.getJobGroup() != null ? request.getJobGroup() : "DEFAULT"); -@@ -41,11 +46,11 @@ public class SysJobService extends ServiceImpl { - save(job); - - log.info("Job created: name={}, target={}", job.getJobName(), job.getInvokeTarget()); -- return job; -+ return toVO(job); - } - - @Transactional -- public SysJob updateJob(Long jobId, UpdateJobRequest request) { -+ public SysJobVO updateJob(Long jobId, UpdateJobRequest request) { - SysJob job = getById(jobId); - if (job == null) { - throw new NotFoundException("定时任务不存在"); -@@ -68,7 +73,7 @@ public class SysJobService extends ServiceImpl { - createSchedulerJob(job); - } - -- return job; -+ return toVO(job); - } - - @Transactional -@@ -136,23 +141,27 @@ public class SysJobService extends ServiceImpl { - } - } - -- public PageResult listJobs(int page, int pageSize) { -+ public PageResult listJobs(int page, int pageSize) { - Page pageParam = PageUtil.safePage(page, pageSize); - LambdaQueryWrapper wrapper = new LambdaQueryWrapper() - .orderByDesc(SysJob::getCreatedAt) - .orderByDesc(SysJob::getJobId); - Page result = page(pageParam, wrapper); -- return PageResult.of(result.getRecords(), result.getTotal(), page, pageSize); -+ return PageResult.of( -+ result.getRecords().stream().map(this::toVO).collect(Collectors.toList()), -+ result.getTotal(), page, pageSize); - } - -- public PageResult listJobLogs(Long jobId, int page, int pageSize) { -+ public PageResult listJobLogs(Long jobId, int page, int pageSize) { - Page pageParam = PageUtil.safePage(page, pageSize); - LambdaQueryWrapper wrapper = new LambdaQueryWrapper() - .eq(SysJobLog::getJobId, jobId) - .orderByDesc(SysJobLog::getStartTime) - .orderByDesc(SysJobLog::getJobLogId); - Page result = jobLogMapper.selectPage(pageParam, wrapper); -- return PageResult.of(result.getRecords(), result.getTotal(), page, pageSize); -+ return PageResult.of( -+ result.getRecords().stream().map(this::toLogVO).collect(Collectors.toList()), -+ result.getTotal(), page, pageSize); - } - - void createSchedulerJob(SysJob job) { -@@ -199,4 +208,16 @@ public class SysJobService extends ServiceImpl { - log.error("Failed to remove scheduler job: jobId={}", job.getJobId(), e); - } - } -+ -+ private SysJobVO toVO(SysJob job) { -+ SysJobVO vo = new SysJobVO(); -+ BeanUtils.copyProperties(job, vo); -+ return vo; -+ } -+ -+ private SysJobLogVO toLogVO(SysJobLog jobLog) { -+ SysJobLogVO vo = new SysJobLogVO(); -+ BeanUtils.copyProperties(jobLog, vo); -+ return vo; -+ } - } -``` - -### `hl-user-service/src/main/java/com/hulalv/user/vo/ContactVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/vo/ContactVO.java b/hl-user-service/src/main/java/com/hulalv/user/vo/ContactVO.java -index 8bd3d9d..53a203c 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/vo/ContactVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/vo/ContactVO.java -@@ -14,7 +14,7 @@ public class ContactVO { - @ApiModelProperty(value = "联系方式ID") - private String id; - -- @ApiModelProperty(value = "渠道类型:ABOUT=关于我们 ONLINE_CS=在线客服 PHONE=电话咨询") -+ @ApiModelProperty(value = "渠道类型,关联字典contact_channel_type:ABOUT=关于我们, ONLINE_CS=在线客服, PHONE=电话咨询") - private String channelType; - - @ApiModelProperty(value = "标题") -@@ -35,7 +35,7 @@ public class ContactVO { - @ApiModelProperty(value = "排序号") - private Integer sortOrder; - -- @ApiModelProperty(value = "状态:0=下线 1=上线") -+ @ApiModelProperty(value = "状态,关联字典common_status:0=下线, 1=上线") - private Integer status; - - @ApiModelProperty(value = "创建时间") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/vo/CustomerVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/vo/CustomerVO.java b/hl-user-service/src/main/java/com/hulalv/user/vo/CustomerVO.java -index d72a7b3..be9f83a 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/vo/CustomerVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/vo/CustomerVO.java -@@ -26,7 +26,7 @@ public class CustomerVO { - @ApiModelProperty(value = "手机号(不脱敏)") - private String phone; - -- @ApiModelProperty(value = "状态:ACTIVE=正常 DISABLED=禁用") -+ @ApiModelProperty(value = "状态,关联字典user_status:ACTIVE=正常, BANNED=已封禁") - private String status; - - @ApiModelProperty(value = "创建时间") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/vo/LoginLogVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/vo/LoginLogVO.java b/hl-user-service/src/main/java/com/hulalv/user/vo/LoginLogVO.java -index 89620fe..3582c3d 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/vo/LoginLogVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/vo/LoginLogVO.java -@@ -18,7 +18,7 @@ public class LoginLogVO { - @ApiModelProperty(value = "管理员名称") - private String adminName; - -- @ApiModelProperty(value = "登录方式:PASSWORD=密码 WECHAT=企微扫码 TWO_FA=二次验证") -+ @ApiModelProperty(value = "登录方式,关联字典login_method:PASSWORD=密码登录, WECHAT_QR=企微扫码登录, TWO_FA=二次验证登录") - private String loginMethod; - - @ApiModelProperty(value = "登录IP地址") -@@ -36,7 +36,7 @@ public class LoginLogVO { - @ApiModelProperty(value = "登录地区") - private String location; - -- @ApiModelProperty(value = "登录状态:SUCCESS=成功 FAILED=失败") -+ @ApiModelProperty(value = "登录状态,关联字典login_status:SUCCESS=成功, FAILED=失败") - private String status; - - @ApiModelProperty(value = "失败原因") -``` - -### `hl-user-service/src/main/java/com/hulalv/user/vo/SysJobLogVO.java` (A) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/vo/SysJobLogVO.java b/hl-user-service/src/main/java/com/hulalv/user/vo/SysJobLogVO.java -new file mode 100644 -index 0000000..3f031c1 ---- /dev/null -+++ b/hl-user-service/src/main/java/com/hulalv/user/vo/SysJobLogVO.java -@@ -0,0 +1,37 @@ -+package com.hulalv.user.vo; -+ -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; -+import lombok.Data; -+import java.time.LocalDateTime; -+ -+@Data -+@ApiModel("定时任务执行日志") -+public class SysJobLogVO { -+ @ApiModelProperty("日志ID") -+ private Long jobLogId; -+ -+ @ApiModelProperty("任务ID") -+ private Long jobId; -+ -+ @ApiModelProperty("任务名称") -+ private String jobName; -+ -+ @ApiModelProperty("调用目标") -+ private String invokeTarget; -+ -+ @ApiModelProperty(value = "执行状态", notes = "字典类型:job_log_status。可选值:SUCCESS=成功, FAIL=失败") -+ private String status; -+ -+ @ApiModelProperty("执行结果/异常信息") -+ private String message; -+ -+ @ApiModelProperty("开始时间") -+ private LocalDateTime startTime; -+ -+ @ApiModelProperty("结束时间") -+ private LocalDateTime endTime; -+ -+ @ApiModelProperty("创建时间") -+ private LocalDateTime createdAt; -+} -``` - -### `hl-user-service/src/main/java/com/hulalv/user/vo/SysJobVO.java` (A) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/vo/SysJobVO.java b/hl-user-service/src/main/java/com/hulalv/user/vo/SysJobVO.java -new file mode 100644 -index 0000000..1e84456 ---- /dev/null -+++ b/hl-user-service/src/main/java/com/hulalv/user/vo/SysJobVO.java -@@ -0,0 +1,43 @@ -+package com.hulalv.user.vo; -+ -+import io.swagger.annotations.ApiModel; -+import io.swagger.annotations.ApiModelProperty; -+import lombok.Data; -+import java.time.LocalDateTime; -+ -+@Data -+@ApiModel("定时任务信息") -+public class SysJobVO { -+ @ApiModelProperty("任务ID") -+ private Long jobId; -+ -+ @ApiModelProperty("任务名称") -+ private String jobName; -+ -+ @ApiModelProperty(value = "任务分组", notes = "字典类型:job_group。可选值:DEFAULT=默认分组, SYSTEM=系统任务, WECHAT=企微同步, INSURANCE=保险同步") -+ private String jobGroup; -+ -+ @ApiModelProperty("调用目标(Bean名称.方法名)") -+ private String invokeTarget; -+ -+ @ApiModelProperty("Cron表达式") -+ private String cronExpression; -+ -+ @ApiModelProperty(value = "计划执行策略", notes = "字典类型:job_misfire_policy。可选值:DEFAULT=默认策略, FIRE_ONCE=立即触发一次, DO_NOTHING=不触发") -+ private String misfirePolicy; -+ -+ @ApiModelProperty("是否允许并发执行") -+ private Boolean concurrent; -+ -+ @ApiModelProperty(value = "任务状态", notes = "字典类型:job_status。可选值:ACTIVE=启用, PAUSED=已暂停") -+ private String status; -+ -+ @ApiModelProperty("备注") -+ private String remark; -+ -+ @ApiModelProperty("创建时间") -+ private LocalDateTime createdAt; -+ -+ @ApiModelProperty("更新时间") -+ private LocalDateTime updatedAt; -+} -``` - -### `hl-user-service/src/main/java/com/hulalv/user/vo/UserVO.java` (M) - -```diff -diff --git a/hl-user-service/src/main/java/com/hulalv/user/vo/UserVO.java b/hl-user-service/src/main/java/com/hulalv/user/vo/UserVO.java -index cb64d33..bbc0ede 100644 ---- a/hl-user-service/src/main/java/com/hulalv/user/vo/UserVO.java -+++ b/hl-user-service/src/main/java/com/hulalv/user/vo/UserVO.java -@@ -29,20 +29,20 @@ public class UserVO { - @ApiModelProperty(value = "真实手机号(仅内部接口返回,用于订单预填)", hidden = true) - private String rawPhone; // 真实手机号(仅内部接口返回,用于订单预填) - -- @ApiModelProperty(value = "状态:ACTIVE=正常 DISABLED=禁用") -+ @ApiModelProperty(value = "状态,关联字典user_status:ACTIVE=正常, BANNED=已封禁") - private String status; - - // 个人信息字段(用于编辑"本人"出行人信息) - @ApiModelProperty(value = "真实姓名") - private String realName; - -- @ApiModelProperty(value = "证件类型:ID_CARD=身份证 PASSPORT=护照") -+ @ApiModelProperty(value = "证件类型,关联字典id_card_type:ID_CARD=身份证, PASSPORT=护照") - private String idCardType; - - @ApiModelProperty(value = "证件号码") - private String idCardNo; - -- @ApiModelProperty(value = "性别:0=女 1=男") -+ @ApiModelProperty(value = "性别,关联字典gender:0=女, 1=男") - private Integer gender; - - @ApiModelProperty(value = "出生日期") -``` - -### `hl-user-service/src/test/java/com/hulalv/user/service/SysJobServiceTest.java` (M) - -```diff -diff --git a/hl-user-service/src/test/java/com/hulalv/user/service/SysJobServiceTest.java b/hl-user-service/src/test/java/com/hulalv/user/service/SysJobServiceTest.java -index 64d284e..853dcd1 100644 ---- a/hl-user-service/src/test/java/com/hulalv/user/service/SysJobServiceTest.java -+++ b/hl-user-service/src/test/java/com/hulalv/user/service/SysJobServiceTest.java -@@ -10,6 +10,8 @@ import com.hulalv.user.dto.UpdateJobRequest; - import com.hulalv.user.entity.SysJob; - import com.hulalv.user.entity.SysJobLog; - import com.hulalv.user.mapper.SysJobLogMapper; -+import com.hulalv.user.vo.SysJobLogVO; -+import com.hulalv.user.vo.SysJobVO; - import org.junit.jupiter.api.BeforeEach; - import org.junit.jupiter.api.Test; - import org.junit.jupiter.api.extension.ExtendWith; -@@ -60,7 +62,7 @@ class SysJobServiceTest { - - doReturn(true).when(sysJobService).save(any(SysJob.class)); - -- SysJob result = sysJobService.createJob(request); -+ SysJobVO result = sysJobService.createJob(request); - - assertNotNull(result); - assertEquals("新任务", result.getJobName()); -@@ -82,7 +84,7 @@ class SysJobServiceTest { - - doReturn(true).when(sysJobService).save(any(SysJob.class)); - -- SysJob result = sysJobService.createJob(request); -+ SysJobVO result = sysJobService.createJob(request); - - assertEquals("SYSTEM", result.getJobGroup()); - assertEquals("FIRE_ONCE", result.getMisfirePolicy()); -@@ -99,7 +101,7 @@ class SysJobServiceTest { - doReturn(testJob).when(sysJobService).getById(3001L); - doReturn(true).when(sysJobService).updateById(any(SysJob.class)); - -- SysJob result = sysJobService.updateJob(3001L, request); -+ SysJobVO result = sysJobService.updateJob(3001L, request); - - assertEquals("更新任务名", result.getJobName()); - assertEquals("0 0/10 * * * ?", result.getCronExpression()); -@@ -121,7 +123,7 @@ class SysJobServiceTest { - when(scheduler.deleteJob(jobKey)).thenReturn(true); - when(scheduler.scheduleJob(any(JobDetail.class), any(Trigger.class))).thenReturn(null); - -- SysJob result = sysJobService.updateJob(3001L, request); -+ SysJobVO result = sysJobService.updateJob(3001L, request); - - assertNotNull(result); - verify(scheduler).deleteJob(jobKey); -@@ -248,10 +250,11 @@ class SysJobServiceTest { - - doReturn(mockPage).when(sysJobService).page(any(Page.class), any()); - -- PageResult result = sysJobService.listJobs(1, 10); -+ PageResult result = sysJobService.listJobs(1, 10); - - assertNotNull(result); - assertEquals(1, result.getRecords().size()); -+ assertInstanceOf(SysJobVO.class, result.getRecords().get(0)); - } - - @Test -@@ -268,9 +271,10 @@ class SysJobServiceTest { - when(jobLogMapper.selectPage(any(Page.class), any(LambdaQueryWrapper.class))) - .thenReturn(mockPage); - -- PageResult result = sysJobService.listJobLogs(3001L, 1, 10); -+ PageResult result = sysJobService.listJobLogs(3001L, 1, 10); - - assertNotNull(result); - assertEquals(1, result.getRecords().size()); -+ assertInstanceOf(SysJobLogVO.class, result.getRecords().get(0)); - } - } -``` - + \ No newline at end of file