Align origin/main with upstream/main (GitHub). The two branches diverged due to pre-rebase vs post-rebase merge commits for the k8s-amd64-dockerfiles feature. Includes: multi-stage Go compilation Dockerfiles, pan-bolt inventory features, CRM relations, Excel import tooling, proto/gRPC updates, migration scripts, and tools/ directory. Excludes deploy/bin/ pre-compiled binaries (arm64, not needed for amd64 K3s cluster; builds use multi-stage Dockerfiles now).
124 lines
4.2 KiB
Go
124 lines
4.2 KiB
Go
package model
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
|
)
|
|
|
|
var _ InvProductPanModel = (*customInvProductPanModel)(nil)
|
|
|
|
// PanListItem is the aggregated view row for the pan-dimension panel.
|
|
// Colors is aggregated from the bolts on this pan; spec is omitted (product-level only).
|
|
type PanListItem struct {
|
|
PanId string `db:"pan_id"`
|
|
ProductId string `db:"product_id"`
|
|
Name string `db:"name"`
|
|
Position string `db:"position"`
|
|
ProductName string `db:"product_name"`
|
|
Colors string `db:"colors"`
|
|
BoltCount int64 `db:"bolt_count"`
|
|
TotalLengthM float64 `db:"total_length_m"`
|
|
}
|
|
|
|
type (
|
|
InvProductPanModel interface {
|
|
invProductPanModel
|
|
FindByProductId(ctx context.Context, productId string) ([]*InvProductPan, error)
|
|
DeleteByProductId(ctx context.Context, productId string) error
|
|
BulkReplace(ctx context.Context, productId, tenantId string, pans []*InvProductPan) error
|
|
FindPanList(ctx context.Context, tenantId string, page, pageSize int64, productName, position string) ([]*PanListItem, int64, error)
|
|
}
|
|
|
|
customInvProductPanModel struct {
|
|
*defaultInvProductPanModel
|
|
}
|
|
)
|
|
|
|
func NewInvProductPanModel(conn sqlx.SqlConn) InvProductPanModel {
|
|
return &customInvProductPanModel{
|
|
defaultInvProductPanModel: newInvProductPanModel(conn),
|
|
}
|
|
}
|
|
|
|
func (m *customInvProductPanModel) FindByProductId(ctx context.Context, productId string) ([]*InvProductPan, error) {
|
|
var list []*InvProductPan
|
|
query := fmt.Sprintf("SELECT %s FROM %s WHERE `product_id` = ? ORDER BY `sort_order`", invProductPanRows, m.table)
|
|
err := m.conn.QueryRowsCtx(ctx, &list, query, productId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return list, nil
|
|
}
|
|
|
|
func (m *customInvProductPanModel) DeleteByProductId(ctx context.Context, productId string) error {
|
|
query := fmt.Sprintf("DELETE FROM %s WHERE `product_id` = ?", m.table)
|
|
_, err := m.conn.ExecCtx(ctx, query, productId)
|
|
return err
|
|
}
|
|
|
|
func (m *customInvProductPanModel) FindPanList(ctx context.Context, tenantId string, page, pageSize int64, productName, position string) ([]*PanListItem, int64, error) {
|
|
where := "WHERE pan.tenant_id = ? AND p.deleted_at IS NULL"
|
|
args := []interface{}{tenantId}
|
|
|
|
if productName != "" {
|
|
where += " AND p.product_name LIKE ?"
|
|
args = append(args, "%"+productName+"%")
|
|
}
|
|
if position != "" {
|
|
where += " AND pan.position LIKE ?"
|
|
args = append(args, "%"+position+"%")
|
|
}
|
|
|
|
countQuery := fmt.Sprintf(`SELECT COUNT(DISTINCT pan.pan_id)
|
|
FROM %s pan JOIN inv_product p ON p.product_id = pan.product_id %s`, m.table, where)
|
|
var total int64
|
|
if err := m.conn.QueryRowCtx(ctx, &total, countQuery, args...); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
query := fmt.Sprintf(`SELECT pan.pan_id, pan.product_id, pan.name, pan.position,
|
|
p.product_name,
|
|
COALESCE(GROUP_CONCAT(DISTINCT b.color ORDER BY b.color SEPARATOR ', '), '') AS colors,
|
|
COUNT(b.bolt_id) AS bolt_count,
|
|
COALESCE(SUM(b.length_m), 0) AS total_length_m
|
|
FROM %s pan
|
|
JOIN inv_product p ON p.product_id = pan.product_id
|
|
LEFT JOIN inv_product_bolt b ON b.pan_id = pan.pan_id
|
|
%s
|
|
GROUP BY pan.pan_id
|
|
ORDER BY pan.created_at DESC
|
|
LIMIT ? OFFSET ?`, m.table, where)
|
|
args = append(args, pageSize, (page-1)*pageSize)
|
|
|
|
var list []*PanListItem
|
|
if err := m.conn.QueryRowsCtx(ctx, &list, query, args...); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return list, total, nil
|
|
}
|
|
|
|
func (m *customInvProductPanModel) BulkReplace(ctx context.Context, productId, tenantId string, pans []*InvProductPan) error {
|
|
return m.conn.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
delQuery := fmt.Sprintf("DELETE FROM %s WHERE `product_id` = ?", m.table)
|
|
if _, err := session.ExecCtx(ctx, delQuery, productId); err != nil {
|
|
return err
|
|
}
|
|
if len(pans) == 0 {
|
|
return nil
|
|
}
|
|
placeholder := "(?, ?, ?, ?, ?, ?)"
|
|
placeholders := make([]string, len(pans))
|
|
args := make([]interface{}, 0, len(pans)*6)
|
|
for i, p := range pans {
|
|
placeholders[i] = placeholder
|
|
args = append(args, p.PanId, productId, p.Name, p.Position, p.SortOrder, tenantId)
|
|
}
|
|
insQuery := fmt.Sprintf("INSERT INTO %s (%s) VALUES %s", m.table, invProductPanRowsExpectAutoSet, strings.Join(placeholders, ","))
|
|
_, err := session.ExecCtx(ctx, insQuery, args...)
|
|
return err
|
|
})
|
|
}
|