Files

103 lines
3.0 KiB
Go

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
}