feat: 完成规格映射与采购任务创建 (#69)

This commit is contained in:
chengma
2026-08-09 22:55:14 +08:00
parent 610e9e3749
commit 4433e3af37
18 changed files with 976 additions and 135 deletions
+57 -6
View File
@@ -67,6 +67,11 @@ func (h *Handler) renderSybListWithLoginReason(c *gin.Context, keyword, pageRaw,
"读取顺运宝同步记录失败,数据没有被改动。刷新页面重试;一直失败请把这句话报给维护者。")
return
}
assignableClients, err := service.ListAssignableClients(h.db, currentUser(c), h.onlineThreshold)
if err != nil {
fail(c, http.StatusInternalServerError, "读取可分配客户端失败,数据没有被改动。")
return
}
syncStatus := service.GetSybSyncStatus()
status := msg
@@ -177,8 +182,9 @@ func (h *Handler) renderSybListWithLoginReason(c *gin.Context, keyword, pageRaw,
keyword, dateFrom, dateTo),
"HistoryFetchPagination": sybHistoryPartialPagination(history.Page, history.TotalPages,
keyword, dateFrom, dateTo),
"Pagination": service.NewPaginationView(result.Page, result.TotalPages, values.Encode()),
"DetailURL": "/syb/detail?" + detailValues.Encode(),
"Pagination": service.NewPaginationView(result.Page, result.TotalPages, values.Encode()),
"DetailURL": "/syb/detail?" + detailValues.Encode(),
"AssignableClients": assignableClients,
}))
}
@@ -592,8 +598,16 @@ func (h *Handler) SybCollectPdd(c *gin.Context) {
// 不是这一张订单的临时数据。下次遇到同一个蝦皮 SKU 自动带出,
// 操作员只需确认。见 docs/admin/03-data-model.md §5。
func (h *Handler) SybMatch(c *gin.Context) {
// TODO(骨架): upsert sku_mappings
fail(c, http.StatusNotImplemented, "规格匹配尚未实现。")
actor := currentUser(c)
operator := ""
if actor != nil {
operator = actor.UserID
}
if err := service.SaveSybMapping(h.db, c.PostForm("syb_id"), c.PostForm("pdd_option_key"), operator); err != nil {
h.sybRedirect(c, "规格映射未保存:"+err.Error())
return
}
h.sybRedirect(c, "规格映射已保存;相同蝦皮规格和 PDD 商品会自动复用。")
}
// SybCreateTask 由勾选的货运单创建采购任务。
@@ -608,8 +622,45 @@ func (h *Handler) SybMatch(c *gin.Context) {
//
// 校验不过的**不要静默跳过**,要列出来告诉操作员缺什么。
func (h *Handler) SybCreateTask(c *gin.Context) {
// TODO(骨架): 调 service.CreatePurchaseTasks(sybIDs, clientID)
fail(c, http.StatusNotImplemented, "创建采购任务尚未实现。")
ids := c.PostFormArray("ids")
prices := c.PostFormArray("max_price_yuan")
if len(ids) == 0 {
h.sybRedirect(c, "没有选择货运单明细,没有创建采购任务。")
return
}
requests := make([]service.PurchaseTaskRequest, 0, len(ids))
preFailures := make([]service.TaskCreateError, 0)
for i, sybID := range ids {
if i >= len(prices) {
preFailures = append(preFailures, service.TaskCreateError{SybID: sybID, Reason: "人民币价格上限不能为空"})
continue
}
cent, err := service.ParsePriceYuanToCent(prices[i])
if err != nil {
preFailures = append(preFailures, service.TaskCreateError{SybID: sybID, Reason: err.Error()})
continue
}
requests = append(requests, service.PurchaseTaskRequest{SybID: sybID, MaxPriceCent: cent})
}
result, err := service.CreatePurchaseTasks(h.db, currentUser(c), requests, c.PostForm("client_id"))
if err != nil {
h.sybRedirect(c, "采购任务没有创建:"+err.Error())
return
}
result.Failures = append(preFailures, result.Failures...)
h.sybRedirect(c, purchaseTaskResultMessage(result))
}
func purchaseTaskResultMessage(result service.PurchaseTaskResult) string {
parts := []string{fmt.Sprintf("已创建 %d 个采购任务", result.Created)}
if len(result.Failures) > 0 {
failures := make([]string, 0, len(result.Failures))
for _, failure := range result.Failures {
failures = append(failures, failure.SybID+"("+failure.Reason+")")
}
parts = append(parts, "未创建:"+strings.Join(failures, ";"))
}
return strings.Join(parts, "。")
}
// SybDelete 批量删除货运单。