优化配送订单列表可读信息显示
This commit is contained in:
@@ -82,7 +82,6 @@ func ListGasorderContractRevision(ctx *gin.Context) {
|
||||
func GetGasorderContractRevision(ctx *gin.Context) {
|
||||
common.GetResource(ctx, &models.GasorderContractRevision{})
|
||||
}
|
||||
func ListGasorderBasic(ctx *gin.Context) { common.ListResource(ctx, &models.GasorderBasic{}) }
|
||||
func GetGasorderBasic(ctx *gin.Context) { getGasorderBasic(ctx) }
|
||||
func ListGasorderAssign(ctx *gin.Context) { common.ListResource(ctx, &models.GasorderAssign{}) }
|
||||
func GetGasorderAssign(ctx *gin.Context) { common.GetResource(ctx, &models.GasorderAssign{}) }
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
// 功能描述:为平台配送订单列表补充创建方名称、收货地址和合同气瓶摘要。
|
||||
// 版本:v1.0.0
|
||||
package gasorder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/heqiapp/platforms/backend/api/internal/impl"
|
||||
"git.apinb.com/heqiapp/platforms/backend/api/internal/logic/common"
|
||||
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// gasorderListDisplay 是订单持久化快照与列表专用可读字段组成的响应模型。
|
||||
type gasorderListDisplay struct {
|
||||
models.GasorderBasic
|
||||
CreatorDisplayName string `json:"creator_display_name"`
|
||||
ContractProductsSummary string `json:"contract_products_summary"`
|
||||
}
|
||||
|
||||
// ListGasorderBasic 返回平台订单分页列表,并补充只用于管理端展示的可读摘要。
|
||||
func ListGasorderBasic(ctx *gin.Context) {
|
||||
page, size := common.PageSize(ctx)
|
||||
var orders []models.GasorderBasic
|
||||
var total int64
|
||||
query := common.ApplyKeywordFilter(ctx, common.ActiveRecords(impl.DBService.Model(&models.GasorderBasic{})), &models.GasorderBasic{})
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
if err := query.Order("created_at desc").Offset((page - 1) * size).Limit(size).Find(&orders).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
displays, err := buildGasorderListDisplays(orders)
|
||||
if err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
response, err := common.PublicResourceResponse(displays)
|
||||
if err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
protected := common.ProtectPreciseLocation(ctx, &models.GasorderBasic{}, response)
|
||||
infra.Response.Success(ctx, gin.H{"total": total, "list": restoreGasorderListAddresses(protected, orders)})
|
||||
}
|
||||
|
||||
// buildGasorderListDisplays 批量读取创建方与有效订单气瓶,避免列表逐行查询。
|
||||
func buildGasorderListDisplays(orders []models.GasorderBasic) ([]gasorderListDisplay, error) {
|
||||
creatorNames, err := loadGasorderCreatorNames(orders)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
productSummaries, err := loadGasorderProductSummaries(orders)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
displays := make([]gasorderListDisplay, 0, len(orders))
|
||||
for _, order := range orders {
|
||||
creatorName := strings.TrimSpace(creatorNames[creatorLookupKey(order.CreatorType, order.CreatorID)])
|
||||
if creatorName == "" {
|
||||
creatorName = fmt.Sprintf("记录已失效(%s)", order.CreatorIdentity)
|
||||
}
|
||||
displays = append(displays, gasorderListDisplay{
|
||||
GasorderBasic: order,
|
||||
CreatorDisplayName: creatorName,
|
||||
ContractProductsSummary: productSummaries[order.ID],
|
||||
})
|
||||
}
|
||||
return displays, nil
|
||||
}
|
||||
|
||||
func creatorLookupKey(creatorType string, creatorID uint64) string {
|
||||
return fmt.Sprintf("%s:%d", creatorType, creatorID)
|
||||
}
|
||||
|
||||
// loadGasorderCreatorNames 按四类创建方批量加载当前可读名称,归档或已删除记录不参与展示。
|
||||
func loadGasorderCreatorNames(orders []models.GasorderBasic) (map[string]string, error) {
|
||||
ids := map[string][]uint64{}
|
||||
for _, order := range orders {
|
||||
ids[order.CreatorType] = append(ids[order.CreatorType], order.CreatorID)
|
||||
}
|
||||
names := map[string]string{}
|
||||
load := func(creatorType string, records any) error {
|
||||
if len(ids[creatorType]) == 0 {
|
||||
return nil
|
||||
}
|
||||
return common.ActiveRecords(impl.DBService).Where("id IN ? AND status <> ?", ids[creatorType], common.StatusArchived).Find(records).Error
|
||||
}
|
||||
var users []models.UserAccount
|
||||
if err := load("user", &users); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range users {
|
||||
names[creatorLookupKey("user", item.ID)] = firstReadableName(item.Name, item.RealName, item.Username)
|
||||
}
|
||||
var staff []models.StaffAccount
|
||||
if err := load("staff", &staff); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range staff {
|
||||
names[creatorLookupKey("staff", item.ID)] = firstReadableName(item.Name, item.Username)
|
||||
}
|
||||
var deliveries []models.DeliveryBasic
|
||||
if err := load("delivery", &deliveries); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range deliveries {
|
||||
names[creatorLookupKey("delivery", item.ID)] = item.Name
|
||||
}
|
||||
var stations []models.GasBasic
|
||||
if err := load("gas", &stations); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range stations {
|
||||
names[creatorLookupKey("gas", item.ID)] = item.Name
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
|
||||
func firstReadableName(values ...string) string {
|
||||
for _, value := range values {
|
||||
if value = strings.TrimSpace(value); value != "" {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// loadGasorderProductSummaries 生成“名称(类型)”或“名称(类型)等 N 个”的订单气瓶摘要。
|
||||
func loadGasorderProductSummaries(orders []models.GasorderBasic) (map[uint64]string, error) {
|
||||
orderIDs := make([]uint64, 0, len(orders))
|
||||
for _, order := range orders {
|
||||
orderIDs = append(orderIDs, order.ID)
|
||||
}
|
||||
if len(orderIDs) == 0 {
|
||||
return map[uint64]string{}, nil
|
||||
}
|
||||
var items []gasorderItemDisplay
|
||||
if err := gasorderItemDisplayQuery(impl.DBService, "").
|
||||
Where("gasorder_item.gasorder_basic_id IN ? AND gasorder_item.active = ?", orderIDs, true).
|
||||
Order("gasorder_item.gasorder_basic_id asc, gasorder_item.id asc").Scan(&items).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
type summary struct {
|
||||
first string
|
||||
count int
|
||||
}
|
||||
grouped := map[uint64]summary{}
|
||||
for _, item := range items {
|
||||
current := grouped[item.GasorderBasicID]
|
||||
if current.count == 0 {
|
||||
name := firstReadableName(item.ProductName, item.ProductCode, item.Identity)
|
||||
if productType := strings.TrimSpace(item.ProductTypeName); productType != "" {
|
||||
name += "(" + productType + ")"
|
||||
}
|
||||
current.first = name
|
||||
}
|
||||
current.count++
|
||||
grouped[item.GasorderBasicID] = current
|
||||
}
|
||||
result := map[uint64]string{}
|
||||
for orderID, item := range grouped {
|
||||
result[orderID] = item.first
|
||||
if item.count > 1 {
|
||||
result[orderID] = fmt.Sprintf("%s等 %d 个", item.first, item.count)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// restoreGasorderListAddresses 仅在已鉴权的平台订单列表中恢复订单收货地址快照。
|
||||
func restoreGasorderListAddresses(response any, orders []models.GasorderBasic) any {
|
||||
list, ok := response.([]any)
|
||||
if !ok {
|
||||
return response
|
||||
}
|
||||
for index, item := range list {
|
||||
if index >= len(orders) {
|
||||
break
|
||||
}
|
||||
if record, ok := item.(map[string]any); ok {
|
||||
record["address"] = orders[index].Address
|
||||
}
|
||||
}
|
||||
return response
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// 功能描述:验证平台配送订单列表的可读名称、地址恢复和空值兜底规则。
|
||||
// 版本:v1.0.0
|
||||
package gasorder
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
|
||||
)
|
||||
|
||||
// TestFirstReadableName 验证创建方名称按首个非空业务名称降级。
|
||||
func TestFirstReadableName(t *testing.T) {
|
||||
if got := firstReadableName("", " 张三 ", "staff-01"); got != "张三" {
|
||||
t.Fatalf("首个可读名称 = %q,期望 张三", got)
|
||||
}
|
||||
if got := firstReadableName("", " "); got != "" {
|
||||
t.Fatalf("全空名称应返回空字符串,实际为 %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRestoreGasorderListAddresses 验证仅按分页记录顺序恢复已鉴权订单的地址快照。
|
||||
func TestRestoreGasorderListAddresses(t *testing.T) {
|
||||
response := []any{
|
||||
map[string]any{"identity": "order-1"},
|
||||
map[string]any{"identity": "order-2"},
|
||||
}
|
||||
orders := []models.GasorderBasic{
|
||||
{Address: "上海市浦东新区客户路 88 号"},
|
||||
{Address: ""},
|
||||
}
|
||||
restored := restoreGasorderListAddresses(response, orders).([]any)
|
||||
if got := restored[0].(map[string]any)["address"]; got != orders[0].Address {
|
||||
t.Fatalf("订单地址 = %v,期望 %s", got, orders[0].Address)
|
||||
}
|
||||
if got := restored[1].(map[string]any)["address"]; got != "" {
|
||||
t.Fatalf("空地址应保持为空,实际为 %v", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user