refactor: 重构产线工位与备料流程,移除冗余字段

1. 移除工单、工件、日排产中的冗余工位组合/接驳台字段
2. 新增工位接驳台编码字段与唯一约束,关联WMS接驳台主数据
3. 重构日排产为工位产量分配模式,替代原接驳台列表
4. 新增备料单工位级字段与分批出库支持
5. 移除定时同步可生产数量,改为WMS实时拉取接口
6. 过滤操作日志,排除登录/退出相关日志
7. 调整仪表盘工序展示逻辑为今日派工路线
8. 新增接驳台维护菜单与基础数据
This commit is contained in:
SunYF
2026-09-19 07:50:21 +08:00
parent 543655d441
commit 37f10d3a13
156 changed files with 4489 additions and 1285 deletions
+27 -1
View File
@@ -245,6 +245,7 @@ type StationReq struct {
Name string `json:"name"`
StationType *string `json:"stationType"`
FlowId *int `json:"flowId"`
DockCode *string `json:"dockCode"` // 绑定的接驳台编码(与 WMS dock.dock_code 对应,1:1
}
type StationVO struct {
@@ -257,6 +258,7 @@ type StationVO struct {
Status string `json:"status"`
IsBuiltin bool `json:"isBuiltin"`
HasDock bool `json:"hasDock"`
DockCode string `json:"dockCode"`
}
func (s *Service) ListStations(ctx context.Context) ([]*StationVO, error) {
@@ -271,7 +273,7 @@ func (s *Service) ListStations(ctx context.Context) ([]*StationVO, error) {
}
out := make([]*StationVO, 0, len(stas))
for _, st := range stas {
vo := &StationVO{Id: st.ID, StationNo: st.StationNo, Name: st.Name, FlowId: st.FlowId, StationType: st.StationType, Status: st.Status, IsBuiltin: st.IsBuiltin, HasDock: st.HasDock}
vo := &StationVO{Id: st.ID, StationNo: st.StationNo, Name: st.Name, FlowId: st.FlowId, StationType: st.StationType, Status: st.Status, IsBuiltin: st.IsBuiltin, HasDock: st.HasDock, DockCode: st.DockCode}
if f, ok := flowMap[st.FlowId]; ok {
vo.FlowName = f.Name
}
@@ -288,6 +290,7 @@ func (s *Service) ListStations(ctx context.Context) ([]*StationVO, error) {
// 内置工位(种子/初始化数据,is_builtin=true)需连 PLC 并必须按工位号顺序流转,
// 不允许手动更改工位类型;页面新增的工位一律为非内置,可改类型、可删除。
// 「是否有接驳台」对应实体位置,由内置数据给定,不接收页面入参。
// 接驳台与工位 1:1:绑定前校验该接驳台未被其他工位占用(数据库另有部分唯一索引兜底)。
func (s *Service) SaveStation(ctx context.Context, req StationReq, operator string) error {
if req.StationNo < 0 {
return errors.New("工位号非法(需 ≥ 0")
@@ -308,11 +311,18 @@ func (s *Service) SaveStation(ctx context.Context, req StationReq, operator stri
return errors.New("工位类型仅支持 LINE/OFFLINE")
}
}
// 页面新增的是非内置工位:无实体接驳台,不可绑定接驳台
if req.DockCode != nil && *req.DockCode != "" {
return errors.New("自定义工位(非内置)无实体接驳台,不可绑定接驳台")
}
cr := s.ctx.EntClient.Station.Create().
SetStationNo(req.StationNo).SetName(req.Name).SetStationType(stype).SetStatus("ENABLED").
// 页面「新增工位」创建的是非内置工位(可改类型、可删除);内置工位只能由种子/初始化数据产生。
// 是否有接驳台对应实体位置,由内置数据给定,页面新增时一律为 false 且不可手改。
SetIsBuiltin(false).SetHasDock(false)
if req.DockCode != nil {
cr.SetDockCode(*req.DockCode)
}
if req.FlowId != nil && *req.FlowId > 0 {
flow, fErr := s.ctx.EntClient.ProcessFlow.Get(ctx, *req.FlowId)
if fErr != nil {
@@ -361,6 +371,22 @@ func (s *Service) SaveStation(ctx context.Context, req StationReq, operator stri
upd.SetFlowId(0)
}
}
if req.DockCode != nil {
dc := *req.DockCode
if dc != "" {
// 只有内置工位(实体产线位置)才有接驳台
if !st.IsBuiltin {
return errors.New("自定义工位(非内置)无实体接驳台,不可绑定接驳台")
}
// 接驳台与工位 1:1:已被其他工位占用则拒绝
other, oErr := s.ctx.EntClient.Station.Query().
Where(station.DockCode(dc), station.StationNoNEQ(req.StationNo)).First(ctx)
if oErr == nil && other != nil {
return fmt.Errorf("接驳台 %s 已绑定工位%d,一个接驳台只能绑定一个工位", dc, other.StationNo)
}
}
upd.SetDockCode(dc)
}
if _, err := upd.Save(ctx); err != nil {
return err
}