refactor(wms/mes): 统一多场景查询逻辑,移除关键字混搜

1. 移除所有多字段关键字混搜,改为各筛选字段独立查询
2. 调整excel导出相关逻辑,优化文件名处理与导入模板
3. 修复物料导入的类型解析与token获取逻辑
4. 更新依赖与前端页面文案、筛选参数
This commit is contained in:
SunYF
2026-09-08 13:43:08 +08:00
parent e852c7cd37
commit 6d8bb75696
16 changed files with 141 additions and 114 deletions
@@ -40,7 +40,7 @@ func ListProductTypesPageHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
page := atoiDefault(q.Get("page"), 1)
pageSize := atoiDefault(q.Get("pageSize"), 20)
total, list, wmsOnline, err := logic.New(svcCtx).ListProductTypesPage(r.Context(),
q.Get("keyword"), q.Get("isActive"), page, pageSize)
q.Get("code"), q.Get("name"), q.Get("category"), q.Get("isActive"), page, pageSize)
if err != nil {
httpx.Fail(w, 3001, err.Error())
return
@@ -96,7 +96,7 @@ func ExportProductTypesHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
b, err := svcCtx.Wms.ExportProductTypes(r.Context(),
q.Get("keyword"), q.Get("isActive"), q.Get("startDate"), q.Get("endDate"))
q.Get("code"), q.Get("name"), q.Get("category"), q.Get("isActive"), q.Get("startDate"), q.Get("endDate"))
if err != nil {
httpx.Fail(w, 3002, "导出失败(WMS 不可达):"+err.Error())
return
+20 -13
View File
@@ -71,24 +71,25 @@ func (s *Service) DeleteProductType(ctx context.Context, id int) error {
// ListProductTypes 全量列表(下拉/兼容形态,id asc 新建在底部)。
// degraded=false 表示 WMS 不可达、数据来自本地只读缓存。
func (s *Service) ListProductTypes(ctx context.Context) ([]wmsclient.ProductTypeRow, bool, error) {
list, err := s.ctx.Wms.ProductTypes(ctx, "", "")
list, err := s.ctx.Wms.ProductTypes(ctx, "")
if err == nil {
return list, true, nil
}
fallback, ferr := s.localProductTypes(ctx, "")
fallback, ferr := s.localProductTypes(ctx, "", "", "")
if ferr != nil {
return nil, false, errors.New("WMS 不可达且本地缓存读取失败")
}
return fallback, false, nil
}
// ListProductTypesPage 分页+搜索(管理页真分页)
func (s *Service) ListProductTypesPage(ctx context.Context, keyword, isActive string, page, pageSize int) (int64, []wmsclient.ProductTypeRow, bool, error) {
total, list, err := s.ctx.Wms.ProductTypePage(ctx, keyword, isActive, page, pageSize)
// ListProductTypesPage 分页+搜索(管理页真分页)
// 2026-09-08 禁止关键字混搜:编码/名称/类别各自独立模糊。
func (s *Service) ListProductTypesPage(ctx context.Context, code, name, category, isActive string, page, pageSize int) (int64, []wmsclient.ProductTypeRow, bool, error) {
total, list, err := s.ctx.Wms.ProductTypePage(ctx, code, name, category, isActive, page, pageSize)
if err == nil {
return total, list, true, nil
}
fallback, ferr := s.localProductTypes(ctx, keyword)
fallback, ferr := s.localProductTypes(ctx, code, name, category)
if ferr != nil {
return 0, nil, false, errors.New("WMS 不可达且本地缓存读取失败")
}
@@ -104,7 +105,7 @@ func (s *Service) ListProductTypesPage(ctx context.Context, keyword, isActive st
}
func (s *Service) productTypeByID(ctx context.Context, id int) (*wmsclient.ProductTypeRow, error) {
list, err := s.ctx.Wms.ProductTypes(ctx, "", "")
list, err := s.ctx.Wms.ProductTypes(ctx, "")
if err == nil {
for i := range list {
if list[i].ID == id {
@@ -121,18 +122,24 @@ func (s *Service) productTypeByID(ctx context.Context, id int) (*wmsclient.Produ
return &wmsclient.ProductTypeRow{ID: pt.ID, Code: pt.Code, Name: pt.Name}, nil
}
func (s *Service) localProductTypes(ctx context.Context, keyword string) ([]wmsclient.ProductTypeRow, error) {
// localProductTypes 本地只读缓存过滤(降级用):编码/名称/类别各自独立模糊匹配
func (s *Service) localProductTypes(ctx context.Context, code, name, category string) ([]wmsclient.ProductTypeRow, error) {
list, err := s.ctx.EntClient.ProductType.Query().Order(ent.Asc(producttype.FieldID)).All(ctx)
if err != nil {
return nil, err
}
codeKw := strings.ToLower(strings.TrimSpace(code))
nameKw := strings.ToLower(strings.TrimSpace(name))
catKw := strings.ToLower(strings.TrimSpace(category))
rows := make([]wmsclient.ProductTypeRow, 0, len(list))
kw := strings.ToLower(strings.TrimSpace(keyword))
for _, p := range list {
if kw != "" &&
!strings.Contains(strings.ToLower(p.Code), kw) &&
!strings.Contains(strings.ToLower(p.Name), kw) &&
!strings.Contains(strings.ToLower(p.Category), kw) {
if codeKw != "" && !strings.Contains(strings.ToLower(p.Code), codeKw) {
continue
}
if nameKw != "" && !strings.Contains(strings.ToLower(p.Name), nameKw) {
continue
}
if catKw != "" && !strings.Contains(strings.ToLower(p.Category), catKw) {
continue
}
rows = append(rows, wmsclient.ProductTypeRow{
+25 -13
View File
@@ -6,6 +6,7 @@ import (
"context"
"encoding/json"
"net/http"
"net/url"
"time"
)
@@ -151,12 +152,9 @@ func (c *Client) putJSON(ctx context.Context, path string, body any) error {
return nil
}
// ProductTypes 全量产品型号(item_type=3id asc,新建在底部)。keyword/isActive 可空。
func (c *Client) ProductTypes(ctx context.Context, keyword, isActive string) ([]ProductTypeRow, error) {
// ProductTypes 全量产品型号(item_type=3id asc,新建在底部)。isActive 可空。
func (c *Client) ProductTypes(ctx context.Context, isActive string) ([]ProductTypeRow, error) {
q := "/api/internal/product-types?"
if keyword != "" {
q += "keyword=" + keyword + "&"
}
if isActive != "" {
q += "isActive=" + isActive
}
@@ -167,11 +165,18 @@ func (c *Client) ProductTypes(ctx context.Context, keyword, isActive string) ([]
return list, nil
}
// ProductTypePage 分页+搜索(产品型号管理页真分页)
func (c *Client) ProductTypePage(ctx context.Context, keyword, isActive string, page, pageSize int) (int64, []ProductTypeRow, error) {
// ProductTypePage 分页+搜索(产品型号管理页真分页)
// 2026-09-08 禁止关键字混搜:编码/名称/类别各自独立模糊。
func (c *Client) ProductTypePage(ctx context.Context, code, name, category, isActive string, page, pageSize int) (int64, []ProductTypeRow, error) {
q := fmt.Sprintf("/api/internal/product-types?page=%d&pageSize=%d", page, pageSize)
if keyword != "" {
q += "&keyword=" + keyword
if code != "" {
q += "&code=" + url.QueryEscape(code)
}
if name != "" {
q += "&name=" + url.QueryEscape(name)
}
if category != "" {
q += "&category=" + url.QueryEscape(category)
}
if isActive != "" {
q += "&isActive=" + isActive
@@ -205,11 +210,18 @@ func (c *Client) DeleteProductType(ctx context.Context, id int) error {
return c.post(ctx, "/api/internal/product-types/delete", map[string]any{"id": id})
}
// ExportProductTypes 拉取产品型号导出 xlsx 字节流(WMS 端执行统一导出时间规则)
func (c *Client) ExportProductTypes(ctx context.Context, keyword, isActive, startDate, endDate string) ([]byte, error) {
// ExportProductTypes 拉取产品型号导出 xlsx 字节流(WMS 端执行统一导出时间规则)
// 编码/名称/类别各自独立模糊筛选(禁止关键字混搜)。
func (c *Client) ExportProductTypes(ctx context.Context, code, name, category, isActive, startDate, endDate string) ([]byte, error) {
q := "/api/internal/product-types/export?"
if keyword != "" {
q += "keyword=" + keyword + "&"
if code != "" {
q += "code=" + url.QueryEscape(code) + "&"
}
if name != "" {
q += "name=" + url.QueryEscape(name) + "&"
}
if category != "" {
q += "category=" + url.QueryEscape(category) + "&"
}
if isActive != "" {
q += "isActive=" + isActive + "&"