feat: 复用颜色映射生成完整采购规格 (#295)
This commit is contained in:
@@ -77,7 +77,14 @@ func UpsertSpecMapping(q Execer, m model.SpecMapping) error {
|
||||
// UpsertAutomaticSpecMapping 只在没有人工映射且上下文版本变化时写入自动结果。
|
||||
// 同一上下文的并发 AI 请求由先写入者获胜;人工保存无论先后都不会被自动结果覆盖。
|
||||
func UpsertAutomaticSpecMapping(q Execer, m model.SpecMapping) error {
|
||||
_, err := q.Exec(`
|
||||
_, err := UpsertAutomaticSpecMappingChanged(q, m)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpsertAutomaticSpecMappingChanged 与 UpsertAutomaticSpecMapping 使用同一条并发安全 SQL,
|
||||
// 并返回本次是否真正插入或更新。调用方据此避免为幂等重放重复追加决策审计。
|
||||
func UpsertAutomaticSpecMappingChanged(q Execer, m model.SpecMapping) (bool, error) {
|
||||
result, err := q.Exec(`
|
||||
INSERT INTO spec_mappings
|
||||
(shopee_goods_id,spec_key,pdd_goods_id,pdd_option_key,pdd_options,spec_raw,
|
||||
mapped_at,mapped_by,source,source_provider_id,source_model,confidence_bps,
|
||||
@@ -101,9 +108,30 @@ func UpsertAutomaticSpecMapping(q Execer, m model.SpecMapping) error {
|
||||
nullableText(m.SourceModel), nullableInt(m.ConfidenceBPS, m.ConfidenceSet), nullableText(m.SourceReason),
|
||||
nullableText(m.SourceVersion), nullableText(m.ContextVersion))
|
||||
if err != nil {
|
||||
return fmt.Errorf("保存自动规格映射失败: %w", err)
|
||||
return false, fmt.Errorf("保存自动规格映射失败: %w", err)
|
||||
}
|
||||
return nil
|
||||
rows, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("读取自动规格映射保存结果失败: %w", err)
|
||||
}
|
||||
return rows > 0, nil
|
||||
}
|
||||
|
||||
// DeleteAutomaticSpecMappingByVersion 只删除指定规则自己生成的映射。
|
||||
// 人工和 AI 结果以及其他规则版本永远不受影响。
|
||||
func DeleteAutomaticSpecMappingByVersion(q Execer, shopeeGoodsID, specKey, pddGoodsID, sourceVersion string) (bool, error) {
|
||||
result, err := q.Exec(`DELETE FROM spec_mappings
|
||||
WHERE shopee_goods_id=? AND spec_key=? AND pdd_goods_id=?
|
||||
AND source='rule' AND source_version=?`,
|
||||
shopeeGoodsID, specKey, pddGoodsID, sourceVersion)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("清除失效的颜色辅助规格映射失败: %w", err)
|
||||
}
|
||||
rows, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("读取颜色辅助规格映射清除结果失败: %w", err)
|
||||
}
|
||||
return rows > 0, nil
|
||||
}
|
||||
|
||||
func InsertAISpecMatchDecision(q Execer, d model.AISpecMatchDecision) error {
|
||||
|
||||
@@ -332,6 +332,25 @@ func ListShopeePddLinksByGoodsIDs(q Execer, goodsIDs []string) (map[string]strin
|
||||
return links, nil
|
||||
}
|
||||
|
||||
// ListShopeeGoodsIDsByPddGoodsID 返回当前仍关联指定 PDD 商品的蝦皮商品。
|
||||
func ListShopeeGoodsIDsByPddGoodsID(q Execer, pddGoodsID string) ([]string, error) {
|
||||
rows, err := q.Query(`SELECT goods_id FROM shopee_products
|
||||
WHERE pdd_goods_id=? AND deleted_at IS NULL ORDER BY goods_id`, pddGoodsID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询 PDD 商品 %s 的蝦皮关联失败: %w", pddGoodsID, err)
|
||||
}
|
||||
defer rows.Close()
|
||||
var result []string
|
||||
for rows.Next() {
|
||||
var goodsID string
|
||||
if err := rows.Scan(&goodsID); err != nil {
|
||||
return nil, fmt.Errorf("读取 PDD 商品的蝦皮关联失败: %w", err)
|
||||
}
|
||||
result = append(result, goodsID)
|
||||
}
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
// UpdateShopeePddLink 更新蝦皮商品当前关联的 PDD 商品。
|
||||
// 调用方必须先在同一事务里保证 PDD 商品存在,避免留下悬空关联。
|
||||
func UpdateShopeePddLink(q Execer, shopeeGoodsID, pddGoodsID, pddURL string) error {
|
||||
|
||||
@@ -726,6 +726,26 @@ func GetSybOrderContext(q Execer, sybID string) (*SybOrderContext, error) {
|
||||
return &row, nil
|
||||
}
|
||||
|
||||
// ListSybIDsByShopeeGoodsID 限定读取一个蝦皮商品已有的有效规格明细,供写入事件幂等派生。
|
||||
func ListSybIDsByShopeeGoodsID(q Execer, goodsID string) ([]string, error) {
|
||||
rows, err := q.Query(`SELECT syb_id FROM syb_orders
|
||||
WHERE shopee_goods_id=? AND spec_key IS NOT NULL AND spec_key<>''
|
||||
ORDER BY syb_id`, goodsID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询蝦皮商品 %s 的顺运宝明细失败: %w", goodsID, err)
|
||||
}
|
||||
defer rows.Close()
|
||||
var result []string
|
||||
for rows.Next() {
|
||||
var sybID string
|
||||
if err := rows.Scan(&sybID); err != nil {
|
||||
return nil, fmt.Errorf("读取颜色辅助顺运宝明细失败: %w", err)
|
||||
}
|
||||
result = append(result, sybID)
|
||||
}
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
// ListSybOrders 按筛选条件分页查货运单明细列表,按更新时间倒序。
|
||||
func ListSybOrders(q Execer, filter SybOrderFilter, limit, offset int) ([]model.SybOrder, error) {
|
||||
where, args := sybOrderFilterClause(filter)
|
||||
|
||||
Reference in New Issue
Block a user