feat: 增加顺运宝批量 AI 规格匹配 (#202)

This commit is contained in:
chengma
2026-08-14 10:30:08 +08:00
parent 0201dab98c
commit d64579e9b3
26 changed files with 1289 additions and 26 deletions
+66 -5
View File
@@ -1064,7 +1064,13 @@ type SybOrderView struct {
NeedsAttention bool
CanCollect bool
CanPurchase bool
CanAIMatch bool
SelectionActions string
SelectionHint string
MappingSource string
MappingSourceText string
MappingSourceClass string
MappingSourceHelp string
DefaultUnitPrice string
DefaultTotalPrice string
MappedPddChoice string
@@ -1081,6 +1087,7 @@ const (
SybStagePddCollectingStale = "pdd_collecting_stale"
SybStagePddFailed = "pdd_failed"
SybStageMappingPending = "mapping_pending"
SybStageAIMatched = "ai_matched"
SybStagePurchaseReady = "purchase_ready"
SybStageTaskCreated = "task_created"
SybStagePurchaseCompleted = "purchase_completed"
@@ -1104,6 +1111,7 @@ func SybStageOptions() []SybStageOption {
{Value: SybStagePddCollectingStale, Text: "PDD 采集中(超时)"},
{Value: SybStagePddFailed, Text: "PDD 采集失败"},
{Value: SybStageMappingPending, Text: "规格待匹配"},
{Value: SybStageAIMatched, Text: "AI规格匹配"},
{Value: SybStagePurchaseReady, Text: "可创建采购任务"},
{Value: SybStageTaskCreated, Text: "已创建采购任务"},
{Value: SybStagePurchaseCompleted, Text: "采购完成"},
@@ -1253,6 +1261,7 @@ func ListSybOrdersView(db *sql.DB, keyword, shop, stage string, page int) (*SybL
}
if stage == SybStagePddCollecting || stage == SybStagePddCollectingStale ||
stage == SybStageMappingPending || stage == SybStagePurchaseReady ||
stage == SybStageAIMatched ||
stage == SybStageTaskCreated || stage == SybStagePurchaseCompleted ||
stage == SybStagePurchaseReview || stage == SybStagePurchaseBlocked {
return listAdvancedSybStage(db, orderNos, shop, stage, page)
@@ -1311,7 +1320,11 @@ func listAdvancedSybStage(db *sql.DB, orderNos []string, shop, stage string, pag
filtered := make([]repository.SybOrderContext, 0)
for _, context := range contexts {
value, _, _, _ := sybStageFor(context)
if value == stage {
matches := value == stage
if stage == SybStageAIMatched {
matches = value == SybStagePurchaseReady && context.MappingSource == "ai" && mappingIsValid(context)
}
if matches {
filtered = append(filtered, context)
}
}
@@ -1378,14 +1391,46 @@ func sybOrderViewFor(context repository.SybOrderContext) SybOrderView {
v.CanCollect = v.Stage == SybStagePddPending || v.Stage == SybStagePddFailed ||
v.Stage == SybStagePddCollectingStale
v.CanPurchase = v.Stage == SybStagePurchaseReady
v.CanAIMatch = v.Stage == SybStageMappingPending || v.Stage == SybStagePurchaseReady
actions := make([]string, 0, 3)
if v.CanCollect {
actions = append(actions, "collect")
}
if v.CanPurchase {
actions = append(actions, "purchase")
}
if v.CanAIMatch {
actions = append(actions, "ai")
}
v.SelectionActions = strings.Join(actions, " ")
switch {
case v.CanCollect:
v.SelectionHint = "可批量创建 PDD 采集任务"
case v.CanPurchase:
v.SelectionHint = "可批量创建采购任务"
case len(actions) > 0:
labels := make([]string, 0, len(actions))
if v.CanCollect {
labels = append(labels, "创建采集")
}
if v.CanPurchase {
labels = append(labels, "创建采购")
}
if v.CanAIMatch {
labels = append(labels, "AI规格匹配")
}
v.SelectionHint = "可用于:" + strings.Join(labels, "、")
default:
v.SelectionHint = "当前阶段不能批量操作:" + v.StageHelp
}
if context.MappingOptionKey != "" {
v.MappingSource = context.MappingSource
if v.MappingSource == "" {
v.MappingSource = "manual"
}
v.MappingSourceText = mappingSourceText(v.MappingSource)
v.MappingSourceClass = "source-" + v.MappingSource
v.MappingSourceHelp = context.MappingReason
if !mappingIsValid(context) {
v.MappingSourceText += "(已失效)"
}
}
if v.CanPurchase {
v.MappingOptionKey = context.MappingOptionKey
v.ContextVersion = mappingContextVersion(context)
@@ -1451,6 +1496,10 @@ type SybProcessingDetail struct {
RecommendationNotice string
MappingValid bool
HasActiveTask bool
MappingSource string
MappingSourceText string
MappingSourceClass string
MappingSourceHelp string
}
func GetSybProcessingDetail(db *sql.DB, sybID string) (*SybProcessingDetail, error) {
@@ -1472,6 +1521,18 @@ func GetSybProcessingDetail(db *sql.DB, sybID string) (*SybProcessingDetail, err
(d.Stage == SybStagePddPending || d.Stage == SybStagePddFailed ||
d.Stage == SybStagePddCollectingStale)
d.HasActiveTask = context.HasActiveTask
if context.MappingOptionKey != "" {
d.MappingSource = context.MappingSource
if d.MappingSource == "" {
d.MappingSource = "manual"
}
d.MappingSourceText = mappingSourceText(d.MappingSource)
d.MappingSourceClass = "source-" + d.MappingSource
d.MappingSourceHelp = context.MappingReason
if !mappingIsValid(*context) {
d.MappingSourceText += "(已失效)"
}
}
if context.PddCollectStatus == string(model.CollectCollected) && context.PddSkusJSON != "" {
choices, keys, names, parseErr := pddOptionChoices(context.PddSkusJSON)
if parseErr == nil {