Files
bj_power/bj_power_mes/internal/logic/inspection.go
T
SunYF e852c7cd37 chore: 批量完成项目多模块迭代优化
1. 废弃半成品库存表并统一库存主表
2. 修复列表排序与搜索大小写不敏感问题
3. 新增用户最近登录时间、工单BOM名称字段
4. 完善角色管理、工位选择器功能
5. 增加拧紧数据补录、成品自动回流WMS能力
6. 统一导出时间范围校验规则
7. 丰富物料/备料单筛选条件
8. 调整菜单与权限命名适配产品型号业务
2026-09-08 11:44:04 +08:00

145 lines
4.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package logic
import (
"context"
"encoding/json"
"errors"
"strings"
"time"
"bj_power_mes/ent"
"bj_power_mes/ent/inspectionrecord"
)
// FlexStr 兼容客户端把数字字段传成 number 或 string(前端 stationNo 用数字,
// 标准 JSON 反序列化进 string 会报错 → 400 请求体解析失败)
type FlexStr string
func (f *FlexStr) UnmarshalJSON(b []byte) error {
s := strings.TrimSpace(string(b))
s = strings.Trim(s, `"`)
if s == "null" {
s = ""
}
*f = FlexStr(s)
return nil
}
// InspectionReq 巡检记录请求(PAD 巡检终端,块8)
type InspectionReq struct {
Category string `json:"category"` // CHECKIN/POINT/PROCESS/DONE/ALARM
StationNo FlexStr `json:"stationNo"`
Shift string `json:"shift"` // 早/中/晚
OrderNo string `json:"orderNo"` // 工单号
Sn string `json:"sn"` // 工件SN
Result string `json:"result"` // OK/NG
Items []string `json:"items"` // 点检项/异常类型
Photo string `json:"photo"` // 拍照文件名
Remark string `json:"remark"` // 文字描述/签字
Operator string `json:"operator"` // 操作人
}
// CreateInspection 提交巡检记录;ALARM 类型同时触发看板报警(SSE + 清缓存)
func (s *Service) CreateInspection(ctx context.Context, req InspectionReq, operator string) error {
if req.Category == "" {
return errors.New("记录类型必填")
}
category := req.Category
if !oneOf(category, "CHECKIN", "POINT", "PROCESS", "DONE", "ALARM") {
return errors.New("记录类型不合法")
}
result := req.Result
if result == "" {
result = "OK"
}
if req.Operator == "" {
req.Operator = operator
}
_, err := s.ctx.EntClient.InspectionRecord.Create().
SetCategory(category).
SetStationNo(string(req.StationNo)).
SetShift(req.Shift).
SetOrderNo(req.OrderNo).
SetSn(req.Sn).
SetResult(result).
SetItems(req.Items).
SetPhoto(req.Photo).
SetRemark(req.Remark).
SetOperator(req.Operator).
Save(ctx)
if err != nil {
return err
}
s.ctx.EventLog.Write(ctx, "inspection."+category, req.OrderNo, req.Operator, "inspection_record",
req.Sn, "巡检终端提交", map[string]any{"category": category, "stationNo": string(req.StationNo), "result": result})
if category == "ALARM" {
// 触发看板报警:SSE 推送 + 使 Redis 看板报警缓存失效
alarmJSON, _ := json.Marshal(map[string]any{
"level": "CRITICAL",
"type": "inspection_alarm",
"message": "巡检异常上报:" + req.Remark,
"station": string(req.StationNo),
"time": time.Now().Format("2006-01-02 15:04:05"),
})
if s.ctx.SSE != nil {
s.ctx.SSE.Publish("dashboard.alarm", string(alarmJSON))
}
if s.ctx.RedisClient != nil {
_, _ = s.ctx.RedisClient.Del("dashboard:alarms")
}
}
s.notifyDashboard()
return nil
}
// ListInspections 查询巡检记录(不分页,供内部/导出用,封顶 1000)
func (s *Service) ListInspections(ctx context.Context, category, operator, from, to string) ([]*ent.InspectionRecord, error) {
rows, _, err := s.ListInspectionsPaged(ctx, category, operator, from, to, "", "", 1, 1000)
return rows, err
}
// ListInspectionsPaged 分页查询巡检记录,返回 {rows, total};排序 id desc 最新置顶
// orderNo/stationNo2026-09-08 补充筛选(大小写不敏感)
func (s *Service) ListInspectionsPaged(ctx context.Context, category, operator, from, to, orderNo, stationNo string, page, pageSize int) ([]*ent.InspectionRecord, int, error) {
q := s.ctx.EntClient.InspectionRecord.Query()
if category != "" {
q = q.Where(inspectionrecord.Category(category))
}
if orderNo != "" {
q = q.Where(inspectionrecord.OrderNoEqualFold(orderNo))
}
if stationNo != "" {
q = q.Where(inspectionrecord.StationNoEqualFold(stationNo))
}
if operator != "" {
q = q.Where(inspectionrecord.Operator(operator))
}
if from != "" {
if f, err := time.Parse("2006-01-02", from); err == nil {
q = q.Where(inspectionrecord.CreatedAtGTE(f))
}
}
if to != "" {
if t, err := time.Parse("2006-01-02", to); err == nil {
q = q.Where(inspectionrecord.CreatedAtLT(t.Add(24 * time.Hour)))
}
}
total, err := q.Count(ctx)
if err != nil {
return nil, 0, err
}
rows, err := q.Order(ent.Desc(inspectionrecord.FieldID)).
Offset((page - 1) * pageSize).Limit(pageSize).All(ctx)
return rows, total, err
}
func oneOf(v string, items ...string) bool {
for _, it := range items {
if v == it {
return true
}
}
return false
}