2026-05-05 03:05:06 +08:00

237 lines
8.1 KiB
Go
Raw Permalink 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 userclient
import (
"context"
userv1 "hyapp.local/api/proto/user/v1"
)
// Country 是 admin-server 暴露给后台前端的国家主数据 DTO。
// 这里不引用 user-service 的 domain/storage 包,避免后台服务和用户服务代码结构耦合。
type Country struct {
// CountryID 是 user-service 生成的国家主键,后台增删改查都以它定位记录。
CountryID int64 `json:"countryId"`
// CountryName 是稳定英文或拼音名称,例如 China、United States。
CountryName string `json:"countryName"`
// CountryCode 是 App 和用户链路使用的 canonical 国家码,创建后不可变。
CountryCode string `json:"countryCode"`
// CountryDisplayName 是后台和 App 注册页展示用中文名。
CountryDisplayName string `json:"countryDisplayName"`
// SortOrder 控制 App 注册页和后台列表的默认排序。
SortOrder int32 `json:"sortOrder"`
// CreatedAtMs 直接透传 user-service 的毫秒时间戳,避免跨服务时区转换。
CreatedAtMs int64 `json:"createdAtMs"`
// UpdatedAtMs 直接透传 user-service 的毫秒时间戳,便于后台做新旧数据判断。
UpdatedAtMs int64 `json:"updatedAtMs"`
// ISOAlpha3 是 ISO 3166-1 alpha-3 或明确的 user-assigned code。
ISOAlpha3 string `json:"isoAlpha3"`
// ISONumeric 必须保持字符串,避免 020 这类前导零被破坏。
ISONumeric string `json:"isoNumeric"`
// PhoneCountryCode 是 E.164 国家呼叫码,例如 +86。
PhoneCountryCode string `json:"phoneCountryCode"`
// Enabled 表示该国家是否允许 App 注册和用户改国家选择。
Enabled bool `json:"enabled"`
// Flag 是展示字段,不参与国家唯一性、区域归属或权限判断。
Flag string `json:"flag"`
}
// Region 是 user-service 区域主数据投影countries 只包含当前 active 国家码。
type Region struct {
// RegionID 是区域主键BD Leader/BD/Agency 后续都围绕它建立组织关系。
RegionID int64 `json:"regionId"`
// RegionCode 是稳定业务编码;后台修改时仍由 user-service 做唯一性校验。
RegionCode string `json:"regionCode"`
// Name 是后台展示名。
Name string `json:"name"`
// Status 当前只由 user-service 约束为 active 或 disabled。
Status string `json:"status"`
// Countries 是 active 映射国家码列表;一个国家不能同时属于多个 active 区域。
Countries []string `json:"countries"`
// SortOrder 控制后台和业务选择器排序。
SortOrder int32 `json:"sortOrder"`
// CreatedAtMs 直接透传 user-service 的毫秒时间戳。
CreatedAtMs int64 `json:"createdAtMs"`
// UpdatedAtMs 直接透传 user-service 的毫秒时间戳。
UpdatedAtMs int64 `json:"updatedAtMs"`
}
// ListCountriesRequest 支持 enabled 三态过滤nil 表示全部true/false 表示显式筛选。
type ListCountriesRequest struct {
RequestID string
Caller string
Enabled *bool
}
// UpdateCountryRequest 只允许修改展示和辅助字段,不允许修改 country_code。
type UpdateCountryRequest struct {
RequestID string
Caller string
CountryID int64
CountryName string
CountryDisplayName string
SortOrder int32
OperatorUserID int64
ISOAlpha3 string
ISONumeric string
PhoneCountryCode string
Flag string
}
// ListRegionsRequest 支持 status 过滤;空字符串表示全部。
type ListRegionsRequest struct {
RequestID string
Caller string
Status string
}
// GetRegionRequest 按区域主键查询单个区域及 active 国家码。
type GetRegionRequest struct {
RequestID string
Caller string
RegionID int64
}
// UpdateRegionRequest 只修改区域展示字段,不替换国家归属。
type UpdateRegionRequest struct {
RequestID string
Caller string
RegionID int64
RegionCode string
Name string
SortOrder int32
OperatorUserID int64
}
// ReplaceRegionCountriesRequest 原子替换区域国家归属,并由 user-service 创建用户区域重算任务。
type ReplaceRegionCountriesRequest struct {
RequestID string
Caller string
RegionID int64
Countries []string
OperatorUserID int64
}
func (c *GRPCClient) ListCountries(ctx context.Context, req ListCountriesRequest) ([]*Country, error) {
resp, err := c.countryClient.ListCountries(ctx, &userv1.ListCountriesRequest{
Meta: requestMeta(ctx, req.RequestID, req.Caller),
Enabled: req.Enabled,
})
if err != nil {
return nil, err
}
items := make([]*Country, 0, len(resp.GetCountries()))
for _, country := range resp.GetCountries() {
items = append(items, fromProtoCountry(country))
}
return items, nil
}
func (c *GRPCClient) UpdateCountry(ctx context.Context, req UpdateCountryRequest) (*Country, error) {
resp, err := c.countryClient.UpdateCountry(ctx, &userv1.UpdateCountryRequest{
Meta: requestMeta(ctx, req.RequestID, req.Caller),
CountryId: req.CountryID,
CountryName: req.CountryName,
CountryDisplayName: req.CountryDisplayName,
SortOrder: req.SortOrder,
OperatorUserId: req.OperatorUserID,
IsoAlpha3: req.ISOAlpha3,
IsoNumeric: req.ISONumeric,
PhoneCountryCode: req.PhoneCountryCode,
Flag: req.Flag,
})
if err != nil {
return nil, err
}
return fromProtoCountry(resp.GetCountry()), nil
}
func (c *GRPCClient) ListRegions(ctx context.Context, req ListRegionsRequest) ([]*Region, error) {
resp, err := c.regionClient.ListRegions(ctx, &userv1.ListRegionsRequest{
Meta: requestMeta(ctx, req.RequestID, req.Caller),
Status: req.Status,
})
if err != nil {
return nil, err
}
items := make([]*Region, 0, len(resp.GetRegions()))
for _, region := range resp.GetRegions() {
items = append(items, fromProtoRegion(region))
}
return items, nil
}
func (c *GRPCClient) GetRegion(ctx context.Context, req GetRegionRequest) (*Region, error) {
resp, err := c.regionClient.GetRegion(ctx, &userv1.GetRegionRequest{
Meta: requestMeta(ctx, req.RequestID, req.Caller),
RegionId: req.RegionID,
})
if err != nil {
return nil, err
}
return fromProtoRegion(resp.GetRegion()), nil
}
func (c *GRPCClient) UpdateRegion(ctx context.Context, req UpdateRegionRequest) (*Region, error) {
resp, err := c.regionClient.UpdateRegion(ctx, &userv1.UpdateRegionRequest{
Meta: requestMeta(ctx, req.RequestID, req.Caller),
RegionId: req.RegionID,
RegionCode: req.RegionCode,
Name: req.Name,
SortOrder: req.SortOrder,
OperatorUserId: req.OperatorUserID,
})
if err != nil {
return nil, err
}
return fromProtoRegion(resp.GetRegion()), nil
}
func (c *GRPCClient) ReplaceRegionCountries(ctx context.Context, req ReplaceRegionCountriesRequest) (*Region, error) {
resp, err := c.regionClient.ReplaceRegionCountries(ctx, &userv1.ReplaceRegionCountriesRequest{
Meta: requestMeta(ctx, req.RequestID, req.Caller),
RegionId: req.RegionID,
Countries: append([]string(nil), req.Countries...),
OperatorUserId: req.OperatorUserID,
})
if err != nil {
return nil, err
}
return fromProtoRegion(resp.GetRegion()), nil
}
func fromProtoCountry(country *userv1.Country) *Country {
if country == nil {
return nil
}
return &Country{
CountryID: country.GetCountryId(),
CountryName: country.GetCountryName(),
CountryCode: country.GetCountryCode(),
CountryDisplayName: country.GetCountryDisplayName(),
SortOrder: country.GetSortOrder(),
CreatedAtMs: country.GetCreatedAtMs(),
UpdatedAtMs: country.GetUpdatedAtMs(),
ISOAlpha3: country.GetIsoAlpha3(),
ISONumeric: country.GetIsoNumeric(),
PhoneCountryCode: country.GetPhoneCountryCode(),
Enabled: country.GetEnabled(),
Flag: country.GetFlag(),
}
}
func fromProtoRegion(region *userv1.Region) *Region {
if region == nil {
return nil
}
return &Region{
RegionID: region.GetRegionId(),
RegionCode: region.GetRegionCode(),
Name: region.GetName(),
Status: region.GetStatus(),
Countries: append([]string{}, region.GetCountries()...),
SortOrder: region.GetSortOrder(),
CreatedAtMs: region.GetCreatedAtMs(),
UpdatedAtMs: region.GetUpdatedAtMs(),
}
}