package mohong import ( "encoding/json" "fmt" "strings" "hfb_sys/backend/internal/model" "hfb_sys/backend/pkg/money" ) func toProductDTO(row model.MohongProduct, includeAdminFields bool) ProductDTO { images := decodeStringList(row.ImageURLs) dto := ProductDTO{ ID: row.ID, CategoryID: row.CategoryID, Title: row.Title, CoverURL: row.CoverURL, ImageURLs: images, Description: row.Description, PriceCent: row.PriceCent, Price: money.Format(row.PriceCent), OriginalPriceCent: row.OriginalPriceCent, Unit: row.Unit, Stock: row.Stock, SortOrder: row.SortOrder, Status: row.Status, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt, } if row.OriginalPriceCent > 0 { dto.OriginalPrice = money.Format(row.OriginalPriceCent) } if includeAdminFields { dto.QrcodeImageURL = row.QrcodeImageURL } return dto } func toProductDTOWithCategory(row model.MohongProduct, categoryName string, includeAdminFields bool) ProductDTO { dto := toProductDTO(row, includeAdminFields) dto.CategoryName = categoryName return dto } func toOrderDTO(row model.MohongOrder, snap productSnapshot, items []orderItemSnapshot, buyerNickname, buyerPhone string, includeAdmin bool) OrderDTO { if len(items) == 0 { items = decodeOrderItems(row) } title := snap.Title cover := snap.CoverURL unit := snap.Unit if title == "" && len(items) > 0 { title = items[0].Title } if cover == "" && len(items) > 0 { cover = items[0].CoverURL } if unit == "" && len(items) > 0 { unit = items[0].Unit } if len(items) > 1 && title != "" { title = fmt.Sprintf("%s 等%d种", title, len(items)) } itemDTOs := make([]OrderItemDTO, 0, len(items)) for _, item := range items { lineAmount := item.PriceCent * int64(item.Quantity) itemDTOs = append(itemDTOs, OrderItemDTO{ ProductID: item.ID, Title: item.Title, CoverURL: item.CoverURL, Unit: item.Unit, Quantity: item.Quantity, UnitPriceCent: item.PriceCent, UnitPrice: money.Format(item.PriceCent), AmountCent: lineAmount, Amount: money.Format(lineAmount), }) } dto := OrderDTO{ ID: row.ID, OrderNo: row.OrderNo, UserID: row.UserID, ProductID: row.ProductID, Quantity: row.Quantity, UnitPriceCent: row.UnitPriceCent, UnitPrice: money.Format(row.UnitPriceCent), AmountCent: row.AmountCent, Amount: money.Format(row.AmountCent), Status: row.Status, ProductTitle: title, ProductCoverURL: cover, ProductUnit: unit, Items: itemDTOs, QrcodeURLSnapshot: row.QrcodeURLSnapshot, CopyText: row.CopyText, CancelReason: row.CancelReason, PaidAt: row.PaidAt, CompletedAt: row.CompletedAt, CancelledAt: row.CancelledAt, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt, } if includeAdmin { // 后台展示真实手机号,便于履约联系买家 dto.BuyerNickname = buyerNickname dto.BuyerPhone = strings.TrimSpace(buyerPhone) dto.AdminRemark = row.AdminRemark } else { dto.BuyerNickname = buyerNickname dto.BuyerPhone = maskPhone(buyerPhone) } return dto } func decodeStringList(raw []byte) []string { if len(raw) == 0 { return []string{} } var list []string if err := json.Unmarshal(raw, &list); err != nil { return []string{} } out := make([]string, 0, len(list)) for _, item := range list { item = strings.TrimSpace(item) if item != "" { out = append(out, item) } } return out } func encodeStringList(list []string) []byte { clean := make([]string, 0, len(list)) for _, item := range list { item = strings.TrimSpace(item) if item != "" { clean = append(clean, item) } } if len(clean) == 0 { return []byte("[]") } raw, err := json.Marshal(clean) if err != nil { return []byte("[]") } return raw } func decodeProductSnapshot(raw []byte) productSnapshot { var snap productSnapshot if len(raw) == 0 { return snap } _ = json.Unmarshal(raw, &snap) return snap } func maskPhone(phone string) string { phone = strings.TrimSpace(phone) if len(phone) < 7 { return phone } return phone[:3] + "****" + phone[len(phone)-4:] }