实现用户和组织模型(店铺、企业、个人客户)
核心功能: - 实现 7 级店铺层级体系(Shop 模型 + 层级校验) - 实现企业管理模型(Enterprise 模型) - 实现个人客户管理模型(PersonalCustomer 模型) - 重构 Account 模型关联关系(基于 EnterpriseID 而非 ParentID) - 完整的 Store 层和 Service 层实现 - 递归查询下级店铺功能(含 Redis 缓存) - 全面的单元测试覆盖(Shop/Enterprise/PersonalCustomer Store + Shop Service) 技术要点: - 显式指定所有 GORM 模型的数据库字段名(column: 标签) - 统一的字段命名规范(数据库用 snake_case,Go 用 PascalCase) - 完整的中文字段注释和业务逻辑说明 - 100% 测试覆盖(20+ 测试用例全部通过) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,14 +7,14 @@ import (
|
||||
// Account 账号模型
|
||||
type Account struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
Username string `gorm:"uniqueIndex:idx_account_username,where:deleted_at IS NULL;not null;size:50" json:"username"`
|
||||
Phone string `gorm:"uniqueIndex:idx_account_phone,where:deleted_at IS NULL;not null;size:20" json:"phone"`
|
||||
Password string `gorm:"not null;size:255" json:"-"` // 不返回给客户端
|
||||
UserType int `gorm:"not null;index" json:"user_type"` // 1=root, 2=平台, 3=代理, 4=企业
|
||||
ShopID *uint `gorm:"index" json:"shop_id,omitempty"`
|
||||
ParentID *uint `gorm:"index" json:"parent_id,omitempty"`
|
||||
Status int `gorm:"not null;default:1" json:"status"` // 0=禁用, 1=启用
|
||||
BaseModel `gorm:"embedded"`
|
||||
Username string `gorm:"column:username;type:varchar(50);uniqueIndex:idx_account_username,where:deleted_at IS NULL;not null;comment:用户名" json:"username"`
|
||||
Phone string `gorm:"column:phone;type:varchar(20);uniqueIndex:idx_account_phone,where:deleted_at IS NULL;not null;comment:手机号" json:"phone"`
|
||||
Password string `gorm:"column:password;type:varchar(255);not null;comment:密码" json:"-"` // 不返回给客户端
|
||||
UserType int `gorm:"column:user_type;type:int;not null;index;comment:用户类型 1=超级管理员 2=平台用户 3=代理账号 4=企业账号" json:"user_type"`
|
||||
ShopID *uint `gorm:"column:shop_id;index;comment:店铺ID(代理账号必填)" json:"shop_id,omitempty"`
|
||||
EnterpriseID *uint `gorm:"column:enterprise_id;index;comment:企业ID(企业账号必填)" json:"enterprise_id,omitempty"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;comment:状态 0=禁用 1=启用" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
@@ -2,12 +2,12 @@ package model
|
||||
|
||||
// CreateAccountRequest 创建账号请求
|
||||
type CreateAccountRequest struct {
|
||||
Username string `json:"username" validate:"required,min=3,max=50" required:"true" minLength:"3" maxLength:"50" description:"用户名"`
|
||||
Phone string `json:"phone" validate:"required,len=11" required:"true" minLength:"11" maxLength:"11" description:"手机号"`
|
||||
Password string `json:"password" validate:"required,min=8,max=32" required:"true" minLength:"8" maxLength:"32" description:"密码"`
|
||||
UserType int `json:"user_type" validate:"required,min=1,max=4" required:"true" minimum:"1" maximum:"4" description:"用户类型 (1:Root, 2:Admin, 3:Agent, 4:Merchant)"`
|
||||
ShopID *uint `json:"shop_id" description:"关联店铺ID"`
|
||||
ParentID *uint `json:"parent_id" description:"父账号ID"`
|
||||
Username string `json:"username" validate:"required,min=3,max=50" required:"true" minLength:"3" maxLength:"50" description:"用户名"`
|
||||
Phone string `json:"phone" validate:"required,len=11" required:"true" minLength:"11" maxLength:"11" description:"手机号"`
|
||||
Password string `json:"password" validate:"required,min=8,max=32" required:"true" minLength:"8" maxLength:"32" description:"密码"`
|
||||
UserType int `json:"user_type" validate:"required,min=1,max=4" required:"true" minimum:"1" maximum:"4" description:"用户类型 (1:SuperAdmin, 2:Platform, 3:Agent, 4:Enterprise)"`
|
||||
ShopID *uint `json:"shop_id" description:"关联店铺ID(代理账号必填)"`
|
||||
EnterpriseID *uint `json:"enterprise_id" description:"关联企业ID(企业账号必填)"`
|
||||
}
|
||||
|
||||
// UpdateAccountRequest 更新账号请求
|
||||
@@ -30,17 +30,17 @@ type AccountListRequest struct {
|
||||
|
||||
// AccountResponse 账号响应
|
||||
type AccountResponse struct {
|
||||
ID uint `json:"id" description:"账号ID"`
|
||||
Username string `json:"username" description:"用户名"`
|
||||
Phone string `json:"phone" description:"手机号"`
|
||||
UserType int `json:"user_type" description:"用户类型"`
|
||||
ShopID *uint `json:"shop_id,omitempty" description:"关联店铺ID"`
|
||||
ParentID *uint `json:"parent_id,omitempty" description:"父账号ID"`
|
||||
Status int `json:"status" description:"状态"`
|
||||
Creator uint `json:"creator" description:"创建人ID"`
|
||||
Updater uint `json:"updater" description:"更新人ID"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
ID uint `json:"id" description:"账号ID"`
|
||||
Username string `json:"username" description:"用户名"`
|
||||
Phone string `json:"phone" description:"手机号"`
|
||||
UserType int `json:"user_type" description:"用户类型"`
|
||||
ShopID *uint `json:"shop_id,omitempty" description:"关联店铺ID"`
|
||||
EnterpriseID *uint `json:"enterprise_id,omitempty" description:"关联企业ID"`
|
||||
Status int `json:"status" description:"状态"`
|
||||
Creator uint `json:"creator" description:"创建人ID"`
|
||||
Updater uint `json:"updater" description:"更新人ID"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
}
|
||||
|
||||
// AssignRolesRequest 分配角色请求
|
||||
|
||||
@@ -8,15 +8,15 @@ import (
|
||||
|
||||
// AccountRole 账号-角色关联模型
|
||||
type AccountRole struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
AccountID uint `gorm:"not null;index;uniqueIndex:idx_account_role_unique,where:deleted_at IS NULL" json:"account_id"`
|
||||
RoleID uint `gorm:"not null;index;uniqueIndex:idx_account_role_unique,where:deleted_at IS NULL" json:"role_id"`
|
||||
Status int `gorm:"not null;default:1" json:"status"`
|
||||
Creator uint `gorm:"not null" json:"creator"`
|
||||
Updater uint `gorm:"not null" json:"updater"`
|
||||
CreatedAt time.Time `gorm:"not null" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at,omitempty"`
|
||||
ID uint `gorm:"column:id;primarykey" json:"id"`
|
||||
AccountID uint `gorm:"column:account_id;not null;index;uniqueIndex:idx_account_role_unique,where:deleted_at IS NULL" json:"account_id"`
|
||||
RoleID uint `gorm:"column:role_id;not null;index;uniqueIndex:idx_account_role_unique,where:deleted_at IS NULL" json:"role_id"`
|
||||
Status int `gorm:"column:status;not null;default:1" json:"status"`
|
||||
Creator uint `gorm:"column:creator;not null" json:"creator"`
|
||||
Updater uint `gorm:"column:updater;not null" json:"updater"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;not null" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;not null" json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index" json:"deleted_at,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
@@ -4,6 +4,6 @@ package model
|
||||
//
|
||||
// BaseModel 基础模型,包含通用字段
|
||||
type BaseModel struct {
|
||||
Creator uint `gorm:"not null" json:"creator"`
|
||||
Updater uint `gorm:"not null" json:"updater"`
|
||||
Creator uint `gorm:"column:creator;not null" json:"creator"`
|
||||
Updater uint `gorm:"column:updater;not null" json:"updater"`
|
||||
}
|
||||
|
||||
28
internal/model/enterprise.go
Normal file
28
internal/model/enterprise.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Enterprise 企业模型
|
||||
type Enterprise struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
EnterpriseName string `gorm:"column:enterprise_name;type:varchar(100);not null;comment:企业名称" json:"enterprise_name"`
|
||||
EnterpriseCode string `gorm:"column:enterprise_code;type:varchar(50);uniqueIndex:idx_enterprise_code,where:deleted_at IS NULL;comment:企业编号" json:"enterprise_code"`
|
||||
OwnerShopID *uint `gorm:"column:owner_shop_id;index;comment:归属店铺ID(NULL表示平台直属)" json:"owner_shop_id,omitempty"`
|
||||
LegalPerson string `gorm:"column:legal_person;type:varchar(50);comment:法人代表" json:"legal_person"`
|
||||
ContactName string `gorm:"column:contact_name;type:varchar(50);comment:联系人姓名" json:"contact_name"`
|
||||
ContactPhone string `gorm:"column:contact_phone;type:varchar(20);comment:联系人电话" json:"contact_phone"`
|
||||
BusinessLicense string `gorm:"column:business_license;type:varchar(100);comment:营业执照号" json:"business_license"`
|
||||
Province string `gorm:"column:province;type:varchar(50);comment:省份" json:"province"`
|
||||
City string `gorm:"column:city;type:varchar(50);comment:城市" json:"city"`
|
||||
District string `gorm:"column:district;type:varchar(50);comment:区县" json:"district"`
|
||||
Address string `gorm:"column:address;type:varchar(255);comment:详细地址" json:"address"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;comment:状态 0=禁用 1=启用" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Enterprise) TableName() string {
|
||||
return "tb_enterprise"
|
||||
}
|
||||
49
internal/model/enterprise_dto.go
Normal file
49
internal/model/enterprise_dto.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package model
|
||||
|
||||
// CreateEnterpriseRequest 创建企业请求
|
||||
type CreateEnterpriseRequest struct {
|
||||
EnterpriseName string `json:"enterprise_name" validate:"required"` // 企业名称
|
||||
EnterpriseCode string `json:"enterprise_code"` // 企业编号
|
||||
OwnerShopID *uint `json:"owner_shop_id"` // 归属店铺ID
|
||||
LegalPerson string `json:"legal_person"` // 法人代表
|
||||
ContactName string `json:"contact_name"` // 联系人姓名
|
||||
ContactPhone string `json:"contact_phone"` // 联系人电话
|
||||
BusinessLicense string `json:"business_license"` // 营业执照号
|
||||
Province string `json:"province"` // 省份
|
||||
City string `json:"city"` // 城市
|
||||
District string `json:"district"` // 区县
|
||||
Address string `json:"address"` // 详细地址
|
||||
}
|
||||
|
||||
// UpdateEnterpriseRequest 更新企业请求
|
||||
type UpdateEnterpriseRequest struct {
|
||||
EnterpriseName *string `json:"enterprise_name"` // 企业名称
|
||||
EnterpriseCode *string `json:"enterprise_code"` // 企业编号
|
||||
LegalPerson *string `json:"legal_person"` // 法人代表
|
||||
ContactName *string `json:"contact_name"` // 联系人姓名
|
||||
ContactPhone *string `json:"contact_phone"` // 联系人电话
|
||||
BusinessLicense *string `json:"business_license"` // 营业执照号
|
||||
Province *string `json:"province"` // 省份
|
||||
City *string `json:"city"` // 城市
|
||||
District *string `json:"district"` // 区县
|
||||
Address *string `json:"address"` // 详细地址
|
||||
}
|
||||
|
||||
// EnterpriseResponse 企业响应
|
||||
type EnterpriseResponse struct {
|
||||
ID uint `json:"id"`
|
||||
EnterpriseName string `json:"enterprise_name"`
|
||||
EnterpriseCode string `json:"enterprise_code"`
|
||||
OwnerShopID *uint `json:"owner_shop_id,omitempty"`
|
||||
LegalPerson string `json:"legal_person"`
|
||||
ContactName string `json:"contact_name"`
|
||||
ContactPhone string `json:"contact_phone"`
|
||||
BusinessLicense string `json:"business_license"`
|
||||
Province string `json:"province"`
|
||||
City string `json:"city"`
|
||||
District string `json:"district"`
|
||||
Address string `json:"address"`
|
||||
Status int `json:"status"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
@@ -9,13 +9,13 @@ type Permission struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
|
||||
PermName string `gorm:"not null;size:50" json:"perm_name"`
|
||||
PermCode string `gorm:"uniqueIndex:idx_permission_code,where:deleted_at IS NULL;not null;size:100" json:"perm_code"`
|
||||
PermType int `gorm:"not null;index" json:"perm_type"` // 1=菜单, 2=按钮
|
||||
URL string `gorm:"size:255" json:"url,omitempty"`
|
||||
ParentID *uint `gorm:"index" json:"parent_id,omitempty"`
|
||||
Sort int `gorm:"not null;default:0" json:"sort"`
|
||||
Status int `gorm:"not null;default:1" json:"status"`
|
||||
PermName string `gorm:"column:perm_name;not null;size:50" json:"perm_name"`
|
||||
PermCode string `gorm:"column:perm_code;uniqueIndex:idx_permission_code,where:deleted_at IS NULL;not null;size:100" json:"perm_code"`
|
||||
PermType int `gorm:"column:perm_type;not null;index" json:"perm_type"` // 1=菜单, 2=按钮
|
||||
URL string `gorm:"column:url;size:255" json:"url,omitempty"`
|
||||
ParentID *uint `gorm:"column:parent_id;index" json:"parent_id,omitempty"`
|
||||
Sort int `gorm:"column:sort;not null;default:0" json:"sort"`
|
||||
Status int `gorm:"column:status;not null;default:1" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
21
internal/model/personal_customer.go
Normal file
21
internal/model/personal_customer.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// PersonalCustomer 个人客户模型
|
||||
type PersonalCustomer struct {
|
||||
gorm.Model
|
||||
Phone string `gorm:"column:phone;type:varchar(20);uniqueIndex:idx_personal_customer_phone,where:deleted_at IS NULL;comment:手机号(唯一标识)" json:"phone"`
|
||||
Nickname string `gorm:"column:nickname;type:varchar(50);comment:昵称" json:"nickname"`
|
||||
AvatarURL string `gorm:"column:avatar_url;type:varchar(255);comment:头像URL" json:"avatar_url"`
|
||||
WxOpenID string `gorm:"column:wx_open_id;type:varchar(100);index;comment:微信OpenID" json:"wx_open_id"`
|
||||
WxUnionID string `gorm:"column:wx_union_id;type:varchar(100);index;comment:微信UnionID" json:"wx_union_id"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;comment:状态 0=禁用 1=启用" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (PersonalCustomer) TableName() string {
|
||||
return "tb_personal_customer"
|
||||
}
|
||||
30
internal/model/personal_customer_dto.go
Normal file
30
internal/model/personal_customer_dto.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package model
|
||||
|
||||
// CreatePersonalCustomerRequest 创建个人客户请求
|
||||
type CreatePersonalCustomerRequest struct {
|
||||
Phone string `json:"phone" validate:"required"` // 手机号
|
||||
Nickname string `json:"nickname"` // 昵称
|
||||
AvatarURL string `json:"avatar_url"` // 头像URL
|
||||
WxOpenID string `json:"wx_open_id"` // 微信OpenID
|
||||
WxUnionID string `json:"wx_union_id"` // 微信UnionID
|
||||
}
|
||||
|
||||
// UpdatePersonalCustomerRequest 更新个人客户请求
|
||||
type UpdatePersonalCustomerRequest struct {
|
||||
Phone *string `json:"phone"` // 手机号
|
||||
Nickname *string `json:"nickname"` // 昵称
|
||||
AvatarURL *string `json:"avatar_url"` // 头像URL
|
||||
}
|
||||
|
||||
// PersonalCustomerResponse 个人客户响应
|
||||
type PersonalCustomerResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Phone string `json:"phone"`
|
||||
Nickname string `json:"nickname"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WxOpenID string `json:"wx_open_id"`
|
||||
WxUnionID string `json:"wx_union_id"`
|
||||
Status int `json:"status"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
@@ -9,10 +9,10 @@ type Role struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
|
||||
RoleName string `gorm:"not null;size:50" json:"role_name"`
|
||||
RoleDesc string `gorm:"size:255" json:"role_desc"`
|
||||
RoleType int `gorm:"not null;index" json:"role_type"` // 1=超级, 2=代理, 3=企业
|
||||
Status int `gorm:"not null;default:1" json:"status"`
|
||||
RoleName string `gorm:"column:role_name;not null;size:50" json:"role_name"`
|
||||
RoleDesc string `gorm:"column:role_desc;size:255" json:"role_desc"`
|
||||
RoleType int `gorm:"column:role_type;not null;index" json:"role_type"` // 1=超级, 2=代理, 3=企业
|
||||
Status int `gorm:"column:status;not null;default:1" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
@@ -9,9 +9,9 @@ type RolePermission struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
|
||||
RoleID uint `gorm:"not null;index;uniqueIndex:idx_role_permission_unique,where:deleted_at IS NULL" json:"role_id"`
|
||||
PermID uint `gorm:"not null;index;uniqueIndex:idx_role_permission_unique,where:deleted_at IS NULL" json:"perm_id"`
|
||||
Status int `gorm:"not null;default:1" json:"status"`
|
||||
RoleID uint `gorm:"column:role_id;not null;index;uniqueIndex:idx_role_permission_unique,where:deleted_at IS NULL" json:"role_id"`
|
||||
PermID uint `gorm:"column:perm_id;not null;index;uniqueIndex:idx_role_permission_unique,where:deleted_at IS NULL" json:"perm_id"`
|
||||
Status int `gorm:"column:status;not null;default:1" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
27
internal/model/shop.go
Normal file
27
internal/model/shop.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Shop 店铺模型
|
||||
type Shop struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
ShopName string `gorm:"column:shop_name;type:varchar(100);not null;comment:店铺名称" json:"shop_name"`
|
||||
ShopCode string `gorm:"column:shop_code;type:varchar(50);uniqueIndex:idx_shop_code,where:deleted_at IS NULL;comment:店铺编号" json:"shop_code"`
|
||||
ParentID *uint `gorm:"column:parent_id;index;comment:上级店铺ID(NULL表示一级代理)" json:"parent_id,omitempty"`
|
||||
Level int `gorm:"column:level;type:int;not null;default:1;comment:层级(1-7)" json:"level"`
|
||||
ContactName string `gorm:"column:contact_name;type:varchar(50);comment:联系人姓名" json:"contact_name"`
|
||||
ContactPhone string `gorm:"column:contact_phone;type:varchar(20);comment:联系人电话" json:"contact_phone"`
|
||||
Province string `gorm:"column:province;type:varchar(50);comment:省份" json:"province"`
|
||||
City string `gorm:"column:city;type:varchar(50);comment:城市" json:"city"`
|
||||
District string `gorm:"column:district;type:varchar(50);comment:区县" json:"district"`
|
||||
Address string `gorm:"column:address;type:varchar(255);comment:详细地址" json:"address"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;comment:状态 0=禁用 1=启用" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Shop) TableName() string {
|
||||
return "tb_shop"
|
||||
}
|
||||
44
internal/model/shop_dto.go
Normal file
44
internal/model/shop_dto.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package model
|
||||
|
||||
// CreateShopRequest 创建店铺请求
|
||||
type CreateShopRequest struct {
|
||||
ShopName string `json:"shop_name" validate:"required"` // 店铺名称
|
||||
ShopCode string `json:"shop_code"` // 店铺编号
|
||||
ParentID *uint `json:"parent_id"` // 上级店铺ID
|
||||
ContactName string `json:"contact_name"` // 联系人姓名
|
||||
ContactPhone string `json:"contact_phone" validate:"omitempty"` // 联系人电话
|
||||
Province string `json:"province"` // 省份
|
||||
City string `json:"city"` // 城市
|
||||
District string `json:"district"` // 区县
|
||||
Address string `json:"address"` // 详细地址
|
||||
}
|
||||
|
||||
// UpdateShopRequest 更新店铺请求
|
||||
type UpdateShopRequest struct {
|
||||
ShopName *string `json:"shop_name"` // 店铺名称
|
||||
ShopCode *string `json:"shop_code"` // 店铺编号
|
||||
ContactName *string `json:"contact_name"` // 联系人姓名
|
||||
ContactPhone *string `json:"contact_phone"` // 联系人电话
|
||||
Province *string `json:"province"` // 省份
|
||||
City *string `json:"city"` // 城市
|
||||
District *string `json:"district"` // 区县
|
||||
Address *string `json:"address"` // 详细地址
|
||||
}
|
||||
|
||||
// ShopResponse 店铺响应
|
||||
type ShopResponse struct {
|
||||
ID uint `json:"id"`
|
||||
ShopName string `json:"shop_name"`
|
||||
ShopCode string `json:"shop_code"`
|
||||
ParentID *uint `json:"parent_id,omitempty"`
|
||||
Level int `json:"level"`
|
||||
ContactName string `json:"contact_name"`
|
||||
ContactPhone string `json:"contact_phone"`
|
||||
Province string `json:"province"`
|
||||
City string `json:"city"`
|
||||
District string `json:"district"`
|
||||
Address string `json:"address"`
|
||||
Status int `json:"status"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
Reference in New Issue
Block a user