5-27代码优化.md 12.6 KB

5-27 代码优化

本文档说明 2026-05-27 对美国版接口的变更。

  1. 修复 App 管理员级联选店接口 404admin-scope-regions 等 Query 传参无法命中路由,见 us-app-auth-路由修复)。
  2. 同步修复 Web auth-scope 同类路由(regions / locations 使用 Query 传 partnerIdgroupId)。
  3. App Label Report 页pages/more/label-report):完善 get-label-report,支持 7d / 30d / 90d / 自定义日期(见 app-label-report)。
  4. 泰额版 POST /api/app/th-app-auth/login:修复登录成功后因 主库无 LoginLog 表 导致 500(见 th-app-auth-login)。

级联选店业务见 5-26代码优化.mdus-app-auth / auth-scope 章节。


us-app-auth 管理员选店路由 404 修复

问题现象

GET /api/app/us-app-auth/admin-scope-regions?partnerId=3a217015-4def-3813-01bf-05e4c8c09be6
Authorization: Bearer {app_token}

返回 404 Not Found(未进入业务逻辑,非 400 权限错误)。

根因

项目使用 YiConventionalRouteBuilder:当 Action 仅有一个Id 结尾的参数(如 partnerId)时,约定路由会生成 路径参数,例如:

GET /api/app/us-app-auth/admin-scope-regions/{partnerId}

客户端若用 Query ?partnerId=... 调用,路径不匹配 → 404

admin-scope-locations 同时有 partnerId + groupId 两个 *Id 参数时,约定路由通常 不会 把 Id 放进路径,故 Query 方式有时能通;为统一行为,已改为显式路由。

修复方式

UsAppAuthAppService / AuthScopeAppService 上为级联选店方法增加 显式 [HttpGet] / [HttpPost] 模板(与 forgot-password 相同写法),强制 partnerIdgroupIdQuery

正确接口地址(修复后)

步骤 方法 路径 Query
公司 GET /api/app/us-app-auth/admin-scope-companies
Region GET /api/app/us-app-auth/admin-scope-regions partnerId(必填)
门店 GET /api/app/us-app-auth/admin-scope-locations partnerIdgroupId(必填)
确认选店 POST /api/app/us-app-auth/select-admin-scope-location Body JSON

鉴权:App 登录 Token(client_kind=us-app)+ 平台管理员。

Region 列表 — 正确示例

GET /api/app/us-app-auth/admin-scope-regions?partnerId=3a217015-4def-3813-01bf-05e4c8c09be6 HTTP/1.1
Host: localhost:19001
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

响应AuthScopeRegionOptionDto[]

[
  {
    "id": "fl_group_id_east",
    "groupName": "East Region",
    "partnerId": "3a217015-4def-3813-01bf-05e4c8c09be6",
    "state": true
  }
]

门店列表 — 正确示例

GET /api/app/us-app-auth/admin-scope-locations?partnerId=3a217015-4def-3813-01bf-05e4c8c09be6&groupId=fl_group_id_east HTTP/1.1
Authorization: Bearer {app_token}

兼容说明(不推荐)

修复前若误按约定路由调用,Region 可能需写成路径参数:

GET /api/app/us-app-auth/admin-scope-regions/3a217015-4def-3813-01bf-05e4c8c09be6

请统一使用 Query ?partnerId=,与文档及 App 封装一致。

Web auth-scope(同步修复)

方法 路径 Query
GET /api/app/auth-scope/companies
GET /api/app/auth-scope/regions partnerId
GET /api/app/auth-scope/locations partnerIdgroupId
POST /api/app/auth-scope/select-location Body
GET /api/app/auth-scope/current-scope

联调注意

现象 处理
仍 404 确认已部署含本修复的后端;路径勿多写 /us-app-auth 前缀(完整路径见上表)
400「请使用 App 登录令牌」 使用 POST /api/app/us-app-auth/login 返回的 Token
400「仅管理员可使用」 换管理员账号
200 但 [] 空数组 该公司下无 fl_group 或数据未录入

推荐调用顺序(App 管理员)

POST /api/app/us-app-auth/login
  → GET  /api/app/us-app-auth/admin-scope-companies
  → GET  /api/app/us-app-auth/admin-scope-regions?partnerId={公司Id}
  → GET  /api/app/us-app-auth/admin-scope-locations?partnerId={公司Id}&groupId={区域Id}
  → POST /api/app/us-app-auth/select-admin-scope-location
  → GET  /api/app/us-app-auth/my-locations

App Label Report 标签报表

应用服务UsAppLabelingAppService
接口POST /api/app/us-app-labeling/get-label-report
页面:App Label Report(指标卡 + Labels by Category + Print Volume Trends + Most Used Products)

鉴权与数据范围

说明
Token App 登录 POST /api/app/us-app-auth/login
门店 Body locationId(当前选中门店;管理员可先 select-admin-scope-location
管理员 / Partner 当前门店 全部 打印任务
其它角色 CreatedBy == 当前用户 的任务

请求体(UsAppLabelReportQueryInputVo)

字段 类型 必填 说明
locationId string 门店 Guid
period string 7d(默认)/ 30d / 90d / custom
startDate date custom 时必填 含当天,如 2026-05-20
endDate date custom 时必填 含当天,默认今天
keyword string 产品名 / 标签分类名模糊匹配

周期与 App UI 对应

App 按钮 period
Last 7 Days 7d
Last 30 Days 30d
Last 90 Days 90d
Custom + Start/End custom + startDate + endDate

区间规则(含起止日当天):

period 起止(结束日 = 今天或 endDate)
7d 共 7 个自然日(今天往前 6 天)
30d 共 30 个自然日
90d 共 90 个自然日
custom startDate ~ endDate(最长 366 天)

请求示例

最近 7 天

POST /api/app/us-app-labeling/get-label-report HTTP/1.1
Authorization: Bearer {app_token}
Content-Type: application/json
{
  "locationId": "3a21220f-db37-3e32-7390-d55f64cd62a8",
  "period": "7d"
}

最近 30 天

{
  "locationId": "3a21220f-db37-3e32-7390-d55f64cd62a8",
  "period": "30d"
}

自定义日期(对应 UI Start / End)

{
  "locationId": "3a21220f-db37-3e32-7390-d55f64cd62a8",
  "period": "custom",
  "startDate": "2026-05-20",
  "endDate": "2026-05-27"
}

响应体(ReportsLabelReportOutputDto)

appliedRange(本次实际统计区间)

字段 说明
period 7d / 30d / 90d / custom
startDate yyyy-MM-dd
endDate yyyy-MM-dd
dayCount 自然日天数
trendDescription 趋势图副标题(英文,如 Daily label printing volume for the last 7 days.

summary(四张指标卡)

字段 UI 对应
totalLabelsPrinted Total Labels Printed
totalLabelsPrintedChangeRate 相对 上一同长度周期 变化率(%,如 20.1 表示 +20.1%)
mostPrintedCategoryName / mostPrintedCategoryCount Most Printed Category
topProductName / topProductCount Top Product
avgDailyPrints Avg. Daily Prints
avgDailyPrintsChangeRate 日均相对上一周期变化率

labelsByCategory(Labels by Category 柱状图)

{ categoryId, categoryName, count }[],按 count 降序。分类来自 标签分类fl_label_category)。

{ date, count }[]整个查询区间内每日打印量(7d 返回 7 个点,30d 返回 30 个点,以此类推;无数据日为 0)。

mostUsedProducts(Most Used Products 表格)

字段 UI 列
productName Product Name
categoryName Category(产品分类名)
totalPrinted Total Printed
usagePercent Usage %(占当期总打印量百分比)

响应示例(节选)

{
  "appliedRange": {
    "period": "7d",
    "startDate": "2026-05-21",
    "endDate": "2026-05-27",
    "dayCount": 7,
    "trendDescription": "Daily label printing volume for the last 7 days."
  },
  "summary": {
    "totalLabelsPrinted": 2543,
    "totalLabelsPrintedPrevPeriod": 2118,
    "totalLabelsPrintedChangeRate": 20.06,
    "mostPrintedCategoryName": "Dairy",
    "mostPrintedCategoryCount": 450,
    "topProductName": "Whole Milk",
    "topProductCount": 182,
    "avgDailyPrints": 363.29,
    "avgDailyPrintsPrevPeriod": 302.57,
    "avgDailyPrintsChangeRate": 20.07
  },
  "labelsByCategory": [
    { "categoryName": "Dairy", "count": 450 },
    { "categoryName": "Meat", "count": 380 }
  ],
  "printVolumeTrend": [
    { "date": "2026-05-21", "count": 72 },
    { "date": "2026-05-22", "count": 85 }
  ],
  "mostUsedProducts": [
    {
      "productName": "Whole Milk",
      "categoryName": "Dairy",
      "totalPrinted": 182,
      "usagePercent": 7.16
    }
  ]
}

与旧版差异(本次优化)

优化前 优化后
period startDate/endDate,默认约 30 天 显式 7d/30d/90d/custom
printVolumeTrend 仅区间内 最后 7 天 整个查询区间按日汇总
appliedRange 回显实际区间与趋势副标题
路由 仅约定路由 增加 [HttpPost("us-app-labeling/get-label-report")] 显式路径

联调注意

现象 处理
404 确认路径为 POST .../get-label-report(非 GET)
custom 报错 须同时传 startDateendDate
趋势只有 7 个点但选了 30d 部署含本修复的后端
指标全 0 该门店/角色在区间内无打印任务;检查 locationId
分类名为空 打印任务未关联标签分类

更完整的权限说明见 5-18接口优化.md → us-app-print-log / get-label-report 章节。


泰额版 th-app-auth 登录

应用服务ThAppAuthAppService(泰额模块 FoodLabeling.Th.Application
路径POST /api/app/th-app-auth/login(已加显式路由 [HttpPost("th-app-auth/login")]

问题现象

日志显示登录逻辑已执行成功(查租户、用户、userlocation 均有 SQL),但请求最终 500

MySqlException: Table 'antis-foodlabeling-host.loginlog' doesn't exist

浏览器还可能提示:

Request origin http://saas-test.3ffoodsafety.com does not have permission to access the resource.

根因

  1. LoginLog:泰额 App 在租户库校验用户,但登录后发布了 LoginEvent,在 UoW 提交阶段当前连接(主库 host) 插入 LoginLog;主库 antis-foodlabeling-host 未建该表 → 整单失败。
  2. CORSApp:CorsOrigins 未包含 http://saas-test.3ffoodsafety.com

修复说明

处理
泰额 App 登录 不再发布 LoginEvent,避免写 host 库 LoginLog
LoginEventHandler 外层 try/catch + autoSave: true;写库失败仅打 Warning,不影响 Web 登录
CORS appsettings.jsonApp:CorsOrigins 增加 saas-test.3ffoodsafety.com(http/https)
路由 th-app-auth/loginth-app-auth/my-locations 显式 [HttpPost] / [HttpGet]

请求示例

POST /api/app/th-app-auth/login
Content-Type: application/json
{
  "tenantId": "11111111-1111-1111-1111-111111111111",
  "email": "admin@example.com",
  "password": "YourPassword1!"
}

部署注意

  1. 重新发布 泰额版 Yi.Abp.Web(含 FoodLabeling.Th.ApplicationYi.Framework.Rbac.Domain)。
  2. 生产环境若域名不同,在 App:CorsOrigins(或 appsettings.Production.json)中追加前端 Origin,分号分隔。
  3. 若需在主库记录 Web 管理员登录日志,可在 host 库执行 RBAC 初始化脚本创建 LoginLog 表(泰额 App 登录不依赖该表)。

多租户登录完整说明见 5-19泰额版.md


变更记录

日期 说明
2026-05-27 泰额 th-app-auth/login:取消 LoginEvent;修复 host 无 LoginLog 导致 500;CORS 增加 saas-test 域名
2026-05-27 App Label Report:get-label-report 支持 7d/30d/90d/custom;趋势按全区间按日汇总;出参 appliedRange
2026-05-27 修复 us-app-auth / auth-scope 级联选店 404:显式路由,partnerId/groupId 使用 Query
2026-05-27 补充 5-27代码优化.md 接口说明与 curl 示例