feat: 支持人工修改蝦皮规格 (#215)
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"cmautobuy/admin/model"
|
||||
"cmautobuy/admin/repository"
|
||||
)
|
||||
|
||||
const maxShopeeSKUFieldRunes = 500
|
||||
|
||||
// UpdateShopeeSKUManual 保存采购员对现有蝦皮规格的人工修正。
|
||||
// 只修改颜色、尺码和建议说明;规格原文、身份字段和既有采购数据保持不变。
|
||||
func UpdateShopeeSKUManual(db *sql.DB, actor *model.User, goodsID, skuRecordID,
|
||||
color, size, advice string, now time.Time) error {
|
||||
if actor == nil || actor.Status != model.UserActive {
|
||||
return ErrUnauthenticated
|
||||
}
|
||||
goodsID = strings.TrimSpace(goodsID)
|
||||
skuRecordID = strings.TrimSpace(skuRecordID)
|
||||
color = strings.TrimSpace(color)
|
||||
size = strings.TrimSpace(size)
|
||||
advice = strings.TrimSpace(advice)
|
||||
if goodsID == "" {
|
||||
return invalidFieldInput("shopee_goods_id", "蝦皮商品编号不能为空")
|
||||
}
|
||||
if skuRecordID == "" {
|
||||
return invalidFieldInput("sku_record_id", "蝦皮规格记录编号不能为空")
|
||||
}
|
||||
if color == "" {
|
||||
return invalidFieldInput("color", "颜色不能为空")
|
||||
}
|
||||
if size == "" {
|
||||
return invalidFieldInput("size", "尺码不能为空")
|
||||
}
|
||||
for _, field := range []struct {
|
||||
name, label, value string
|
||||
}{{"color", "颜色", color}, {"size", "尺码", size}, {"advice", "建议说明", advice}} {
|
||||
if utf8.RuneCountInString(field.value) > maxShopeeSKUFieldRunes {
|
||||
return invalidFieldInput(field.name, "%s最多 500 个字符", field.label)
|
||||
}
|
||||
}
|
||||
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
state, err := repository.GetShopeeSKUManualState(tx, skuRecordID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if state == nil || state.GoodsID != goodsID {
|
||||
return invalidFieldInput("sku_record_id", "蝦皮规格不存在或不属于当前商品,请刷新页面后重试")
|
||||
}
|
||||
sources, err := decodeShopeeSKUProvenance(state.FieldSources)
|
||||
if err != nil {
|
||||
return fmt.Errorf("读取蝦皮规格字段来源失败: %w", err)
|
||||
}
|
||||
observedTimes, err := decodeShopeeSKUProvenance(state.FieldObservedAt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("读取蝦皮规格字段时间失败: %w", err)
|
||||
}
|
||||
at := now.UTC().Format(model.TimeLayout)
|
||||
for _, field := range []string{"color", "size", "advice"} {
|
||||
sources[field] = "manual"
|
||||
observedTimes[field] = at
|
||||
}
|
||||
sourcesJSON, err := json.Marshal(sources)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
timesJSON, err := json.Marshal(observedTimes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updated, err := repository.UpdateShopeeSKUManualFields(tx, skuRecordID, goodsID,
|
||||
color, size, advice, string(sourcesJSON), string(timesJSON), at)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !updated {
|
||||
return invalidFieldInput("sku_record_id", "蝦皮规格已发生变化,请刷新页面后重试")
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func decodeShopeeSKUProvenance(raw string) (map[string]string, error) {
|
||||
values := map[string]string{}
|
||||
if strings.TrimSpace(raw) == "" {
|
||||
return values, nil
|
||||
}
|
||||
if err := json.Unmarshal([]byte(raw), &values); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
Reference in New Issue
Block a user