修复:平台后台显示用户地址和坐标
仅在已授权的用户地址列表与详情接口恢复真实地址、经度和纬度。前端增加六位小数、未填写提示及编辑回填,并同步安全规范、项目文档和操作日志。
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
// 功能描述:实现平台总后台的用户地址与服务关系管理。
|
||||
// 版本:v1.1
|
||||
package user
|
||||
|
||||
import (
|
||||
@@ -20,8 +22,69 @@ type addressRequest struct {
|
||||
IsDefault bool `json:"is_default"`
|
||||
}
|
||||
|
||||
func ListUserAddress(ctx *gin.Context) { common.ListPage[models.UserAddress](ctx) }
|
||||
func GetUserAddress(ctx *gin.Context) { common.GetByIdentity[models.UserAddress](ctx) }
|
||||
// ListUserAddress 查询用户地址分页列表,并为已授权的平台页面恢复地址与坐标。
|
||||
func ListUserAddress(ctx *gin.Context) {
|
||||
page, size := common.PageSize(ctx)
|
||||
var list []models.UserAddress
|
||||
var total int64
|
||||
query := common.ApplyKeywordFilter(ctx, common.ActiveRecords(impl.DBService.Model(&models.UserAddress{})), &models.UserAddress{})
|
||||
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(&list).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
response, err := common.PublicResourceResponse(list)
|
||||
if err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
protected := common.ProtectPreciseLocation(ctx, &models.UserAddress{}, response)
|
||||
infra.Response.Success(ctx, gin.H{"total": total, "list": restoreUserAddressLocations(protected, list)})
|
||||
}
|
||||
|
||||
// GetUserAddress 查询用户地址详情,并返回详情与编辑页需要的地址和坐标。
|
||||
func GetUserAddress(ctx *gin.Context) {
|
||||
var address models.UserAddress
|
||||
if err := common.ActiveRecords(impl.DBService).Where("identity = ?", ctx.Param("identity")).First(&address).Error; err != nil {
|
||||
common.RespondRecordError(ctx, err)
|
||||
return
|
||||
}
|
||||
response, err := common.PublicResourceResponse(address)
|
||||
if err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
protected := common.ProtectPreciseLocation(ctx, &models.UserAddress{}, response)
|
||||
infra.Response.Success(ctx, restoreUserAddressLocations(protected, []models.UserAddress{address}))
|
||||
}
|
||||
|
||||
// restoreUserAddressLocations 仅在用户地址受控接口中恢复完整地址和精确坐标。
|
||||
func restoreUserAddressLocations(response any, addresses []models.UserAddress) any {
|
||||
restore := func(record map[string]any, address models.UserAddress) {
|
||||
record["address"] = address.Address
|
||||
record["longitude"] = address.Longitude
|
||||
record["latitude"] = address.Latitude
|
||||
}
|
||||
switch data := response.(type) {
|
||||
case []any:
|
||||
for index, item := range data {
|
||||
if index >= len(addresses) {
|
||||
break
|
||||
}
|
||||
if record, ok := item.(map[string]any); ok {
|
||||
restore(record, addresses[index])
|
||||
}
|
||||
}
|
||||
case map[string]any:
|
||||
if len(addresses) > 0 {
|
||||
restore(data, addresses[0])
|
||||
}
|
||||
}
|
||||
return response
|
||||
}
|
||||
func CreateUserAddress(ctx *gin.Context) {
|
||||
var request addressRequest
|
||||
if err := ctx.ShouldBindJSON(&request); err != nil {
|
||||
|
||||
@@ -1,8 +1,45 @@
|
||||
// 功能描述:验证平台用户地址写入参数与 GORM 的兼容性。
|
||||
// 版本:v1.0
|
||||
// 版本:v1.1
|
||||
package user
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
|
||||
)
|
||||
|
||||
// TestRestoreUserAddressLocations 验证用户地址列表按原顺序恢复地址与坐标。
|
||||
func TestRestoreUserAddressLocations(t *testing.T) {
|
||||
response := []any{
|
||||
map[string]any{"identity": "address-1"},
|
||||
map[string]any{"identity": "address-2"},
|
||||
}
|
||||
addresses := []models.UserAddress{
|
||||
{Address: "广州市越秀区测试路 1 号", Longitude: "113.264385", Latitude: "23.129112"},
|
||||
{Address: "", Longitude: "", Latitude: ""},
|
||||
}
|
||||
|
||||
restored := restoreUserAddressLocations(response, addresses).([]any)
|
||||
first := restored[0].(map[string]any)
|
||||
if first["address"] != addresses[0].Address || first["longitude"] != addresses[0].Longitude || first["latitude"] != addresses[0].Latitude {
|
||||
t.Fatalf("第一条用户地址位置未正确恢复:%#v", first)
|
||||
}
|
||||
second := restored[1].(map[string]any)
|
||||
if second["address"] != "" || second["longitude"] != "" || second["latitude"] != "" {
|
||||
t.Fatalf("空位置字段应保持为空:%#v", second)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRestoreUserAddressLocation 验证用户地址详情恢复编辑所需字段。
|
||||
func TestRestoreUserAddressLocation(t *testing.T) {
|
||||
response := map[string]any{"identity": "address-1"}
|
||||
address := models.UserAddress{Address: "深圳市南山区测试路 8 号", Longitude: "113.930478", Latitude: "22.533191"}
|
||||
|
||||
restored := restoreUserAddressLocations(response, []models.UserAddress{address}).(map[string]any)
|
||||
if restored["address"] != address.Address || restored["longitude"] != address.Longitude || restored["latitude"] != address.Latitude {
|
||||
t.Fatalf("用户地址详情位置未正确恢复:%#v", restored)
|
||||
}
|
||||
}
|
||||
|
||||
// TestUserAddressUpdateValuesUsesSupportedMap 验证更新参数使用标准映射并保留布尔零值。
|
||||
func TestUserAddressUpdateValuesUsesSupportedMap(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user