Files
cmautobuy/admin/service/inner_code_page.go
T

144 lines
4.7 KiB
Go

package service
import (
"database/sql"
"fmt"
"strings"
"cmautobuy/admin/model"
"cmautobuy/admin/repository"
)
// InnerCodeStatusOption 是页面状态筛选项。
type InnerCodeStatusOption struct {
Value string
Text string
}
var innerCodeStatusOptions = []InnerCodeStatusOption{
{"", "全部状态"},
{string(model.InnerCodePending), "待匹配"},
{string(model.InnerCodeReady), "可回写"},
{string(model.InnerCodeApplying), "回写中"},
{string(model.InnerCodeUpdated), "已回写"},
{string(model.InnerCodeAlreadyFilled), "已存在"},
{string(model.InnerCodeSkipped), "已跳过"},
{string(model.InnerCodeFailed), "失败"},
{string(model.InnerCodeNeedsCheck), "需核对"},
}
// InnerCodeRowView 是正式页面的一行。
type InnerCodeRowView struct {
ID int64
BusinessDate string
OrderNumber string
Stall string
SpecRaw string
SybSpec string
InnerCode string
RemoteInnerCode string
Status string
StatusText string
StatusClass string
ResultMessage string
UpdatedAt string
CanSelect bool
HasRemoteOldCode bool
CanRecheck bool
}
// InnerCodeListPage 是列表、分页和底栏统计。
type InnerCodeListPage struct {
Rows []InnerCodeRowView
Total int
Page int
TotalPages int
Status string
Keyword string
Date string
Counts repository.InnerCodeStatusCounts
IsFiltered bool
}
// InnerCodeStatusOptions 返回稳定顺序的筛选项副本。
func InnerCodeStatusOptions() []InnerCodeStatusOption {
return append([]InnerCodeStatusOption(nil), innerCodeStatusOptions...)
}
// ListInnerCodePage 校验筛选并返回统一 20 条 SQL 分页结果。
func ListInnerCodePage(db *sql.DB, businessDate, status, keyword string, requestedPage int) (*InnerCodeListPage, error) {
status = strings.TrimSpace(status)
if !validInnerCodeStatusFilter(status) {
status = ""
}
keyword = strings.TrimSpace(keyword)
filter := repository.InnerCodeListFilter{BusinessDate: businessDate, Status: status, Keyword: keyword}
total, err := repository.CountInnerCodeRecords(db, filter)
if err != nil {
return nil, err
}
totalPages := TotalPages(total)
page := ClampPage(requestedPage, totalPages)
records, err := repository.ListInnerCodeRecords(db, filter, PageSize, (page-1)*PageSize)
if err != nil {
return nil, err
}
counts, err := repository.CountInnerCodeStatuses(db, businessDate)
if err != nil {
return nil, err
}
result := &InnerCodeListPage{Total: total, Page: page, TotalPages: totalPages,
Status: status, Keyword: keyword, Date: businessDate, Counts: counts,
IsFiltered: status != "" || keyword != ""}
result.Rows = make([]InnerCodeRowView, 0, len(records))
for _, record := range records {
result.Rows = append(result.Rows, innerCodeRowView(record))
}
return result, nil
}
func validInnerCodeStatusFilter(status string) bool {
for _, option := range innerCodeStatusOptions {
if option.Value == status {
return true
}
}
return false
}
func innerCodeRowView(record model.InnerCodeRecord) InnerCodeRowView {
statusText := map[model.InnerCodeStatus]string{
model.InnerCodePending: "待匹配", model.InnerCodeReady: "可回写",
model.InnerCodeApplying: "回写中", model.InnerCodeUpdated: "已回写",
model.InnerCodeAlreadyFilled: "已存在", model.InnerCodeSkipped: "已跳过",
model.InnerCodeFailed: "失败", model.InnerCodeNeedsCheck: "需核对",
}[record.Status]
if statusText == "" {
statusText = "未知"
}
return InnerCodeRowView{
ID: record.ID, BusinessDate: record.BusinessDate, OrderNumber: record.OrderNumber,
Stall: displayInnerCodeValue(record.Stall), SpecRaw: displayInnerCodeValue(record.SpecRaw),
SybSpec: displayInnerCodeValue(record.SybSpec), InnerCode: record.InnerCode,
RemoteInnerCode: displayInnerCodeValue(record.RemoteInnerCode), Status: string(record.Status),
StatusText: statusText, StatusClass: "inner-code-status-" + string(record.Status),
ResultMessage: displayInnerCodeValue(record.ResultMessage), UpdatedAt: formatLocalTime(record.UpdatedAt),
CanSelect: record.Status == model.InnerCodeReady,
HasRemoteOldCode: record.Status == model.InnerCodeReady && record.RemoteInnerCode != "",
CanRecheck: record.Status == model.InnerCodeNeedsCheck,
}
}
func displayInnerCodeValue(value string) string {
if strings.TrimSpace(value) == "" {
return "—"
}
return value
}
// InnerCodeStatusMessage 生成底栏可读统计。
func InnerCodeStatusMessage(page *InnerCodeListPage) string {
return fmt.Sprintf("共 %d 条,可回写 %d 条,需核对 %d 条;当前筛选 %d 条",
page.Counts.Total, page.Counts.Ready, page.Counts.NeedsCheck, page.Total)
}