feat&refactor: 2026-09-22 半成品业务模型重构与功能完善

- 重构半成品流转逻辑:进度权威源改为 workpiece.currentStationNo,新增 completedText 快照字段,废除 doneProcessCodes
- 清理物料品类中半成品类型,存量数据幂等清理,调整物料管理方式文案为批次/序列号
- 新增日排产状态专用更新接口,修复工单工艺校验逻辑
- 新增物料档案代理接口、深路径文件下载接口
- 优化前端界面文案与工位选择逻辑,补充追溯页半成品流转展示
- 调整WMS端物料品类校验与入库接口契约
- 新增/更新数据库表结构与实体类代码
This commit is contained in:
SunYF
2026-09-22 14:42:52 +08:00
parent 09cfc6ca1c
commit d3eda6b588
49 changed files with 1155 additions and 1122 deletions
+2 -1
View File
@@ -681,6 +681,7 @@ var (
{Name: "sn", Type: field.TypeString, Size: 64},
{Name: "order_no", Type: field.TypeString, Size: 64, Default: ""},
{Name: "done_process_codes", Type: field.TypeJSON, Nullable: true},
{Name: "completed_text", Type: field.TypeString, Size: 64, Default: ""},
{Name: "action", Type: field.TypeString, Size: 20, Default: "INBOUND"},
{Name: "target_dock", Type: field.TypeString, Size: 20, Default: ""},
{Name: "operator", Type: field.TypeString, Size: 64, Default: ""},
@@ -705,7 +706,7 @@ var (
{
Name: "semiflow_action",
Unique: false,
Columns: []*schema.Column{SemiFlowColumns[4]},
Columns: []*schema.Column{SemiFlowColumns[5]},
},
},
}
+55 -1
View File
@@ -18563,6 +18563,7 @@ type SemiFlowMutation struct {
orderNo *string
doneProcessCodes *[]int
appenddoneProcessCodes []int
completedText *string
action *string
targetDock *string
operator *string
@@ -18814,6 +18815,42 @@ func (m *SemiFlowMutation) ResetDoneProcessCodes() {
delete(m.clearedFields, semiflow.FieldDoneProcessCodes)
}
// SetCompletedText sets the "completedText" field.
func (m *SemiFlowMutation) SetCompletedText(s string) {
m.completedText = &s
}
// CompletedText returns the value of the "completedText" field in the mutation.
func (m *SemiFlowMutation) CompletedText() (r string, exists bool) {
v := m.completedText
if v == nil {
return
}
return *v, true
}
// OldCompletedText returns the old "completedText" field's value of the SemiFlow entity.
// If the SemiFlow object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *SemiFlowMutation) OldCompletedText(ctx context.Context) (v string, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldCompletedText is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldCompletedText requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldCompletedText: %w", err)
}
return oldValue.CompletedText, nil
}
// ResetCompletedText resets all changes to the "completedText" field.
func (m *SemiFlowMutation) ResetCompletedText() {
m.completedText = nil
}
// SetAction sets the "action" field.
func (m *SemiFlowMutation) SetAction(s string) {
m.action = &s
@@ -18992,7 +19029,7 @@ func (m *SemiFlowMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
func (m *SemiFlowMutation) Fields() []string {
fields := make([]string, 0, 7)
fields := make([]string, 0, 8)
if m.sn != nil {
fields = append(fields, semiflow.FieldSn)
}
@@ -19002,6 +19039,9 @@ func (m *SemiFlowMutation) Fields() []string {
if m.doneProcessCodes != nil {
fields = append(fields, semiflow.FieldDoneProcessCodes)
}
if m.completedText != nil {
fields = append(fields, semiflow.FieldCompletedText)
}
if m.action != nil {
fields = append(fields, semiflow.FieldAction)
}
@@ -19028,6 +19068,8 @@ func (m *SemiFlowMutation) Field(name string) (ent.Value, bool) {
return m.OrderNo()
case semiflow.FieldDoneProcessCodes:
return m.DoneProcessCodes()
case semiflow.FieldCompletedText:
return m.CompletedText()
case semiflow.FieldAction:
return m.Action()
case semiflow.FieldTargetDock:
@@ -19051,6 +19093,8 @@ func (m *SemiFlowMutation) OldField(ctx context.Context, name string) (ent.Value
return m.OldOrderNo(ctx)
case semiflow.FieldDoneProcessCodes:
return m.OldDoneProcessCodes(ctx)
case semiflow.FieldCompletedText:
return m.OldCompletedText(ctx)
case semiflow.FieldAction:
return m.OldAction(ctx)
case semiflow.FieldTargetDock:
@@ -19089,6 +19133,13 @@ func (m *SemiFlowMutation) SetField(name string, value ent.Value) error {
}
m.SetDoneProcessCodes(v)
return nil
case semiflow.FieldCompletedText:
v, ok := value.(string)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetCompletedText(v)
return nil
case semiflow.FieldAction:
v, ok := value.(string)
if !ok {
@@ -19184,6 +19235,9 @@ func (m *SemiFlowMutation) ResetField(name string) error {
case semiflow.FieldDoneProcessCodes:
m.ResetDoneProcessCodes()
return nil
case semiflow.FieldCompletedText:
m.ResetCompletedText()
return nil
case semiflow.FieldAction:
m.ResetAction()
return nil
+10 -4
View File
@@ -1171,26 +1171,32 @@ func init() {
semiflow.DefaultOrderNo = semiflowDescOrderNo.Default.(string)
// semiflow.OrderNoValidator is a validator for the "orderNo" field. It is called by the builders before save.
semiflow.OrderNoValidator = semiflowDescOrderNo.Validators[0].(func(string) error)
// semiflowDescCompletedText is the schema descriptor for completedText field.
semiflowDescCompletedText := semiflowFields[4].Descriptor()
// semiflow.DefaultCompletedText holds the default value on creation for the completedText field.
semiflow.DefaultCompletedText = semiflowDescCompletedText.Default.(string)
// semiflow.CompletedTextValidator is a validator for the "completedText" field. It is called by the builders before save.
semiflow.CompletedTextValidator = semiflowDescCompletedText.Validators[0].(func(string) error)
// semiflowDescAction is the schema descriptor for action field.
semiflowDescAction := semiflowFields[4].Descriptor()
semiflowDescAction := semiflowFields[5].Descriptor()
// semiflow.DefaultAction holds the default value on creation for the action field.
semiflow.DefaultAction = semiflowDescAction.Default.(string)
// semiflow.ActionValidator is a validator for the "action" field. It is called by the builders before save.
semiflow.ActionValidator = semiflowDescAction.Validators[0].(func(string) error)
// semiflowDescTargetDock is the schema descriptor for targetDock field.
semiflowDescTargetDock := semiflowFields[5].Descriptor()
semiflowDescTargetDock := semiflowFields[6].Descriptor()
// semiflow.DefaultTargetDock holds the default value on creation for the targetDock field.
semiflow.DefaultTargetDock = semiflowDescTargetDock.Default.(string)
// semiflow.TargetDockValidator is a validator for the "targetDock" field. It is called by the builders before save.
semiflow.TargetDockValidator = semiflowDescTargetDock.Validators[0].(func(string) error)
// semiflowDescOperator is the schema descriptor for operator field.
semiflowDescOperator := semiflowFields[6].Descriptor()
semiflowDescOperator := semiflowFields[7].Descriptor()
// semiflow.DefaultOperator holds the default value on creation for the operator field.
semiflow.DefaultOperator = semiflowDescOperator.Default.(string)
// semiflow.OperatorValidator is a validator for the "operator" field. It is called by the builders before save.
semiflow.OperatorValidator = semiflowDescOperator.Validators[0].(func(string) error)
// semiflowDescCreatedAt is the schema descriptor for createdAt field.
semiflowDescCreatedAt := semiflowFields[7].Descriptor()
semiflowDescCreatedAt := semiflowFields[8].Descriptor()
// semiflow.DefaultCreatedAt holds the default value on creation for the createdAt field.
semiflow.DefaultCreatedAt = semiflowDescCreatedAt.Default.(func() time.Time)
// semiflowDescID is the schema descriptor for id field.
+13 -2
View File
@@ -22,8 +22,10 @@ type SemiFlow struct {
Sn string `json:"sn,omitempty"`
// OrderNo holds the value of the "orderNo" field.
OrderNo string `json:"orderNo,omitempty"`
// 已完成工序码
// 已完成工序码(已废除,历史数据保留)
DoneProcessCodes []int `json:"doneProcessCodes,omitempty"`
// 完成至工位快照(如:已完成至工位3;空=尚未报工)
CompletedText string `json:"completedText,omitempty"`
// Action holds the value of the "action" field.
Action string `json:"action,omitempty"`
// TargetDock holds the value of the "targetDock" field.
@@ -44,7 +46,7 @@ func (*SemiFlow) scanValues(columns []string) ([]any, error) {
values[i] = new([]byte)
case semiflow.FieldID:
values[i] = new(sql.NullInt64)
case semiflow.FieldSn, semiflow.FieldOrderNo, semiflow.FieldAction, semiflow.FieldTargetDock, semiflow.FieldOperator:
case semiflow.FieldSn, semiflow.FieldOrderNo, semiflow.FieldCompletedText, semiflow.FieldAction, semiflow.FieldTargetDock, semiflow.FieldOperator:
values[i] = new(sql.NullString)
case semiflow.FieldCreatedAt:
values[i] = new(sql.NullTime)
@@ -89,6 +91,12 @@ func (_m *SemiFlow) assignValues(columns []string, values []any) error {
return fmt.Errorf("unmarshal field doneProcessCodes: %w", err)
}
}
case semiflow.FieldCompletedText:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field completedText", values[i])
} else if value.Valid {
_m.CompletedText = value.String
}
case semiflow.FieldAction:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field action", values[i])
@@ -158,6 +166,9 @@ func (_m *SemiFlow) String() string {
builder.WriteString("doneProcessCodes=")
builder.WriteString(fmt.Sprintf("%v", _m.DoneProcessCodes))
builder.WriteString(", ")
builder.WriteString("completedText=")
builder.WriteString(_m.CompletedText)
builder.WriteString(", ")
builder.WriteString("action=")
builder.WriteString(_m.Action)
builder.WriteString(", ")
+12
View File
@@ -19,6 +19,8 @@ const (
FieldOrderNo = "order_no"
// FieldDoneProcessCodes holds the string denoting the doneprocesscodes field in the database.
FieldDoneProcessCodes = "done_process_codes"
// FieldCompletedText holds the string denoting the completedtext field in the database.
FieldCompletedText = "completed_text"
// FieldAction holds the string denoting the action field in the database.
FieldAction = "action"
// FieldTargetDock holds the string denoting the targetdock field in the database.
@@ -37,6 +39,7 @@ var Columns = []string{
FieldSn,
FieldOrderNo,
FieldDoneProcessCodes,
FieldCompletedText,
FieldAction,
FieldTargetDock,
FieldOperator,
@@ -60,6 +63,10 @@ var (
DefaultOrderNo string
// OrderNoValidator is a validator for the "orderNo" field. It is called by the builders before save.
OrderNoValidator func(string) error
// DefaultCompletedText holds the default value on creation for the "completedText" field.
DefaultCompletedText string
// CompletedTextValidator is a validator for the "completedText" field. It is called by the builders before save.
CompletedTextValidator func(string) error
// DefaultAction holds the default value on creation for the "action" field.
DefaultAction string
// ActionValidator is a validator for the "action" field. It is called by the builders before save.
@@ -96,6 +103,11 @@ func ByOrderNo(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldOrderNo, opts...).ToFunc()
}
// ByCompletedText orders the results by the completedText field.
func ByCompletedText(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCompletedText, opts...).ToFunc()
}
// ByAction orders the results by the action field.
func ByAction(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldAction, opts...).ToFunc()
+70
View File
@@ -64,6 +64,11 @@ func OrderNo(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldEQ(FieldOrderNo, v))
}
// CompletedText applies equality check predicate on the "completedText" field. It's identical to CompletedTextEQ.
func CompletedText(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldEQ(FieldCompletedText, v))
}
// Action applies equality check predicate on the "action" field. It's identical to ActionEQ.
func Action(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldEQ(FieldAction, v))
@@ -224,6 +229,71 @@ func DoneProcessCodesNotNil() predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldNotNull(FieldDoneProcessCodes))
}
// CompletedTextEQ applies the EQ predicate on the "completedText" field.
func CompletedTextEQ(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldEQ(FieldCompletedText, v))
}
// CompletedTextNEQ applies the NEQ predicate on the "completedText" field.
func CompletedTextNEQ(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldNEQ(FieldCompletedText, v))
}
// CompletedTextIn applies the In predicate on the "completedText" field.
func CompletedTextIn(vs ...string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldIn(FieldCompletedText, vs...))
}
// CompletedTextNotIn applies the NotIn predicate on the "completedText" field.
func CompletedTextNotIn(vs ...string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldNotIn(FieldCompletedText, vs...))
}
// CompletedTextGT applies the GT predicate on the "completedText" field.
func CompletedTextGT(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldGT(FieldCompletedText, v))
}
// CompletedTextGTE applies the GTE predicate on the "completedText" field.
func CompletedTextGTE(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldGTE(FieldCompletedText, v))
}
// CompletedTextLT applies the LT predicate on the "completedText" field.
func CompletedTextLT(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldLT(FieldCompletedText, v))
}
// CompletedTextLTE applies the LTE predicate on the "completedText" field.
func CompletedTextLTE(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldLTE(FieldCompletedText, v))
}
// CompletedTextContains applies the Contains predicate on the "completedText" field.
func CompletedTextContains(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldContains(FieldCompletedText, v))
}
// CompletedTextHasPrefix applies the HasPrefix predicate on the "completedText" field.
func CompletedTextHasPrefix(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldHasPrefix(FieldCompletedText, v))
}
// CompletedTextHasSuffix applies the HasSuffix predicate on the "completedText" field.
func CompletedTextHasSuffix(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldHasSuffix(FieldCompletedText, v))
}
// CompletedTextEqualFold applies the EqualFold predicate on the "completedText" field.
func CompletedTextEqualFold(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldEqualFold(FieldCompletedText, v))
}
// CompletedTextContainsFold applies the ContainsFold predicate on the "completedText" field.
func CompletedTextContainsFold(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldContainsFold(FieldCompletedText, v))
}
// ActionEQ applies the EQ predicate on the "action" field.
func ActionEQ(v string) predicate.SemiFlow {
return predicate.SemiFlow(sql.FieldEQ(FieldAction, v))
+30
View File
@@ -46,6 +46,20 @@ func (_c *SemiFlowCreate) SetDoneProcessCodes(v []int) *SemiFlowCreate {
return _c
}
// SetCompletedText sets the "completedText" field.
func (_c *SemiFlowCreate) SetCompletedText(v string) *SemiFlowCreate {
_c.mutation.SetCompletedText(v)
return _c
}
// SetNillableCompletedText sets the "completedText" field if the given value is not nil.
func (_c *SemiFlowCreate) SetNillableCompletedText(v *string) *SemiFlowCreate {
if v != nil {
_c.SetCompletedText(*v)
}
return _c
}
// SetAction sets the "action" field.
func (_c *SemiFlowCreate) SetAction(v string) *SemiFlowCreate {
_c.mutation.SetAction(v)
@@ -147,6 +161,10 @@ func (_c *SemiFlowCreate) defaults() {
v := semiflow.DefaultOrderNo
_c.mutation.SetOrderNo(v)
}
if _, ok := _c.mutation.CompletedText(); !ok {
v := semiflow.DefaultCompletedText
_c.mutation.SetCompletedText(v)
}
if _, ok := _c.mutation.Action(); !ok {
v := semiflow.DefaultAction
_c.mutation.SetAction(v)
@@ -183,6 +201,14 @@ func (_c *SemiFlowCreate) check() error {
return &ValidationError{Name: "orderNo", err: fmt.Errorf(`ent: validator failed for field "SemiFlow.orderNo": %w`, err)}
}
}
if _, ok := _c.mutation.CompletedText(); !ok {
return &ValidationError{Name: "completedText", err: errors.New(`ent: missing required field "SemiFlow.completedText"`)}
}
if v, ok := _c.mutation.CompletedText(); ok {
if err := semiflow.CompletedTextValidator(v); err != nil {
return &ValidationError{Name: "completedText", err: fmt.Errorf(`ent: validator failed for field "SemiFlow.completedText": %w`, err)}
}
}
if _, ok := _c.mutation.Action(); !ok {
return &ValidationError{Name: "action", err: errors.New(`ent: missing required field "SemiFlow.action"`)}
}
@@ -259,6 +285,10 @@ func (_c *SemiFlowCreate) createSpec() (*SemiFlow, *sqlgraph.CreateSpec) {
_spec.SetField(semiflow.FieldDoneProcessCodes, field.TypeJSON, value)
_node.DoneProcessCodes = value
}
if value, ok := _c.mutation.CompletedText(); ok {
_spec.SetField(semiflow.FieldCompletedText, field.TypeString, value)
_node.CompletedText = value
}
if value, ok := _c.mutation.Action(); ok {
_spec.SetField(semiflow.FieldAction, field.TypeString, value)
_node.Action = value
+44
View File
@@ -75,6 +75,20 @@ func (_u *SemiFlowUpdate) ClearDoneProcessCodes() *SemiFlowUpdate {
return _u
}
// SetCompletedText sets the "completedText" field.
func (_u *SemiFlowUpdate) SetCompletedText(v string) *SemiFlowUpdate {
_u.mutation.SetCompletedText(v)
return _u
}
// SetNillableCompletedText sets the "completedText" field if the given value is not nil.
func (_u *SemiFlowUpdate) SetNillableCompletedText(v *string) *SemiFlowUpdate {
if v != nil {
_u.SetCompletedText(*v)
}
return _u
}
// SetAction sets the "action" field.
func (_u *SemiFlowUpdate) SetAction(v string) *SemiFlowUpdate {
_u.mutation.SetAction(v)
@@ -161,6 +175,11 @@ func (_u *SemiFlowUpdate) check() error {
return &ValidationError{Name: "orderNo", err: fmt.Errorf(`ent: validator failed for field "SemiFlow.orderNo": %w`, err)}
}
}
if v, ok := _u.mutation.CompletedText(); ok {
if err := semiflow.CompletedTextValidator(v); err != nil {
return &ValidationError{Name: "completedText", err: fmt.Errorf(`ent: validator failed for field "SemiFlow.completedText": %w`, err)}
}
}
if v, ok := _u.mutation.Action(); ok {
if err := semiflow.ActionValidator(v); err != nil {
return &ValidationError{Name: "action", err: fmt.Errorf(`ent: validator failed for field "SemiFlow.action": %w`, err)}
@@ -214,6 +233,9 @@ func (_u *SemiFlowUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if _u.mutation.DoneProcessCodesCleared() {
_spec.ClearField(semiflow.FieldDoneProcessCodes, field.TypeJSON)
}
if value, ok := _u.mutation.CompletedText(); ok {
_spec.SetField(semiflow.FieldCompletedText, field.TypeString, value)
}
if value, ok := _u.mutation.Action(); ok {
_spec.SetField(semiflow.FieldAction, field.TypeString, value)
}
@@ -291,6 +313,20 @@ func (_u *SemiFlowUpdateOne) ClearDoneProcessCodes() *SemiFlowUpdateOne {
return _u
}
// SetCompletedText sets the "completedText" field.
func (_u *SemiFlowUpdateOne) SetCompletedText(v string) *SemiFlowUpdateOne {
_u.mutation.SetCompletedText(v)
return _u
}
// SetNillableCompletedText sets the "completedText" field if the given value is not nil.
func (_u *SemiFlowUpdateOne) SetNillableCompletedText(v *string) *SemiFlowUpdateOne {
if v != nil {
_u.SetCompletedText(*v)
}
return _u
}
// SetAction sets the "action" field.
func (_u *SemiFlowUpdateOne) SetAction(v string) *SemiFlowUpdateOne {
_u.mutation.SetAction(v)
@@ -390,6 +426,11 @@ func (_u *SemiFlowUpdateOne) check() error {
return &ValidationError{Name: "orderNo", err: fmt.Errorf(`ent: validator failed for field "SemiFlow.orderNo": %w`, err)}
}
}
if v, ok := _u.mutation.CompletedText(); ok {
if err := semiflow.CompletedTextValidator(v); err != nil {
return &ValidationError{Name: "completedText", err: fmt.Errorf(`ent: validator failed for field "SemiFlow.completedText": %w`, err)}
}
}
if v, ok := _u.mutation.Action(); ok {
if err := semiflow.ActionValidator(v); err != nil {
return &ValidationError{Name: "action", err: fmt.Errorf(`ent: validator failed for field "SemiFlow.action": %w`, err)}
@@ -460,6 +501,9 @@ func (_u *SemiFlowUpdateOne) sqlSave(ctx context.Context) (_node *SemiFlow, err
if _u.mutation.DoneProcessCodesCleared() {
_spec.ClearField(semiflow.FieldDoneProcessCodes, field.TypeJSON)
}
if value, ok := _u.mutation.CompletedText(); ok {
_spec.SetField(semiflow.FieldCompletedText, field.TypeString, value)
}
if value, ok := _u.mutation.Action(); ok {
_spec.SetField(semiflow.FieldAction, field.TypeString, value)
}