feat&refactor: 完成多模块功能迭代与配置优化
本次提交覆盖多个业务模块的功能完善与体验优化:
1. **鉴权与配置调整**:
- 统一JWT滑动续签逻辑,简化Token存储,移除RefreshToken相关冗余代码
- 调整多项目配置文件中JWT过期时间为3600秒,统一会话闲置窗口
- 工位配置放开1~12限制,改为仅校验大于0
2. **术语统一替换**:全链路将"精密件"替换为"电气件",修正物料管理描述
3. **功能新增**:
- 新增工位类型、工艺路线与产线点位台账模块
- 添加工艺PDF预览面板、工位终端代理转发接口
- 新增操作日志按操作人列表筛选、工位登出日志记录
- 新增PLC移料指令与产线点位状态管理
4. **业务流程优化**:
- 调整BOM物料删除校验逻辑,优化工单备料计算
- 补充物料图号、检测单号等追溯字段
- 完善工艺流程图与工位绑定关系说明
- 优化前端页面文案与交互细节
5. **代码规范与维护**:
- 新增通用工具函数与前端静态资源
- 整理路由权限与中间件逻辑
- 修复部分接口与配置的不兼容问题
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
package production
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"bj_power_mes/common/httpx"
|
||||
tokenx "bj_power_mes/common/token"
|
||||
"bj_power_mes/ent"
|
||||
"bj_power_mes/ent/user"
|
||||
"bj_power_mes/internal/logic"
|
||||
"bj_power_mes/internal/svc"
|
||||
)
|
||||
@@ -110,6 +115,9 @@ func ListSemiFlowsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
|
||||
// ---------- 操作日志 ----------
|
||||
|
||||
// ListEventLogsHandler GET /api/v1/event-logs 操作日志分页查询
|
||||
// 可见性:admin(SUPER_ADMIN)可看全部并可按操作人筛选;普通用户强制只看自己的日志。
|
||||
// operatorName:操作人中文名(users.name 批量映射,历史数据同样生效)。
|
||||
func ListEventLogsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
q := r.URL.Query()
|
||||
@@ -117,12 +125,109 @@ func ListEventLogsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
pageSize := atoiDefault(q.Get("pageSize"), 20)
|
||||
fromMs, _ := strconv.ParseInt(q.Get("from"), 10, 64)
|
||||
toMs, _ := strconv.ParseInt(q.Get("to"), 10, 64)
|
||||
|
||||
// 当前身份:uid → user(历史数据 operator 中文名/用户名混杂,过滤需同时带两者)
|
||||
uid := currentUid(r, svcCtx)
|
||||
me, _ := svcCtx.EntClient.User.Get(context.Background(), uid)
|
||||
meUsername, _ := r.Context().Value("username").(string)
|
||||
if me == nil && meUsername != "" {
|
||||
me, _ = svcCtx.EntClient.User.Query().Where(user.UsernameEQ(meUsername)).First(context.Background())
|
||||
}
|
||||
var candidates []string
|
||||
isAdmin := false
|
||||
if me != nil {
|
||||
candidates = []string{me.Username, me.Name}
|
||||
if rl, err := svcCtx.EntClient.Role.Get(context.Background(), me.RoleId); err == nil && rl.Code == "SUPER_ADMIN" {
|
||||
isAdmin = true
|
||||
}
|
||||
}
|
||||
explicitFilter := q.Get("operator")
|
||||
if !isAdmin {
|
||||
// 普通用户仅能查看自己的操作日志(用户名 + 中文名任一命中),忽略显式筛选
|
||||
explicitFilter = ""
|
||||
}
|
||||
|
||||
list, total, err := logic.New(svcCtx).ListEventLogs(r.Context(),
|
||||
q.Get("orderNo"), q.Get("operator"), q.Get("eventType"), fromMs, toMs, page, pageSize)
|
||||
q.Get("orderNo"), operatorCandidates(explicitFilter, candidates), q.Get("eventType"), fromMs, toMs, page, pageSize)
|
||||
if err != nil {
|
||||
httpx.Fail(w, 3308, err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Ok(w, map[string]any{"list": list, "total": total})
|
||||
|
||||
// 批量映射操作人中文名,缺档显示原用户名
|
||||
nameMap := realNameMapOf(svcCtx, list)
|
||||
rows := make([]map[string]any, 0, len(list))
|
||||
for _, e := range list {
|
||||
name := nameMap[e.Operator]
|
||||
if name == "" {
|
||||
name = e.Operator
|
||||
}
|
||||
rows = append(rows, map[string]any{
|
||||
"id": e.ID,
|
||||
"eventType": e.EventType,
|
||||
"workOrderNo": e.WorkOrderNo,
|
||||
"description": e.Description,
|
||||
"entityType": e.EntityType,
|
||||
"entityId": e.EntityId,
|
||||
"operator": e.Operator,
|
||||
"operatorName": name,
|
||||
"payload": e.Payload,
|
||||
"createdAt": e.CreatedAt.UnixMilli(),
|
||||
})
|
||||
}
|
||||
httpx.Ok(w, map[string]any{"list": rows, "total": total, "isAdmin": isAdmin})
|
||||
}
|
||||
}
|
||||
|
||||
// currentUid 取当前登录用户ID:优先 JWT 上下文,缺失时回退解析 Bearer token
|
||||
func currentUid(r *http.Request, svcCtx *svc.ServiceContext) int {
|
||||
switch v := r.Context().Value("userId").(type) {
|
||||
case float64:
|
||||
return int(v)
|
||||
case int:
|
||||
return v
|
||||
case int64:
|
||||
return int(v)
|
||||
}
|
||||
auth := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
|
||||
if auth != "" && strings.HasPrefix(r.Header.Get("Authorization"), "Bearer ") {
|
||||
if claims, err := tokenx.Parse(svcCtx.Config.Auth.AccessSecret, auth); err == nil {
|
||||
return claims.UserId
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// operatorCandidates 计算操作人过滤候选:admin 显式筛选时精确匹配输入值;否则取当前用户身份候选
|
||||
func operatorCandidates(filter string, self []string) []string {
|
||||
if filter != "" {
|
||||
return []string{filter}
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
// realNameMapOf 批量取操作人中文名(users.name)
|
||||
func realNameMapOf(svcCtx *svc.ServiceContext, logs []*ent.EventLog) map[string]string {
|
||||
set := make([]string, 0, 8)
|
||||
seen := map[string]bool{}
|
||||
for _, e := range logs {
|
||||
if e.Operator != "" && !seen[e.Operator] {
|
||||
seen[e.Operator] = true
|
||||
set = append(set, e.Operator)
|
||||
}
|
||||
}
|
||||
out := map[string]string{}
|
||||
if len(set) == 0 {
|
||||
return out
|
||||
}
|
||||
us, err := svcCtx.EntClient.User.Query().Where(user.UsernameIn(set...)).All(context.Background())
|
||||
if err != nil {
|
||||
return out
|
||||
}
|
||||
for _, u := range us {
|
||||
if u.Name != "" {
|
||||
out[u.Username] = u.Name
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user