feat: 完成WMS系统权限体系与业务功能迭代
本提交完成了WMS系统的多维度优化升级: 1. 新增RBAC权限系统,支持角色/菜单/按钮三级权限管控 2. 重构库存盘点、物料管理、区域维护等模块的查询筛选与展示逻辑 3. 优化入库/出库/质检等业务流程,完善数据冗余与业务闭环 4. 移除旧装箱表,将装箱逻辑合并到出库主表 5. 新增前端权限判断工具、导出工具与端到端测试用例 6. 补充完善各类注释与数据库字段说明
This commit is contained in:
@@ -22,6 +22,12 @@ func (InspectionRecord) Fields() []ent.Field {
|
||||
field.String("inspection_type").Default("incoming").Comment("来料检/过程检/成品检"),
|
||||
field.String("status").Default("未检").Comment("未检/合格/不合格"),
|
||||
field.String("result_value").Optional().Comment("实测值(部分检验项)"),
|
||||
// 检验数量 / 合格数量(量化闭环:来料/过程/成品检的批次抽检量)
|
||||
field.Int("inspect_qty").Default(0).Comment("检验数量(抽检件数)"),
|
||||
field.Int("pass_qty").Default(0).Comment("合格数量(≤检验数量)"),
|
||||
// 检测说明 / 不合格原因
|
||||
field.String("check_desc").Optional().Comment("检测说明(检验项目/方法)"),
|
||||
field.String("fail_reason").Optional().Comment("不合格原因(不合格时必填)"),
|
||||
field.String("inspector").Optional().Comment("检验人"),
|
||||
field.String("remark").Optional().Comment("备注"),
|
||||
field.Int64("created_at").DefaultFunc(nowUnix),
|
||||
|
||||
@@ -6,8 +6,10 @@ import (
|
||||
"entgo.io/ent/schema/index"
|
||||
)
|
||||
|
||||
// OutboundOrder 出库单
|
||||
// 出库强约束:累计出库 ≤ 工单 BOM 需求量(由 MES 校验),WMS 侧校验 order_no 对应台账
|
||||
// OutboundOrder 出库统一主表
|
||||
// 所有出库(备料出库 workorder / 通用出库 general / 装箱)都落在这一张表,
|
||||
// 用 outbound_type 区分;装箱属性(箱号/SN清单/合同号)直接存本表,不再单独建装箱表。
|
||||
// 备料出库强约束:累计出库 ≤ 工单 BOM 需求量(由 MES 校验),WMS 侧校验 order_no 对应台账。
|
||||
type OutboundOrder struct {
|
||||
ent.Schema
|
||||
}
|
||||
@@ -15,7 +17,7 @@ type OutboundOrder struct {
|
||||
func (OutboundOrder) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("outbound_no").Unique().Comment("出库单号"),
|
||||
// 类型:workorder(工单领料) semi(半成品) finished(成品) scrap(报废)
|
||||
// 类型:workorder(工单领料/MES) general(通用出库,不依赖工单)
|
||||
field.String("outbound_type").Default("workorder").Comment("出库类型"),
|
||||
field.String("order_no").Optional().Comment("关联工单号(工单为唯一挂靠载体)"),
|
||||
field.String("material_code").Comment("物料编码"),
|
||||
@@ -28,6 +30,10 @@ func (OutboundOrder) Fields() []ent.Field {
|
||||
field.String("reviewer").Optional().Comment("复核人"),
|
||||
field.String("target_dock").Optional().Comment("目标接驳台(AGV配送)"),
|
||||
field.String("remark").Optional().Comment("备注"),
|
||||
// 装箱属性:出库时一并记录箱号/SN清单/合同号,统一落在出库主表,不再单独建装箱表
|
||||
field.String("box_no").Optional().Comment("箱号(装箱出库时填写,用于整箱发货追溯)"),
|
||||
field.String("box_sn_list").Optional().Comment("装箱 SN 清单(JSON 数组字符串)"),
|
||||
field.String("contract_no").Optional().Comment("合同号(装箱选填)"),
|
||||
field.Int64("created_at").DefaultFunc(nowUnix).Comment("创建时间"),
|
||||
}
|
||||
}
|
||||
@@ -37,5 +43,6 @@ func (OutboundOrder) Indexes() []ent.Index {
|
||||
index.Fields("order_no"),
|
||||
index.Fields("material_code"),
|
||||
index.Fields("outbound_type"),
|
||||
index.Fields("box_no"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/index"
|
||||
)
|
||||
|
||||
// PackageBox 包装箱 ↔ SN 关联(装箱管理)
|
||||
// 将一个或多个精密件 SN 绑定到一个箱号,便于整箱出入库与追溯。
|
||||
// sn_list 以字符串存多个 SN(逗号分隔 / JSON),不强制外键关联 inventory,
|
||||
// 因为装箱是业务封装动作,箱内 SN 仍各自在 inventory 表中独立流转。
|
||||
type PackageBox struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
func (PackageBox) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("box_no").Unique().Comment("箱号"),
|
||||
// 关联 SN 列表(逗号分隔)或 JSON
|
||||
field.String("sn_list").Optional().Comment("箱内 SN 列表"),
|
||||
field.String("material_code").Optional().Comment("物料编码"),
|
||||
field.Int("quantity").Default(0).Comment("箱内数量"),
|
||||
field.String("operator").Optional().Comment("包装人"),
|
||||
field.String("contract_no").Optional().Comment("合同号(选填)"),
|
||||
field.String("remark").Optional().Comment("备注"),
|
||||
field.Int64("created_at").DefaultFunc(nowUnix),
|
||||
field.Int64("updated_at").DefaultFunc(nowUnix).Optional().Comment("更新时间"),
|
||||
}
|
||||
}
|
||||
|
||||
func (PackageBox) Indexes() []ent.Index {
|
||||
return []ent.Index{
|
||||
index.Fields("material_code"),
|
||||
index.Fields("contract_no"),
|
||||
index.Fields("operator"),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/entsql"
|
||||
"entgo.io/ent/schema"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/index"
|
||||
)
|
||||
|
||||
// Permission 权限/菜单
|
||||
// 模型移植自 MES(schema/permission.go),按 WMS 约定调整字段命名与时间类型。
|
||||
// type 区分两类:
|
||||
// - MENU 菜单权限:对应侧栏菜单项,path 为前端路由
|
||||
// - BUTTON 按钮权限:对应页面内的操作按钮,无 path
|
||||
type Permission struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
func (Permission) Annotations() []schema.Annotation {
|
||||
return []schema.Annotation{entsql.Annotation{Table: "permissions"}}
|
||||
}
|
||||
|
||||
func (Permission) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("code").Unique().MaxLen(64).Comment("权限编码,如 inbound:view"),
|
||||
field.String("name").MaxLen(64).Comment("名称"),
|
||||
field.String("type").Default("MENU").MaxLen(20).Comment("类型 MENU菜单/BUTTON按钮"),
|
||||
field.String("path").Default("").MaxLen(128).Optional().Comment("前端路由(菜单类)"),
|
||||
field.String("icon").Default("").MaxLen(64).Optional().Comment("图标(菜单类)"),
|
||||
field.Int("sort").Default(0).Optional().Comment("排序"),
|
||||
field.String("remark").Default("").MaxLen(255).Optional().Comment("备注"),
|
||||
field.Int64("created_at").DefaultFunc(nowUnix).Comment("创建时间"),
|
||||
field.Int64("updated_at").DefaultFunc(nowUnix).Comment("更新时间"),
|
||||
}
|
||||
}
|
||||
|
||||
func (Permission) Indexes() []ent.Index {
|
||||
return []ent.Index{index.Fields("code").Unique()}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/entsql"
|
||||
"entgo.io/ent/schema"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/index"
|
||||
)
|
||||
|
||||
// Role 角色:承载菜单/按钮权限
|
||||
// 模型移植自 MES(schema/role.go),但按 WMS 约定调整:
|
||||
// - 字段名 snake_case(由 tools/generate.go 统一转 camelCase 输出 JSON)
|
||||
// - 时间字段用 Int64 unix 秒,与 WMS 其余表保持一致
|
||||
// - 与 MES 的差异:MES 的角色/权限为"系统预置只读",WMS 要求可维护,故支持增删改
|
||||
type Role struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
func (Role) Annotations() []schema.Annotation {
|
||||
return []schema.Annotation{entsql.Annotation{Table: "roles"}}
|
||||
}
|
||||
|
||||
func (Role) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("name").MaxLen(64).Comment("角色名称"),
|
||||
field.String("code").Unique().MaxLen(64).Comment("角色编码,如 admin/operator/inspector"),
|
||||
field.String("remark").Default("").MaxLen(255).Optional().Comment("备注"),
|
||||
// 权限编码列表,如 inbound:view / inbound:create
|
||||
field.JSON("permission_codes", []string{}).Optional().SchemaType(map[string]string{
|
||||
dialect.Postgres: "jsonb",
|
||||
}).Comment("权限编码列表"),
|
||||
field.Int64("created_at").DefaultFunc(nowUnix).Comment("创建时间"),
|
||||
field.Int64("updated_at").DefaultFunc(nowUnix).Comment("更新时间"),
|
||||
}
|
||||
}
|
||||
|
||||
func (Role) Indexes() []ent.Index {
|
||||
return []ent.Index{index.Fields("code").Unique()}
|
||||
}
|
||||
@@ -18,7 +18,8 @@ func (User) Fields() []ent.Field {
|
||||
field.String("username").Unique().Comment("登录名"),
|
||||
field.String("password").Comment("密码(哈希)"),
|
||||
field.String("real_name").Optional().Comment("姓名"),
|
||||
field.String("role").Default("operator").Comment("角色 admin/operator/inspector"),
|
||||
field.String("role").Default("operator").Comment("角色 admin/operator/inspector(旧字段,权限数据化后由 role_id 决定,此字段仅作兼容/展示)"),
|
||||
field.Int("role_id").Optional().Comment("角色ID,关联 roles 表;为空时回退按 role 字符串取权限"),
|
||||
field.String("dept").Optional().Comment("部门"),
|
||||
field.String("phone").Optional().Comment("电话"),
|
||||
field.Bool("is_active").Default(true).Comment("是否启用"),
|
||||
|
||||
Reference in New Issue
Block a user