docs(test): 更新电表箱装配业务回归测试文档

- 将文档从代码审计任务转换为端到端业务回归测试链路
- 重新组织文档结构为链路总览、示例数据基线和详细步骤
- 添加完整的业务场景清单涵盖WMS/MES/工位终端三大系统
- 定义统一的测试数据包括产品型号、物料清单、工位派工等
- 提供详细的步骤断言和数量等式验证方法
- 建立贯穿全链路的数据流向和状态变更追踪体系
This commit is contained in:
SunYF
2026-09-21 10:48:53 +08:00
parent 0d34bcd6a3
commit 132c3ed6bd
63 changed files with 3309 additions and 5784 deletions
@@ -305,19 +305,7 @@ func MarkMaterialRequestStatusInternalHandler(svcCtx *svc.ServiceContext) http.H
}
// ---------- 接驳台 / 接料确认 ----------
// ListDocksHandler GET /docks 拉取 WMS 接驳台主数据(dock 真源在 WMS)。
// WMS 不可达降级为错误,前端仍可用写死兜底下拉。
func ListDocksHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
list, err := svcCtx.Wms.ListDocks(r.Context())
if err != nil {
httpx.Fail(w, 3113, "拉取接驳台失败:"+err.Error())
return
}
httpx.Ok(w, list)
}
}
// 接驳台查询/维护接口见 dock.go(真源已迁 MES 本地 dock 表)。
// ReceiveMaterialRequestHandler POST /material-requests/receive 接料确认(MES 备料页人工点「已接料」)。
// qty 可空(≤0 表示确认本批全部剩余);累加 receivedQty(已接料),上限为已发出量。
@@ -0,0 +1,121 @@
package production
import (
"net/http"
"strconv"
"strings"
"bj_power_mes/common/httpx"
"bj_power_mes/ent"
"bj_power_mes/ent/dock"
"bj_power_mes/internal/svc"
)
// 接驳台主数据(真源在 MES2026-09-21 自 WMS 迁入):系统预置只读,不提供增删改。
// 工位维护 / 排产推荐 / AGV 通讯均查本表;仓库不再维护接驳台、也不给接驳台派任务。
// dockRow 接驳台返回 DTO(显式 json 标签,避免 ent omitempty 吞掉 hasPallet=false)。
type dockRow struct {
ID int64 `json:"id"`
DockCode string `json:"dockCode"`
Name string `json:"name"`
DockType string `json:"dockType"`
StationNo int `json:"stationNo"`
Status string `json:"status"`
HasPallet bool `json:"hasPallet"`
PalletRef string `json:"palletRef"`
CreatedAt int64 `json:"createdAt"`
}
func dockRowOf(d *ent.Dock) dockRow {
return dockRow{
ID: int64(d.ID),
DockCode: d.DockCode,
Name: d.Name,
DockType: d.DockType,
StationNo: d.StationNo,
Status: d.Status,
HasPallet: d.HasPallet,
PalletRef: d.PalletRef,
CreatedAt: d.CreatedAt.Unix(),
}
}
// ListDocksHandler GET /docks 接驳台全量列表(工位/排产/AGV 下拉真源,读本地 dock 表)。
func ListDocksHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
list, err := svcCtx.EntClient.Dock.Query().Order(ent.Asc("dockCode")).All(r.Context())
if err != nil {
httpx.Fail(w, 3113, "查询接驳台失败:"+err.Error())
return
}
rows := make([]dockRow, 0, len(list))
for _, d := range list {
rows = append(rows, dockRowOf(d))
}
httpx.Ok(w, rows)
}
}
// ListDocksMaintHandler GET /docks/maint 接驳台维护页只读分页查询。
// 编码精确 / 名称模糊 / 类型精确 / 状态精确各自独立筛选(真分页在 SQL 层)。
func ListDocksMaintHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
query := svcCtx.EntClient.Dock.Query()
if typ := strings.TrimSpace(q.Get("dockType")); typ != "" {
query = query.Where(dock.DockTypeEQ(typ))
}
if code := strings.TrimSpace(q.Get("dockCode")); code != "" {
query = query.Where(dock.DockCodeEqualFold(code))
}
if name := strings.TrimSpace(q.Get("name")); name != "" {
query = query.Where(dock.NameContainsFold(name))
}
if status := strings.TrimSpace(q.Get("status")); status != "" {
query = query.Where(dock.StatusEQ(status))
}
total, err := query.Count(r.Context())
if err != nil {
httpx.Fail(w, 3113, "查询接驳台失败:"+err.Error())
return
}
page, _ := strconv.Atoi(q.Get("page"))
if page < 1 {
page = 1
}
size, _ := strconv.Atoi(q.Get("pageSize"))
if size < 1 || size > 200 {
size = 20
}
list, err := query.
Order(ent.Desc("createdAt"), ent.Desc("id")).
Offset((page - 1) * size).Limit(size).All(r.Context())
if err != nil {
httpx.Fail(w, 3113, "查询接驳台失败:"+err.Error())
return
}
rows := make([]dockRow, 0, len(list))
for _, d := range list {
rows = append(rows, dockRowOf(d))
}
httpx.Ok(w, map[string]any{"list": rows, "total": total, "page": page, "pageSize": size})
}
}
// ListDocksInternalHandler GET /api/internal/docks 供 WMS 拉取接驳台主数据
// (WMS 出库目标工位下拉 / AGV 页接驳台列表;dock 真源已迁 MES)。X-API-TOKEN 保护。
func ListDocksInternalHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
list, err := svcCtx.EntClient.Dock.Query().Order(ent.Asc("dockCode")).All(r.Context())
if err != nil {
httpx.Fail(w, 3113, "查询接驳台失败:"+err.Error())
return
}
rows := make([]dockRow, 0, len(list))
for _, d := range list {
rows = append(rows, dockRowOf(d))
}
httpx.Ok(w, map[string]any{"list": rows})
}
}
@@ -99,6 +99,9 @@ func RegisterProductionRoutes(server *rest.Server, serverCtx *svc.ServiceContext
server.AddRoute(rest.Route{
Method: http.MethodGet, Path: "/api/internal/dock/pallet", Handler: internal(production.DockPalletInternalHandler(serverCtx)),
})
server.AddRoute(rest.Route{
Method: http.MethodGet, Path: "/api/internal/docks", Handler: internal(production.ListDocksInternalHandler(serverCtx)),
})
server.AddRoute(rest.Route{
Method: http.MethodGet, Path: "/api/internal/workpiece/bind-panel", Handler: internal(production.BindPanelInternalHandler(serverCtx)),
})
@@ -181,6 +184,7 @@ func RegisterProductionRoutes(server *rest.Server, serverCtx *svc.ServiceContext
{Method: http.MethodGet, Path: "/qty-reports/stats", Handler: QtyReportStatsHandler(serverCtx)},
{Method: http.MethodPost, Path: "/qty-reports/handle", Handler: HandleQtyReportHandler(serverCtx)},
{Method: http.MethodGet, Path: "/docks", Handler: production.ListDocksHandler(serverCtx)},
{Method: http.MethodGet, Path: "/docks/maint", Handler: production.ListDocksMaintHandler(serverCtx)},
{Method: http.MethodPost, Path: "/plc/send-process", Handler: production.PlcSendProcessHandler(serverCtx)},
{Method: http.MethodGet, Path: "/plc/send-logs", Handler: production.PlcSendLogsHandler(serverCtx)},