优化配送订单列表可读信息显示

This commit is contained in:
czl231
2026-08-14 21:02:02 +08:00
parent 2cff8fb942
commit 3ba05dc147
6 changed files with 286 additions and 4 deletions

View File

@@ -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{}) }

View File

@@ -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
}

View File

@@ -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)
}
}