bindbox-game/internal/service/user/shipping_groups.go
邹方成 45815bfb7d chore: 清理无用文件与优化代码结构
refactor(utils): 修复密码哈希比较逻辑错误
feat(user): 新增按状态筛选优惠券接口
docs: 添加虚拟发货与任务中心相关文档
fix(wechat): 修正Code2Session上下文传递问题
test: 补充订单折扣与积分转换测试用例
build: 更新配置文件与构建脚本
style: 清理多余的空行与注释
2025-12-18 17:35:55 +08:00

133 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package user
import (
"context"
"strconv"
"time"
)
// ProductInfo 商品简要信息
type ProductInfo struct {
ID int64 `json:"id"`
Name string `json:"name"`
Image string `json:"image"`
Price int64 `json:"price"`
}
type ShipmentGroup struct {
ExpressCode string `json:"express_code"`
ExpressNo string `json:"express_no"`
BatchNo string `json:"batch_no"`
Status int32 `json:"status"`
Count int64 `json:"count"`
ShippedAt *time.Time `json:"shipped_at,omitempty"`
ReceivedAt *time.Time `json:"received_at,omitempty"`
InventoryIDs []int64 `json:"inventory_ids"`
ProductIDs []int64 `json:"product_ids"`
Products []ProductInfo `json:"products"`
}
func (s *service) ListUserShipmentGroups(ctx context.Context, userID int64, page, pageSize int) (items []*ShipmentGroup, total int64, err error) {
q := s.readDB.ShippingRecords.WithContext(ctx).ReadDB().Where(s.readDB.ShippingRecords.UserID.Eq(userID))
total, err = q.Count()
if err != nil {
return nil, 0, err
}
if page <= 0 {
page = 1
}
if pageSize <= 0 {
pageSize = 20
}
if pageSize > 100 {
pageSize = 100
}
rows, err := q.Order(s.readDB.ShippingRecords.UpdatedAt.Desc(), s.readDB.ShippingRecords.ID.Desc()).Offset((page - 1) * pageSize).Limit(pageSize).Find()
if err != nil {
return nil, 0, err
}
type acc struct {
status int32
shippedAt *time.Time
receivedAt *time.Time
inv []int64
pid []int64
}
m := make(map[string]*acc)
meta := make(map[string]struct{ code, no, batch string })
order := make([]string, 0) // 保持顺序
for _, r := range rows {
// 分组优先级:运单号 > 批次号 > 记录ID
key := ""
if r.ExpressNo != "" {
// 有运单号,按运单号分组
key = "E|" + r.ExpressCode + "|" + r.ExpressNo
} else if r.BatchNo != "" {
// 无运单号但有批次号,按批次号分组
key = "B|" + r.BatchNo
} else {
// 无运单号也无批次号按记录ID独立
key = "_" + strconv.FormatInt(r.ID, 10)
}
if _, ok := m[key]; !ok {
m[key] = &acc{}
meta[key] = struct{ code, no, batch string }{r.ExpressCode, r.ExpressNo, r.BatchNo}
order = append(order, key)
}
a := m[key]
if a.status == 0 || r.Status >= a.status {
a.status = r.Status
}
if !r.ShippedAt.IsZero() {
t := r.ShippedAt
a.shippedAt = &t
}
if !r.ReceivedAt.IsZero() {
t := r.ReceivedAt
a.receivedAt = &t
}
a.inv = append(a.inv, r.InventoryID)
if r.ProductID > 0 {
a.pid = append(a.pid, r.ProductID)
}
}
items = make([]*ShipmentGroup, 0, len(m))
for _, k := range order {
a := m[k]
md := meta[k]
c := int64(len(a.inv))
// 获取商品详情(去重)
pidSet := make(map[int64]struct{})
for _, pid := range a.pid {
pidSet[pid] = struct{}{}
}
products := make([]ProductInfo, 0, len(pidSet))
for pid := range pidSet {
if prod, _ := s.readDB.Products.WithContext(ctx).ReadDB().Where(s.readDB.Products.ID.Eq(pid)).First(); prod != nil {
products = append(products, ProductInfo{
ID: prod.ID,
Name: prod.Name,
Image: prod.ImagesJSON,
Price: prod.Price,
})
}
}
items = append(items, &ShipmentGroup{
ExpressCode: md.code,
ExpressNo: md.no,
BatchNo: md.batch,
Status: a.status,
Count: c,
ShippedAt: a.shippedAt,
ReceivedAt: a.receivedAt,
InventoryIDs: a.inv,
ProductIDs: a.pid,
Products: products,
})
}
return items, int64(len(items)), nil
}