init
This commit is contained in:
25
server/internal/model/banner.go
Normal file
25
server/internal/model/banner.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Banner 轮播图模型
|
||||
type Banner struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
Title string `json:"title" gorm:"type:varchar(255);not null;comment:轮播图标题"`
|
||||
Image string `json:"image" gorm:"type:varchar(500);not null;comment:轮播图图片URL"`
|
||||
LinkType int `json:"link_type" gorm:"type:tinyint;not null;default:1;comment:链接类型:1-无链接,2-商品详情,3-分类页面,4-外部链接"`
|
||||
LinkValue string `json:"link_value" gorm:"type:varchar(500);comment:链接值"`
|
||||
Sort int `json:"sort" gorm:"type:int;not null;default:0;comment:排序值,数值越大越靠前"`
|
||||
Status int `json:"status" gorm:"type:tinyint;not null;default:1;comment:状态:0-禁用,1-启用"`
|
||||
StartTime *time.Time `json:"start_time" gorm:"comment:开始时间"`
|
||||
EndTime *time.Time `json:"end_time" gorm:"comment:结束时间"`
|
||||
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
|
||||
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Banner) TableName() string {
|
||||
return "ai_banners"
|
||||
}
|
||||
112
server/internal/model/comment.go
Normal file
112
server/internal/model/comment.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Comment 商品评论
|
||||
type Comment struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
UserID uint `json:"user_id" gorm:"not null;index"`
|
||||
ProductID uint `json:"product_id" gorm:"not null;index"`
|
||||
OrderID uint `json:"order_id" gorm:"not null;index"`
|
||||
OrderItemID uint `json:"order_item_id" gorm:"not null;index"`
|
||||
Rating int `json:"rating" gorm:"not null;default:5"` // 评分 1-5星
|
||||
Content string `json:"content" gorm:"type:text"` // 评论内容
|
||||
Images string `json:"images" gorm:"type:text"` // 评论图片,JSON格式存储
|
||||
IsAnonymous bool `json:"is_anonymous" gorm:"default:false"` // 是否匿名评论
|
||||
Status int `json:"status" gorm:"default:1"` // 状态:1-正常,2-隐藏,3-删除
|
||||
ReplyCount int `json:"reply_count" gorm:"default:0"` // 回复数量
|
||||
LikeCount int `json:"like_count" gorm:"default:0"` // 点赞数量
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
Product Product `json:"product,omitempty" gorm:"foreignKey:ProductID"`
|
||||
Order Order `json:"order,omitempty" gorm:"foreignKey:OrderID"`
|
||||
OrderItem OrderItem `json:"order_item,omitempty" gorm:"foreignKey:OrderItemID"`
|
||||
Replies []CommentReply `json:"replies,omitempty" gorm:"foreignKey:CommentID"`
|
||||
}
|
||||
|
||||
// MarshalJSON 自定义JSON序列化,将Images字段从JSON字符串转换为数组
|
||||
func (c Comment) MarshalJSON() ([]byte, error) {
|
||||
type Alias Comment
|
||||
|
||||
// 解析Images字段
|
||||
var images []string
|
||||
if c.Images != "" {
|
||||
if err := json.Unmarshal([]byte(c.Images), &images); err != nil {
|
||||
// 如果解析失败,返回空数组
|
||||
images = []string{}
|
||||
}
|
||||
} else {
|
||||
images = []string{}
|
||||
}
|
||||
|
||||
// 创建临时结构体用于序列化
|
||||
return json.Marshal(&struct {
|
||||
*Alias
|
||||
Images []string `json:"images"`
|
||||
}{
|
||||
Alias: (*Alias)(&c),
|
||||
Images: images,
|
||||
})
|
||||
}
|
||||
|
||||
// CommentReply 评论回复
|
||||
type CommentReply struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
CommentID uint `json:"comment_id" gorm:"not null;index"`
|
||||
UserID uint `json:"user_id" gorm:"not null;index"`
|
||||
Content string `json:"content" gorm:"type:text;not null"`
|
||||
IsAdmin bool `json:"is_admin" gorm:"default:false"` // 是否管理员回复
|
||||
Status int `json:"status" gorm:"default:1"` // 状态:1-正常,2-隐藏,3-删除
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
Comment Comment `json:"comment,omitempty" gorm:"foreignKey:CommentID"`
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
}
|
||||
|
||||
// CommentLike 评论点赞
|
||||
type CommentLike struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
CommentID uint `json:"comment_id" gorm:"not null;index"`
|
||||
UserID uint `json:"user_id" gorm:"not null;index"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// 关联数据
|
||||
Comment Comment `json:"comment,omitempty" gorm:"foreignKey:CommentID"`
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Comment) TableName() string {
|
||||
return "ai_comments"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (CommentReply) TableName() string {
|
||||
return "ai_comment_replies"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (CommentLike) TableName() string {
|
||||
return "ai_comment_likes"
|
||||
}
|
||||
|
||||
// CommentStats 评论统计
|
||||
type CommentStats struct {
|
||||
ProductID uint `json:"product_id"`
|
||||
TotalCount int `json:"total_count"` // 总评论数
|
||||
AverageRating float64 `json:"average_rating"` // 平均评分
|
||||
Rating1Count int `json:"rating_1_count"` // 1星评论数
|
||||
Rating2Count int `json:"rating_2_count"` // 2星评论数
|
||||
Rating3Count int `json:"rating_3_count"` // 3星评论数
|
||||
Rating4Count int `json:"rating_4_count"` // 4星评论数
|
||||
Rating5Count int `json:"rating_5_count"` // 5星评论数
|
||||
HasImagesCount int `json:"has_images_count"` // 带图评论数
|
||||
}
|
||||
212
server/internal/model/common.go
Normal file
212
server/internal/model/common.go
Normal file
@@ -0,0 +1,212 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Coupon 优惠券模型
|
||||
type Coupon struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
Name string `gorm:"size:100;not null" json:"name" binding:"required"`
|
||||
Type uint8 `gorm:"not null" json:"type"` // 1-满减券 2-折扣券 3-免邮券
|
||||
Value uint `gorm:"not null" json:"value"` // 优惠值:满减券为金额(分),折扣券为折扣(如85表示8.5折)
|
||||
MinAmount uint `gorm:"default:0" json:"min_amount"` // 最低消费金额,单位:分
|
||||
TotalCount uint `gorm:"not null" json:"total_count"` // 总发放数量
|
||||
UsedCount uint `gorm:"default:0" json:"used_count"` // 已使用数量
|
||||
StartTime time.Time `gorm:"not null" json:"start_time"`
|
||||
EndTime time.Time `gorm:"not null" json:"end_time"`
|
||||
Status uint8 `gorm:"default:1;index" json:"status"` // 0-禁用 1-启用
|
||||
Description string `gorm:"size:255" json:"description"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
|
||||
// 关联关系
|
||||
UserCoupons []UserCoupon `gorm:"foreignKey:CouponID" json:"user_coupons,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Coupon) TableName() string {
|
||||
return "ai_coupons"
|
||||
}
|
||||
|
||||
// UserCoupon 用户优惠券模型
|
||||
type UserCoupon struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
UserID uint `gorm:"not null;index" json:"user_id"`
|
||||
CouponID uint `gorm:"not null;index" json:"coupon_id"`
|
||||
OrderID *uint `gorm:"index" json:"order_id"` // 使用的订单ID,NULL表示未使用
|
||||
Status uint8 `gorm:"default:0;index" json:"status"` // 0-未使用 1-已使用 2-已过期
|
||||
UsedTime *time.Time `json:"used_time"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
|
||||
// 关联关系
|
||||
User User `gorm:"foreignKey:UserID" json:"user,omitempty"`
|
||||
Coupon Coupon `gorm:"foreignKey:CouponID" json:"coupon,omitempty"`
|
||||
Order Order `gorm:"foreignKey:OrderID" json:"order,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (UserCoupon) TableName() string {
|
||||
return "ai_user_coupons"
|
||||
}
|
||||
|
||||
// Notification 通知模型
|
||||
type Notification struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
UserID uint `gorm:"not null;index" json:"user_id"`
|
||||
Title string `gorm:"size:100;not null" json:"title" binding:"required"`
|
||||
Content string `gorm:"type:text;not null" json:"content" binding:"required"`
|
||||
Type uint8 `gorm:"not null;index" json:"type"` // 1-系统通知 2-订单通知 3-活动通知
|
||||
IsRead uint8 `gorm:"default:0;index" json:"is_read"` // 0-未读 1-已读
|
||||
ReadTime *time.Time `json:"read_time"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
|
||||
// 关联关系
|
||||
User User `gorm:"foreignKey:UserID" json:"user,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Notification) TableName() string {
|
||||
return "ai_notifications"
|
||||
}
|
||||
|
||||
// FileUpload 文件上传模型
|
||||
type FileUpload struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
FileName string `gorm:"size:255;not null" json:"file_name"`
|
||||
FileSize uint `gorm:"not null" json:"file_size"`
|
||||
FileType string `gorm:"size:50;not null" json:"file_type"`
|
||||
FilePath string `gorm:"size:500;not null" json:"file_path"`
|
||||
FileURL string `gorm:"size:500;not null" json:"file_url"`
|
||||
UploadBy uint `gorm:"not null;index" json:"upload_by"` // 上传者ID
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (FileUpload) TableName() string {
|
||||
return "ai_file_uploads"
|
||||
}
|
||||
|
||||
// SystemConfig 系统配置模型
|
||||
type SystemConfig struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
ConfigKey string `gorm:"size:100;uniqueIndex;not null" json:"config_key" binding:"required"`
|
||||
ConfigValue string `gorm:"type:text" json:"config_value"`
|
||||
ConfigDesc string `gorm:"size:255" json:"config_desc"`
|
||||
ConfigType string `gorm:"size:20;default:'string'" json:"config_type"` // string, number, boolean, json
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SystemConfig) TableName() string {
|
||||
return "ai_system_configs"
|
||||
}
|
||||
|
||||
// SystemLog 系统日志模型
|
||||
type SystemLog struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
Level string `gorm:"size:20;not null;index" json:"level"`
|
||||
Message string `gorm:"type:text;not null" json:"message"`
|
||||
Context string `gorm:"type:text" json:"context"` // JSON格式的上下文信息
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SystemLog) TableName() string {
|
||||
return "ai_system_logs"
|
||||
}
|
||||
|
||||
// AdminUser 管理员用户模型
|
||||
type AdminUser struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
Username string `gorm:"size:50;uniqueIndex;not null" json:"username" binding:"required"`
|
||||
Password string `gorm:"size:255;not null" json:"-"` // 不返回密码
|
||||
Nickname string `gorm:"size:50" json:"nickname"`
|
||||
Email string `gorm:"size:100" json:"email"`
|
||||
Phone string `gorm:"size:20" json:"phone"`
|
||||
Avatar string `gorm:"size:255" json:"avatar"`
|
||||
RoleID uint `gorm:"not null;index" json:"role_id"`
|
||||
Status uint8 `gorm:"default:1;index" json:"status"` // 0-禁用 1-正常
|
||||
LastLogin *time.Time `json:"last_login"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
|
||||
// 关联关系
|
||||
Role AdminRole `gorm:"foreignKey:RoleID" json:"role,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (AdminUser) TableName() string {
|
||||
return "ai_admin_users"
|
||||
}
|
||||
|
||||
// AdminRole 管理员角色模型
|
||||
type AdminRole struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
Name string `gorm:"size:50;not null" json:"name" binding:"required"`
|
||||
Description string `gorm:"size:255" json:"description"`
|
||||
Permissions string `gorm:"type:text" json:"permissions"` // JSON格式的权限列表
|
||||
Status uint8 `gorm:"default:1;index" json:"status"` // 0-禁用 1-正常
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
|
||||
// 关联关系
|
||||
AdminUsers []AdminUser `gorm:"foreignKey:RoleID" json:"admin_users,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (AdminRole) TableName() string {
|
||||
return "ai_admin_roles"
|
||||
}
|
||||
|
||||
// OperationLog 操作日志模型
|
||||
type OperationLog struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
UserID uint `gorm:"not null;index" json:"user_id"`
|
||||
UserType string `gorm:"size:20;not null;index" json:"user_type"` // user, admin
|
||||
Action string `gorm:"size:100;not null" json:"action"`
|
||||
Resource string `gorm:"size:100;not null" json:"resource"`
|
||||
Method string `gorm:"size:10;not null" json:"method"`
|
||||
Path string `gorm:"size:255;not null" json:"path"`
|
||||
IP string `gorm:"size:50;not null" json:"ip"`
|
||||
UserAgent string `gorm:"size:500" json:"user_agent"`
|
||||
RequestData string `gorm:"type:text" json:"request_data"`
|
||||
ResponseData string `gorm:"type:text" json:"response_data"`
|
||||
StatusCode int `gorm:"not null" json:"status_code"`
|
||||
Duration int `gorm:"not null" json:"duration"` // 请求耗时,单位:毫秒
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (OperationLog) TableName() string {
|
||||
return "ai_operation_logs"
|
||||
}
|
||||
|
||||
// DataStatistics 数据统计模型
|
||||
type DataStatistics struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
Date string `gorm:"size:10;not null;index" json:"date"` // YYYY-MM-DD
|
||||
Type string `gorm:"size:50;not null;index" json:"type"` // daily, weekly, monthly
|
||||
Metric string `gorm:"size:50;not null;index" json:"metric"` // user_count, order_count, sales_amount等
|
||||
Value uint `gorm:"not null" json:"value"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (DataStatistics) TableName() string {
|
||||
return "ai_data_statistics"
|
||||
}
|
||||
336
server/internal/model/frontend.go
Normal file
336
server/internal/model/frontend.go
Normal file
@@ -0,0 +1,336 @@
|
||||
package model
|
||||
|
||||
// FrontendProduct 前端商品数据结构
|
||||
type FrontendProduct struct {
|
||||
SaasID string `json:"saasId"`
|
||||
StoreID string `json:"storeId"`
|
||||
SpuID string `json:"spuId"`
|
||||
Title string `json:"title"`
|
||||
PrimaryImage string `json:"primaryImage"`
|
||||
Images []string `json:"images"`
|
||||
Video *string `json:"video"`
|
||||
Available int `json:"available"`
|
||||
MinSalePrice string `json:"minSalePrice"`
|
||||
MinLinePrice string `json:"minLinePrice"`
|
||||
MaxSalePrice string `json:"maxSalePrice"`
|
||||
MaxLinePrice string `json:"maxLinePrice"`
|
||||
SpuStockQuantity int `json:"spuStockQuantity"`
|
||||
SoldNum int `json:"soldNum"`
|
||||
IsPutOnSale int `json:"isPutOnSale"`
|
||||
CategoryIds []string `json:"categoryIds"`
|
||||
SpecList []FrontendProductSpec `json:"specList"`
|
||||
SkuList []FrontendProductSKU `json:"skuList"`
|
||||
SpuTagList []FrontendProductTag `json:"spuTagList"`
|
||||
LimitInfo []FrontendLimitInfo `json:"limitInfo,omitempty"`
|
||||
Desc []string `json:"desc"`
|
||||
Etitle string `json:"etitle"`
|
||||
GroupIdList []string `json:"groupIdList,omitempty"`
|
||||
IsAvailable *int `json:"isAvailable,omitempty"`
|
||||
IsSoldOut *bool `json:"isSoldOut,omitempty"`
|
||||
PromotionList interface{} `json:"promotionList"`
|
||||
MinProfitPrice interface{} `json:"minProfitPrice"`
|
||||
}
|
||||
|
||||
// FrontendProductSpec 前端商品规格
|
||||
type FrontendProductSpec struct {
|
||||
SpecID string `json:"specId"`
|
||||
Title string `json:"title"`
|
||||
SpecValueList []FrontendProductSpecValue `json:"specValueList"`
|
||||
}
|
||||
|
||||
// FrontendProductSpecValue 前端商品规格值
|
||||
type FrontendProductSpecValue struct {
|
||||
SpecValueID string `json:"specValueId"`
|
||||
SpecID string `json:"specId"`
|
||||
SaasID string `json:"saasId"`
|
||||
SpecValue string `json:"specValue"`
|
||||
Image string `json:"image"`
|
||||
}
|
||||
|
||||
// FrontendProductSKU 前端商品SKU
|
||||
type FrontendProductSKU struct {
|
||||
SkuID string `json:"skuId"`
|
||||
SkuImage string `json:"skuImage"`
|
||||
SpecInfo []FrontendSKUSpecInfo `json:"specInfo"`
|
||||
PriceInfo []FrontendSKUPriceInfo `json:"priceInfo"`
|
||||
StockInfo FrontendSKUStockInfo `json:"stockInfo"`
|
||||
Weight *FrontendSKUWeight `json:"weight"`
|
||||
Volume interface{} `json:"volume"`
|
||||
ProfitPrice interface{} `json:"profitPrice"`
|
||||
}
|
||||
|
||||
// FrontendSKUSpecInfo 前端SKU规格信息
|
||||
type FrontendSKUSpecInfo struct {
|
||||
SpecID string `json:"specId"`
|
||||
SpecTitle string `json:"specTitle"`
|
||||
SpecValueID string `json:"specValueId"`
|
||||
SpecValue string `json:"specValue"`
|
||||
}
|
||||
|
||||
// FrontendSKUPriceInfo 前端SKU价格信息
|
||||
type FrontendSKUPriceInfo struct {
|
||||
PriceType int `json:"priceType"`
|
||||
Price string `json:"price"`
|
||||
PriceTypeName string `json:"priceTypeName"`
|
||||
}
|
||||
|
||||
// FrontendSKUStockInfo 前端SKU库存信息
|
||||
type FrontendSKUStockInfo struct {
|
||||
StockQuantity int `json:"stockQuantity"`
|
||||
SafeStockQuantity int `json:"safeStockQuantity"`
|
||||
SoldQuantity int `json:"soldQuantity"`
|
||||
}
|
||||
|
||||
// FrontendSKUWeight 前端SKU重量信息
|
||||
type FrontendSKUWeight struct {
|
||||
Value interface{} `json:"value"`
|
||||
Unit string `json:"unit"`
|
||||
}
|
||||
|
||||
// FrontendProductTag 前端商品标签
|
||||
type FrontendProductTag struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Image string `json:"image"`
|
||||
}
|
||||
|
||||
// FrontendLimitInfo 前端限购信息
|
||||
type FrontendLimitInfo struct {
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
// FrontendCategory 前端分类数据结构
|
||||
type FrontendCategory struct {
|
||||
GroupID string `json:"groupId"`
|
||||
Name string `json:"name"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
Children []FrontendCategory `json:"children,omitempty"`
|
||||
}
|
||||
|
||||
// FrontendUserCenter 前端用户中心数据结构
|
||||
type FrontendUserCenter struct {
|
||||
UserInfo FrontendUserInfo `json:"userInfo"`
|
||||
CountsData []FrontendCountData `json:"countsData"`
|
||||
OrderTagInfos []FrontendOrderTagInfo `json:"orderTagInfos"`
|
||||
CustomerServiceInfo FrontendCustomerServiceInfo `json:"customerServiceInfo"`
|
||||
}
|
||||
|
||||
// FrontendUserInfo 前端用户信息
|
||||
type FrontendUserInfo struct {
|
||||
AvatarURL string `json:"avatarUrl"`
|
||||
NickName string `json:"nickName"`
|
||||
PhoneNumber string `json:"phoneNumber"`
|
||||
Gender int `json:"gender"`
|
||||
}
|
||||
|
||||
// FrontendCountData 前端计数数据
|
||||
type FrontendCountData struct {
|
||||
Num int `json:"num"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// FrontendOrderTagInfo 前端订单标签信息
|
||||
type FrontendOrderTagInfo struct {
|
||||
OrderNum int `json:"orderNum"`
|
||||
TabType int `json:"tabType"`
|
||||
}
|
||||
|
||||
// FrontendCustomerServiceInfo 前端客服信息
|
||||
type FrontendCustomerServiceInfo struct {
|
||||
ServicePhone string `json:"servicePhone"`
|
||||
ServiceTimeDuration string `json:"serviceTimeDuration"`
|
||||
}
|
||||
|
||||
// FrontendCartData 前端购物车数据结构
|
||||
type FrontendCartData struct {
|
||||
IsNotEmpty bool `json:"isNotEmpty"`
|
||||
StoreGoods []FrontendStoreGoods `json:"storeGoods"`
|
||||
IsAllSelected bool `json:"isAllSelected"`
|
||||
SelectedGoodsCount int `json:"selectedGoodsCount"`
|
||||
TotalAmount string `json:"totalAmount"`
|
||||
TotalDiscountAmount string `json:"totalDiscountAmount"`
|
||||
}
|
||||
|
||||
// FrontendStoreGoods 前端店铺商品
|
||||
type FrontendStoreGoods struct {
|
||||
StoreID string `json:"storeId"`
|
||||
StoreName string `json:"storeName"`
|
||||
StoreStatus int `json:"storeStatus"`
|
||||
TotalDiscountSalePrice string `json:"totalDiscountSalePrice"`
|
||||
PromotionGoodsList []FrontendPromotionGoods `json:"promotionGoodsList,omitempty"`
|
||||
GoodsList []FrontendCartGoods `json:"goodsList,omitempty"`
|
||||
}
|
||||
|
||||
// FrontendPromotionGoods 前端促销商品
|
||||
type FrontendPromotionGoods struct {
|
||||
Title string `json:"title"`
|
||||
PromotionCode string `json:"promotionCode"`
|
||||
PromotionSubCode string `json:"promotionSubCode"`
|
||||
PromotionID string `json:"promotionId"`
|
||||
TagText []string `json:"tagText"`
|
||||
PromotionStatus int `json:"promotionStatus"`
|
||||
Tag string `json:"tag"`
|
||||
Description string `json:"description"`
|
||||
DoorSillRemain interface{} `json:"doorSillRemain"`
|
||||
IsNeedAddOnShop int `json:"isNeedAddOnShop"`
|
||||
GoodsPromotionList []FrontendCartGoods `json:"goodsPromotionList"`
|
||||
}
|
||||
|
||||
// FrontendCartGoods 前端购物车商品
|
||||
type FrontendCartGoods struct {
|
||||
UID string `json:"uid"`
|
||||
SaasID string `json:"saasId"`
|
||||
StoreID string `json:"storeId"`
|
||||
SpuID string `json:"spuId"`
|
||||
SkuID string `json:"skuId"`
|
||||
IsSelected int `json:"isSelected"`
|
||||
Thumb string `json:"thumb"`
|
||||
Title string `json:"title"`
|
||||
PrimaryImage string `json:"primaryImage"`
|
||||
SpecInfo []FrontendSpecification `json:"specInfo"`
|
||||
Quantity int `json:"quantity"`
|
||||
StockStatus bool `json:"stockStatus"`
|
||||
StockQuantity int `json:"stockQuantity"`
|
||||
Price string `json:"price"`
|
||||
OriginPrice string `json:"originPrice"`
|
||||
JoinCartTime string `json:"joinCartTime"`
|
||||
Available int `json:"available"`
|
||||
PutOnSale int `json:"putOnSale"`
|
||||
Etitle interface{} `json:"etitle"`
|
||||
}
|
||||
|
||||
// FrontendOrderList 前端订单列表数据结构
|
||||
type FrontendOrderList struct {
|
||||
PageNum int `json:"pageNum"`
|
||||
PageSize int `json:"pageSize"`
|
||||
TotalCount int `json:"totalCount"`
|
||||
Orders []FrontendOrder `json:"orders"`
|
||||
}
|
||||
|
||||
// FrontendOrder 前端订单
|
||||
type FrontendOrder struct {
|
||||
SaasID string `json:"saasId"`
|
||||
StoreID string `json:"storeId"`
|
||||
StoreName string `json:"storeName"`
|
||||
UID string `json:"uid"`
|
||||
ParentOrderNo string `json:"parentOrderNo"`
|
||||
OrderID string `json:"orderId"`
|
||||
OrderNo string `json:"orderNo"`
|
||||
OrderType int `json:"orderType"`
|
||||
OrderSubType int `json:"orderSubType"`
|
||||
OrderStatus int `json:"orderStatus"`
|
||||
OrderSubStatus interface{} `json:"orderSubStatus"`
|
||||
TotalAmount string `json:"totalAmount"`
|
||||
GoodsAmount string `json:"goodsAmount"`
|
||||
GoodsAmountApp string `json:"goodsAmountApp"`
|
||||
PaymentAmount string `json:"paymentAmount"`
|
||||
FreightFee string `json:"freightFee"`
|
||||
PackageFee string `json:"packageFee"`
|
||||
DiscountAmount string `json:"discountAmount"`
|
||||
ChannelType int `json:"channelType"`
|
||||
ChannelSource string `json:"channelSource"`
|
||||
ChannelIdentity string `json:"channelIdentity"`
|
||||
Remark string `json:"remark"`
|
||||
CancelType interface{} `json:"cancelType"`
|
||||
CancelReasonType interface{} `json:"cancelReasonType"`
|
||||
CancelReason interface{} `json:"cancelReason"`
|
||||
RightsType interface{} `json:"rightsType"`
|
||||
CreateTime string `json:"createTime"`
|
||||
OrderItemVOs []FrontendOrderItem `json:"orderItemVOs"`
|
||||
LogisticsVO FrontendLogistics `json:"logisticsVO"`
|
||||
PaymentVO FrontendPayment `json:"paymentVO"`
|
||||
}
|
||||
|
||||
// FrontendOrderItem 前端订单项
|
||||
type FrontendOrderItem struct {
|
||||
ID string `json:"id"`
|
||||
OrderNo interface{} `json:"orderNo"`
|
||||
SpuID string `json:"spuId"`
|
||||
SkuID string `json:"skuId"`
|
||||
RoomID interface{} `json:"roomId"`
|
||||
GoodsMainType int `json:"goodsMainType"`
|
||||
GoodsViceType int `json:"goodsViceType"`
|
||||
GoodsName string `json:"goodsName"`
|
||||
Specifications []FrontendSpecification `json:"specifications"`
|
||||
GoodsPictureURL string `json:"goodsPictureUrl"`
|
||||
OriginPrice string `json:"originPrice"`
|
||||
ActualPrice string `json:"actualPrice"`
|
||||
BuyQuantity int `json:"buyQuantity"`
|
||||
ItemTotalAmount string `json:"itemTotalAmount"`
|
||||
ItemDiscountAmount string `json:"itemDiscountAmount"`
|
||||
ItemPaymentAmount string `json:"itemPaymentAmount"`
|
||||
GoodsPaymentPrice string `json:"goodsPaymentPrice"`
|
||||
TagPrice interface{} `json:"tagPrice"`
|
||||
TagText interface{} `json:"tagText"`
|
||||
OutCode interface{} `json:"outCode"`
|
||||
LabelVOs interface{} `json:"labelVOs"`
|
||||
ButtonVOs interface{} `json:"buttonVOs"`
|
||||
}
|
||||
|
||||
// FrontendSpecification 前端规格
|
||||
type FrontendSpecification struct {
|
||||
SpecTitle string `json:"specTitle"`
|
||||
SpecValue string `json:"specValue"`
|
||||
}
|
||||
|
||||
// FrontendLogistics 前端物流信息
|
||||
type FrontendLogistics struct {
|
||||
LogisticsType int `json:"logisticsType"`
|
||||
LogisticsNo string `json:"logisticsNo"`
|
||||
LogisticsStatus interface{} `json:"logisticsStatus"`
|
||||
LogisticsCompanyCode string `json:"logisticsCompanyCode"`
|
||||
LogisticsCompanyName string `json:"logisticsCompanyName"`
|
||||
ReceiverAddressID string `json:"receiverAddressId"`
|
||||
ProvinceCode string `json:"provinceCode"`
|
||||
CityCode string `json:"cityCode"`
|
||||
CountryCode string `json:"countryCode"`
|
||||
ReceiverProvince string `json:"receiverProvince"`
|
||||
ReceiverCity string `json:"receiverCity"`
|
||||
ReceiverCountry string `json:"receiverCountry"`
|
||||
ReceiverArea string `json:"receiverArea"`
|
||||
ReceiverAddress string `json:"receiverAddress"`
|
||||
ReceiverPostCode string `json:"receiverPostCode"`
|
||||
ReceiverLongitude string `json:"receiverLongitude"`
|
||||
ReceiverLatitude string `json:"receiverLatitude"`
|
||||
ReceiverIdentity string `json:"receiverIdentity"`
|
||||
ReceiverPhone string `json:"receiverPhone"`
|
||||
ReceiverName string `json:"receiverName"`
|
||||
ExpectArrivalTime interface{} `json:"expectArrivalTime"`
|
||||
SenderName string `json:"senderName"`
|
||||
SenderPhone string `json:"senderPhone"`
|
||||
SenderAddress string `json:"senderAddress"`
|
||||
SendTime interface{} `json:"sendTime"`
|
||||
ArrivalTime interface{} `json:"arrivalTime"`
|
||||
}
|
||||
|
||||
// FrontendPayment 前端支付信息
|
||||
type FrontendPayment struct {
|
||||
PayStatus int `json:"payStatus"`
|
||||
Amount string `json:"amount"`
|
||||
}
|
||||
|
||||
// FrontendAddress 前端地址数据结构
|
||||
type FrontendAddress struct {
|
||||
SaasID string `json:"saasId"`
|
||||
UID string `json:"uid"`
|
||||
AuthToken interface{} `json:"authToken"`
|
||||
ID string `json:"id"`
|
||||
AddressID string `json:"addressId"`
|
||||
Phone string `json:"phone"`
|
||||
Name string `json:"name"`
|
||||
CountryName string `json:"countryName"`
|
||||
CountryCode string `json:"countryCode"`
|
||||
ProvinceName string `json:"provinceName"`
|
||||
ProvinceCode string `json:"provinceCode"`
|
||||
CityName string `json:"cityName"`
|
||||
CityCode string `json:"cityCode"`
|
||||
DistrictName string `json:"districtName"`
|
||||
DistrictCode string `json:"districtCode"`
|
||||
DetailAddress string `json:"detailAddress"`
|
||||
IsDefault int `json:"isDefault"`
|
||||
AddressTag string `json:"addressTag"`
|
||||
Latitude string `json:"latitude"`
|
||||
Longitude string `json:"longitude"`
|
||||
StoreID interface{} `json:"storeId"`
|
||||
}
|
||||
146
server/internal/model/order.go
Normal file
146
server/internal/model/order.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// 订单状态常量
|
||||
const (
|
||||
OrderStatusPending = 1 // 未付款
|
||||
OrderStatusPaid = 2 // 已付款
|
||||
OrderStatusPreparing = 3 // 待发货
|
||||
OrderStatusShipped = 4 // 已发货
|
||||
OrderStatusReceiving = 5 // 待收货
|
||||
OrderStatusCompleted = 6 // 已完成
|
||||
OrderStatusCancelled = 7 // 已取消
|
||||
OrderStatusReturning = 8 // 退货中
|
||||
OrderStatusRefunded = 9 // 已退款
|
||||
)
|
||||
|
||||
// Cart 购物车
|
||||
type Cart struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
UserID uint `json:"user_id" gorm:"not null"`
|
||||
ProductID uint `json:"product_id" gorm:"not null"`
|
||||
SKUID *uint `json:"sku_id" gorm:"column:sk_uid"`
|
||||
Quantity int `json:"quantity" gorm:"not null"`
|
||||
Selected bool `json:"selected" gorm:"default:true"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
Product Product `json:"product,omitempty" gorm:"foreignKey:ProductID"`
|
||||
SKU ProductSKU `json:"sku,omitempty" gorm:"foreignKey:SKUID"`
|
||||
}
|
||||
|
||||
// Order 订单
|
||||
type Order struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
OrderNo string `json:"order_no" gorm:"size:32;not null;uniqueIndex"`
|
||||
UserID uint `json:"user_id" gorm:"not null"`
|
||||
StoreID uint `json:"store_id" gorm:"default:1"`
|
||||
TotalAmount float64 `json:"total_amount" gorm:"type:decimal(10,2);not null"`
|
||||
PayAmount float64 `json:"pay_amount" gorm:"type:decimal(10,2);not null"`
|
||||
DiscountAmount float64 `json:"discount_amount" gorm:"type:decimal(10,2);default:0.00"`
|
||||
ShippingFee float64 `json:"shipping_fee" gorm:"type:decimal(10,2);default:0.00"`
|
||||
CouponID *uint `json:"coupon_id"`
|
||||
CouponAmount float64 `json:"coupon_amount" gorm:"type:decimal(10,2);default:0.00"`
|
||||
PointsAmount float64 `json:"points_amount" gorm:"type:decimal(10,2);default:0.00"`
|
||||
Status int `json:"status" gorm:"default:1"` // 统一状态:1未付款,2已付款,3待发货,4已发货,5待收货,6已完成,7已取消,8退货中,9已退款
|
||||
PayStatus int `json:"pay_status" gorm:"default:0"` // 兼容字段,建议使用Status统一管理
|
||||
PayMethod string `json:"pay_method" gorm:"size:20"`
|
||||
WechatOutTradeNo string `json:"wechat_out_trade_no" gorm:"size:64;index"` // 微信支付商户订单号,每次支付请求唯一
|
||||
WechatTransactionID string `json:"wechat_transaction_id" gorm:"size:64;index"` // 微信支付交易号,支付成功后由微信返回
|
||||
PayTime *time.Time `json:"pay_time"`
|
||||
ShippedAt *time.Time `json:"shipped_at" gorm:"column:shipped_at"`
|
||||
ReceiveTime *time.Time `json:"receive_time"`
|
||||
CancelTime *time.Time `json:"cancel_time"`
|
||||
CancelReason string `json:"cancel_reason" gorm:"size:255"`
|
||||
RefundAmount float64 `json:"refund_amount" gorm:"type:decimal(10,2);default:0.00"`
|
||||
RefundReason string `json:"refund_reason" gorm:"size:255"`
|
||||
RefundTime *time.Time `json:"refund_time"`
|
||||
RefundedAt *time.Time `json:"refunded_at"`
|
||||
ReceiverName string `json:"receiver_name" gorm:"size:50;not null"`
|
||||
ReceiverPhone string `json:"receiver_phone" gorm:"size:20;not null"`
|
||||
ReceiverAddress string `json:"receiver_address" gorm:"size:255;not null"`
|
||||
LogisticsCompany string `json:"logistics_company" gorm:"column:logistics_company;size:50"`
|
||||
LogisticsNo string `json:"logistics_no" gorm:"column:logistics_no;size:100"`
|
||||
Remark string `json:"remark" gorm:"size:255"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
Store Store `json:"store,omitempty" gorm:"foreignKey:StoreID"`
|
||||
Coupon Coupon `json:"coupon,omitempty" gorm:"foreignKey:CouponID"`
|
||||
OrderItems []OrderItem `json:"order_items,omitempty" gorm:"foreignKey:OrderID"`
|
||||
}
|
||||
|
||||
// OrderItem 订单项
|
||||
type OrderItem struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
OrderID uint `json:"order_id" gorm:"not null"`
|
||||
ProductID uint `json:"product_id" gorm:"not null"`
|
||||
SpecID *uint `json:"spec_id" gorm:"column:spec_id"`
|
||||
SKUID *uint `json:"sku_id" gorm:"column:sk_uid"`
|
||||
Quantity int `json:"quantity" gorm:"not null"`
|
||||
Price float64 `json:"price" gorm:"type:decimal(10,2);not null"`
|
||||
TotalPrice float64 `json:"total_price" gorm:"type:decimal(10,2);not null"`
|
||||
ProductName string `json:"product_name" gorm:"size:100;not null"`
|
||||
ProductImage string `json:"product_image" gorm:"size:255"`
|
||||
SpecName string `json:"spec_name" gorm:"column:spec_name"`
|
||||
SpecValue string `json:"spec_value" gorm:"column:spec_value"`
|
||||
SpecInfo JSONMap `json:"spec_info" gorm:"type:json"`
|
||||
IsCommented bool `json:"is_commented" gorm:"default:false"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Order Order `json:"order,omitempty" gorm:"foreignKey:OrderID"`
|
||||
Product Product `json:"product,omitempty" gorm:"foreignKey:ProductID"`
|
||||
SKU ProductSKU `json:"sku,omitempty" gorm:"foreignKey:SKUID"`
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TableName 指定表名
|
||||
func (Cart) TableName() string {
|
||||
return "ai_carts"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Order) TableName() string {
|
||||
return "ai_orders"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (OrderItem) TableName() string {
|
||||
return "order_items"
|
||||
}
|
||||
|
||||
// GetStatusText 获取订单状态文本
|
||||
func (o *Order) GetStatusText() string {
|
||||
switch o.Status {
|
||||
case OrderStatusPending:
|
||||
return "未付款"
|
||||
case OrderStatusPaid:
|
||||
return "已付款"
|
||||
case OrderStatusPreparing:
|
||||
return "待发货"
|
||||
case OrderStatusShipped:
|
||||
return "已发货"
|
||||
case OrderStatusReceiving:
|
||||
return "待收货"
|
||||
case OrderStatusCompleted:
|
||||
return "已完成"
|
||||
case OrderStatusCancelled:
|
||||
return "已取消"
|
||||
case OrderStatusReturning:
|
||||
return "退货中"
|
||||
case OrderStatusRefunded:
|
||||
return "已退款"
|
||||
default:
|
||||
return "未知状态"
|
||||
}
|
||||
}
|
||||
84
server/internal/model/points.go
Normal file
84
server/internal/model/points.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// PointsHistory 积分历史记录
|
||||
type PointsHistory struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
UserID uint `json:"user_id" gorm:"not null;index"`
|
||||
Type int `json:"type" gorm:"not null;comment:类型 1=获得 2=消费"`
|
||||
Points int `json:"points" gorm:"not null;comment:积分数量"`
|
||||
Description string `json:"description" gorm:"size:255;comment:描述"`
|
||||
OrderID *uint `json:"order_id" gorm:"index;comment:关联订单ID"`
|
||||
OrderNo string `json:"order_no" gorm:"size:50;comment:订单号"`
|
||||
ProductName string `json:"product_name" gorm:"size:255;comment:商品名称"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
User User `json:"user" gorm:"foreignKey:UserID"`
|
||||
Order *Order `json:"order,omitempty" gorm:"foreignKey:OrderID"`
|
||||
}
|
||||
|
||||
// PointsRule 积分规则
|
||||
type PointsRule struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
Title string `json:"title" gorm:"size:100;not null;comment:规则标题"`
|
||||
Description string `json:"description" gorm:"size:500;comment:规则描述"`
|
||||
Icon string `json:"icon" gorm:"size:100;comment:图标"`
|
||||
Points int `json:"points" gorm:"comment:积分数量"`
|
||||
Type int `json:"type" gorm:"comment:类型 1=获得 2=消费"`
|
||||
Status int `json:"status" gorm:"default:1;comment:状态 0=禁用 1=启用"`
|
||||
Sort int `json:"sort" gorm:"default:0;comment:排序"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// PointsExchange 积分兑换商品
|
||||
type PointsExchange struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
Name string `json:"name" gorm:"size:255;not null;comment:商品名称"`
|
||||
Description string `json:"description" gorm:"size:500;comment:商品描述"`
|
||||
Image string `json:"image" gorm:"size:255;comment:商品图片"`
|
||||
Points int `json:"points" gorm:"not null;comment:所需积分"`
|
||||
Stock int `json:"stock" gorm:"default:0;comment:库存数量"`
|
||||
ExchangeCount int `json:"exchange_count" gorm:"default:0;comment:兑换次数"`
|
||||
Status int `json:"status" gorm:"default:1;comment:状态 0=下架 1=上架"`
|
||||
Sort int `json:"sort" gorm:"default:0;comment:排序"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// PointsExchangeRecord 积分兑换记录
|
||||
type PointsExchangeRecord struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
UserID uint `json:"user_id" gorm:"not null;index"`
|
||||
PointsExchangeID uint `json:"points_exchange_id" gorm:"not null;index"`
|
||||
Points int `json:"points" gorm:"not null;comment:消耗积分"`
|
||||
Status int `json:"status" gorm:"default:1;comment:状态 1=已兑换 2=已发放"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
User User `json:"user" gorm:"foreignKey:UserID"`
|
||||
PointsExchange PointsExchange `json:"points_exchange" gorm:"foreignKey:PointsExchangeID"`
|
||||
}
|
||||
|
||||
// TableName 设置表名
|
||||
func (PointsHistory) TableName() string {
|
||||
return "points_history"
|
||||
}
|
||||
|
||||
func (PointsRule) TableName() string {
|
||||
return "points_rules"
|
||||
}
|
||||
|
||||
func (PointsExchange) TableName() string {
|
||||
return "points_exchange"
|
||||
}
|
||||
|
||||
func (PointsExchangeRecord) TableName() string {
|
||||
return "points_exchange_records"
|
||||
}
|
||||
237
server/internal/model/product.go
Normal file
237
server/internal/model/product.go
Normal file
@@ -0,0 +1,237 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// JSONSlice 自定义JSON切片类型
|
||||
type JSONSlice []string
|
||||
|
||||
func (j JSONSlice) Value() (driver.Value, error) {
|
||||
return json.Marshal(j)
|
||||
}
|
||||
|
||||
func (j *JSONSlice) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
*j = nil
|
||||
return nil
|
||||
}
|
||||
bytes, ok := value.([]byte)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(bytes, j)
|
||||
}
|
||||
|
||||
// JSONMap 自定义JSON映射类型
|
||||
type JSONMap map[string]interface{}
|
||||
|
||||
func (j JSONMap) Value() (driver.Value, error) {
|
||||
if j == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return json.Marshal(j)
|
||||
}
|
||||
|
||||
func (j *JSONMap) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
*j = make(map[string]interface{})
|
||||
return nil
|
||||
}
|
||||
|
||||
switch v := value.(type) {
|
||||
case []byte:
|
||||
if len(v) == 0 {
|
||||
*j = make(map[string]interface{})
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(v, j)
|
||||
case string:
|
||||
if v == "" {
|
||||
*j = make(map[string]interface{})
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal([]byte(v), j)
|
||||
default:
|
||||
*j = make(map[string]interface{})
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Store 店铺
|
||||
type Store struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
Name string `json:"name" gorm:"size:100;not null"`
|
||||
Logo string `json:"logo" gorm:"size:255"`
|
||||
Description string `json:"description" gorm:"type:text"`
|
||||
Status int `json:"status" gorm:"default:1"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// Category 商品分类
|
||||
type Category struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
Name string `json:"name" gorm:"size:50;not null"`
|
||||
ParentID *uint `json:"parent_id"`
|
||||
Level int `json:"level" gorm:"default:1"`
|
||||
Icon string `json:"icon" gorm:"size:255"`
|
||||
Description string `json:"description" gorm:"size:255"`
|
||||
Sort int `json:"sort" gorm:"default:0"`
|
||||
Status int `json:"status" gorm:"default:1"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Children []Category `json:"children,omitempty" gorm:"-"`
|
||||
HasChildren bool `json:"hasChildren" gorm:"-"`
|
||||
}
|
||||
|
||||
// Product 商品
|
||||
type Product struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
CategoryID uint `json:"category_id" gorm:"not null"`
|
||||
StoreID uint `json:"store_id" gorm:"default:1"`
|
||||
Name string `json:"name" gorm:"size:100;not null"`
|
||||
Description string `json:"description" gorm:"type:text"`
|
||||
Price float64 `json:"price" gorm:"type:decimal(10,2);not null"`
|
||||
OrigPrice float64 `json:"orig_price" gorm:"type:decimal(10,2)"`
|
||||
Stock int `json:"stock" gorm:"default:0"`
|
||||
Sales int `json:"sales" gorm:"default:0"`
|
||||
CommentCount int `json:"comment_count" gorm:"default:0"`
|
||||
AverageRating float64 `json:"average_rating" gorm:"type:decimal(3,2);default:0.00"`
|
||||
MainImage string `json:"main_image" gorm:"size:255"`
|
||||
Images JSONSlice `json:"images" gorm:"type:json"`
|
||||
VideoURL string `json:"video_url" gorm:"size:255"`
|
||||
DetailImages JSONSlice `json:"detail_images" gorm:"type:json"`
|
||||
Status int `json:"status" gorm:"default:1"`
|
||||
IsHot bool `json:"is_hot" gorm:"default:false"`
|
||||
IsNew bool `json:"is_new" gorm:"default:false"`
|
||||
IsRecommend bool `json:"is_recommend" gorm:"default:false"`
|
||||
LimitBuy int `json:"limit_buy" gorm:"default:0"`
|
||||
Points int `json:"points" gorm:"default:0"`
|
||||
Level int `json:"level" gorm:"default:0"`
|
||||
Weight float64 `json:"weight" gorm:"type:decimal(8,2)"`
|
||||
Unit string `json:"unit" gorm:"size:20"`
|
||||
Sort int `json:"sort" gorm:"default:0"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `json:"deleted_at,omitempty" gorm:"index"`
|
||||
|
||||
// 关联数据
|
||||
Category Category `json:"category,omitempty" gorm:"foreignKey:CategoryID"`
|
||||
Store Store `json:"store,omitempty" gorm:"foreignKey:StoreID"`
|
||||
SKUs []ProductSKU `json:"skus,omitempty" gorm:"foreignKey:ProductID"`
|
||||
Tags []ProductTag `json:"tags,omitempty" gorm:"many2many:ai_product_tag_relations;"`
|
||||
Specs []ProductSpec `json:"specs,omitempty" gorm:"foreignKey:ProductID"`
|
||||
ProductImages []ProductImage `json:"product_images,omitempty" gorm:"foreignKey:ProductID"`
|
||||
}
|
||||
|
||||
// ProductSKU 商品SKU
|
||||
type ProductSKU struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
ProductID uint `json:"product_id" gorm:"not null"`
|
||||
SKUCode string `json:"sku_code" gorm:"size:50;not null;uniqueIndex"`
|
||||
SpecValues JSONMap `json:"spec_values" gorm:"type:json;not null"`
|
||||
Price float64 `json:"price" gorm:"type:decimal(10,2);not null"`
|
||||
OriginalPrice float64 `json:"original_price" gorm:"type:decimal(10,2)"`
|
||||
Stock int `json:"stock" gorm:"default:0"`
|
||||
Image string `json:"image" gorm:"size:255"`
|
||||
Weight float64 `json:"weight" gorm:"type:decimal(8,2)"`
|
||||
Status int `json:"status" gorm:"default:1"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ProductTag 商品标签
|
||||
type ProductTag struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
Name string `json:"name" gorm:"size:50;not null"`
|
||||
Color string `json:"color" gorm:"size:20;default:#FF5722"`
|
||||
Sort int `json:"sort" gorm:"default:0"`
|
||||
Status int `json:"status" gorm:"default:1"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ProductSpec 商品规格
|
||||
type ProductSpec struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
ProductID uint `json:"product_id" gorm:"not null"`
|
||||
Name string `json:"name" gorm:"size:50;not null"`
|
||||
Value string `json:"value" gorm:"size:100;not null"`
|
||||
Price float64 `json:"price" gorm:"type:decimal(10,2)"`
|
||||
Stock int `json:"stock" gorm:"default:0"`
|
||||
SKU string `json:"sku" gorm:"size:50"`
|
||||
Sort int `json:"sort" gorm:"default:0"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ProductImage 商品图片
|
||||
type ProductImage struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
ProductID uint `json:"product_id" gorm:"not null"`
|
||||
ImageURL string `json:"image_url" gorm:"size:255;not null"`
|
||||
Sort int `json:"sort" gorm:"default:0"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ProductReview 商品评价
|
||||
type ProductReview struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
ProductID uint `json:"product_id" gorm:"not null"`
|
||||
UserID uint `json:"user_id" gorm:"not null"`
|
||||
OrderID *uint `json:"order_id"`
|
||||
Rating int `json:"rating" gorm:"not null"`
|
||||
Content string `json:"content" gorm:"type:text"`
|
||||
Images JSONSlice `json:"images" gorm:"type:json"`
|
||||
Status int `json:"status" gorm:"default:1"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TableName 指定表名
|
||||
func (Store) TableName() string {
|
||||
return "ai_stores"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Category) TableName() string {
|
||||
return "ai_categories"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Product) TableName() string {
|
||||
return "ai_products"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (ProductSKU) TableName() string {
|
||||
return "ai_product_skus"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (ProductTag) TableName() string {
|
||||
return "ai_product_tags"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (ProductSpec) TableName() string {
|
||||
return "ai_product_specs"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (ProductImage) TableName() string {
|
||||
return "ai_product_images"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (ProductReview) TableName() string {
|
||||
return "ai_product_reviews"
|
||||
}
|
||||
187
server/internal/model/refund.go
Normal file
187
server/internal/model/refund.go
Normal file
@@ -0,0 +1,187 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// 退款状态常量
|
||||
const (
|
||||
RefundStatusPending = 1 // 待审核
|
||||
RefundStatusApproved = 2 // 审核通过
|
||||
RefundStatusRejected = 3 // 审核拒绝
|
||||
RefundStatusProcessing = 4 // 退款中
|
||||
RefundStatusSuccess = 5 // 退款成功
|
||||
RefundStatusFailed = 6 // 退款失败
|
||||
)
|
||||
|
||||
// 退款类型常量
|
||||
const (
|
||||
RefundTypeRefundOnly = 1 // 仅退款
|
||||
RefundTypeReturn = 2 // 退货退款
|
||||
)
|
||||
|
||||
// 微信退款状态常量
|
||||
const (
|
||||
WechatRefundStatusSuccess = "SUCCESS" // 退款成功
|
||||
WechatRefundStatusClosed = "CLOSED" // 退款关闭
|
||||
WechatRefundStatusProcessing = "PROCESSING" // 退款处理中
|
||||
)
|
||||
|
||||
// Refund 退款记录
|
||||
type Refund struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
RefundNo string `json:"refund_no" gorm:"size:64;not null;uniqueIndex"`
|
||||
OrderID uint `json:"order_id" gorm:"not null;index"`
|
||||
OrderNo string `json:"order_no" gorm:"size:32;not null;index"`
|
||||
UserID uint `json:"user_id" gorm:"not null;index"`
|
||||
RefundType int `json:"refund_type" gorm:"not null;default:1"`
|
||||
RefundReason string `json:"refund_reason" gorm:"size:255;not null"`
|
||||
RefundDescription string `json:"refund_description" gorm:"type:text"`
|
||||
RefundAmount float64 `json:"refund_amount" gorm:"type:decimal(10,2);not null"`
|
||||
RefundFee float64 `json:"refund_fee" gorm:"type:decimal(10,2);default:0.00"`
|
||||
ActualRefundAmount float64 `json:"actual_refund_amount" gorm:"type:decimal(10,2);not null"`
|
||||
Status int `json:"status" gorm:"not null;default:1;index"`
|
||||
ApplyTime time.Time `json:"apply_time" gorm:"not null;default:CURRENT_TIMESTAMP;index"`
|
||||
AuditTime *time.Time `json:"audit_time"`
|
||||
RefundTime *time.Time `json:"refund_time"`
|
||||
AdminID *uint `json:"admin_id"`
|
||||
AdminRemark string `json:"admin_remark" gorm:"type:text"`
|
||||
RejectReason string `json:"reject_reason" gorm:"size:255"`
|
||||
|
||||
// 微信退款相关字段
|
||||
WechatRefundID string `json:"wechat_refund_id" gorm:"size:64;index"`
|
||||
WechatOutRefundNo string `json:"wechat_out_refund_no" gorm:"size:64;uniqueIndex"`
|
||||
WechatTransactionID string `json:"wechat_transaction_id" gorm:"size:64;index"`
|
||||
WechatRefundStatus string `json:"wechat_refund_status" gorm:"size:32"`
|
||||
WechatRefundRecvAccount string `json:"wechat_refund_recv_account" gorm:"size:64"`
|
||||
WechatSuccessTime *time.Time `json:"wechat_success_time"`
|
||||
WechatUserReceivedAccount string `json:"wechat_user_received_account" gorm:"size:64"`
|
||||
WechatRefundAccount string `json:"wechat_refund_account" gorm:"size:32"`
|
||||
|
||||
// 退货相关字段
|
||||
ReturnLogisticsCompany string `json:"return_logistics_company" gorm:"size:50"`
|
||||
ReturnLogisticsNo string `json:"return_logistics_no" gorm:"size:100"`
|
||||
ReturnAddress string `json:"return_address" gorm:"size:255"`
|
||||
GoodsReceivedTime *time.Time `json:"goods_received_time"`
|
||||
|
||||
// 图片证据
|
||||
EvidenceImages JSONSlice `json:"evidence_images" gorm:"type:json"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
Order Order `json:"order,omitempty" gorm:"foreignKey:OrderID"`
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
Admin User `json:"admin,omitempty" gorm:"foreignKey:AdminID"`
|
||||
RefundItems []RefundItem `json:"refund_items,omitempty" gorm:"foreignKey:RefundID"`
|
||||
RefundLogs []RefundLog `json:"refund_logs,omitempty" gorm:"foreignKey:RefundID"`
|
||||
}
|
||||
|
||||
// RefundItem 退款项目
|
||||
type RefundItem struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
RefundID uint `json:"refund_id" gorm:"not null;index"`
|
||||
OrderItemID uint `json:"order_item_id" gorm:"not null;index"`
|
||||
ProductID uint `json:"product_id" gorm:"not null;index"`
|
||||
SKUID *uint `json:"sku_id" gorm:"column:sku_id"`
|
||||
ProductName string `json:"product_name" gorm:"size:100;not null"`
|
||||
ProductImage string `json:"product_image" gorm:"size:255"`
|
||||
SpecInfo JSONMap `json:"spec_info" gorm:"type:json"`
|
||||
Quantity int `json:"quantity" gorm:"not null"`
|
||||
UnitPrice float64 `json:"unit_price" gorm:"type:decimal(10,2);not null"`
|
||||
TotalPrice float64 `json:"total_price" gorm:"type:decimal(10,2);not null"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
Refund Refund `json:"refund,omitempty" gorm:"foreignKey:RefundID"`
|
||||
OrderItem OrderItem `json:"order_item,omitempty" gorm:"foreignKey:OrderItemID"`
|
||||
Product Product `json:"product,omitempty" gorm:"foreignKey:ProductID"`
|
||||
SKU ProductSKU `json:"sku,omitempty" gorm:"foreignKey:SKUID"`
|
||||
}
|
||||
|
||||
// RefundLog 退款操作日志
|
||||
type RefundLog struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
RefundID uint `json:"refund_id" gorm:"not null;index"`
|
||||
Action string `json:"action" gorm:"size:50;not null;index"`
|
||||
StatusFrom *int `json:"status_from"`
|
||||
StatusTo *int `json:"status_to"`
|
||||
OperatorType string `json:"operator_type" gorm:"size:20;not null"`
|
||||
OperatorID *uint `json:"operator_id"`
|
||||
Remark string `json:"remark" gorm:"type:text"`
|
||||
ExtraData JSONMap `json:"extra_data" gorm:"type:json"`
|
||||
CreatedAt time.Time `json:"created_at" gorm:"index"`
|
||||
|
||||
// 关联数据
|
||||
Refund Refund `json:"refund,omitempty" gorm:"foreignKey:RefundID"`
|
||||
Operator User `json:"operator,omitempty" gorm:"foreignKey:OperatorID"`
|
||||
}
|
||||
|
||||
// TableName 设置表名
|
||||
func (Refund) TableName() string {
|
||||
return "ai_refunds"
|
||||
}
|
||||
|
||||
// TableName 设置表名
|
||||
func (RefundItem) TableName() string {
|
||||
return "ai_refund_items"
|
||||
}
|
||||
|
||||
// TableName 设置表名
|
||||
func (RefundLog) TableName() string {
|
||||
return "ai_refund_logs"
|
||||
}
|
||||
|
||||
// GetStatusText 获取退款状态文本
|
||||
func (r *Refund) GetStatusText() string {
|
||||
switch r.Status {
|
||||
case RefundStatusPending:
|
||||
return "待审核"
|
||||
case RefundStatusApproved:
|
||||
return "审核通过"
|
||||
case RefundStatusRejected:
|
||||
return "审核拒绝"
|
||||
case RefundStatusProcessing:
|
||||
return "退款中"
|
||||
case RefundStatusSuccess:
|
||||
return "退款成功"
|
||||
case RefundStatusFailed:
|
||||
return "退款失败"
|
||||
default:
|
||||
return "未知状态"
|
||||
}
|
||||
}
|
||||
|
||||
// GetRefundTypeText 获取退款类型文本
|
||||
func (r *Refund) GetRefundTypeText() string {
|
||||
switch r.RefundType {
|
||||
case RefundTypeRefundOnly:
|
||||
return "仅退款"
|
||||
case RefundTypeReturn:
|
||||
return "退货退款"
|
||||
default:
|
||||
return "未知类型"
|
||||
}
|
||||
}
|
||||
|
||||
// IsWechatRefundSuccess 判断微信退款是否成功
|
||||
func (r *Refund) IsWechatRefundSuccess() bool {
|
||||
return r.WechatRefundStatus == WechatRefundStatusSuccess
|
||||
}
|
||||
|
||||
// CanCancel 判断是否可以取消退款申请
|
||||
func (r *Refund) CanCancel() bool {
|
||||
return r.Status == RefundStatusPending
|
||||
}
|
||||
|
||||
// CanAudit 判断是否可以审核
|
||||
func (r *Refund) CanAudit() bool {
|
||||
return r.Status == RefundStatusPending
|
||||
}
|
||||
|
||||
// CanRefund 判断是否可以执行退款
|
||||
func (r *Refund) CanRefund() bool {
|
||||
return r.Status == RefundStatusApproved
|
||||
}
|
||||
123
server/internal/model/role.go
Normal file
123
server/internal/model/role.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Role 角色
|
||||
type Role struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
Name string `json:"name" gorm:"size:50;not null;uniqueIndex"`
|
||||
DisplayName string `json:"display_name" gorm:"size:100;not null"`
|
||||
Description string `json:"description" gorm:"size:255"`
|
||||
Status int `json:"status" gorm:"default:1"` // 0禁用,1正常
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
Permissions []Permission `json:"permissions,omitempty" gorm:"many2many:ai_role_permissions;"`
|
||||
Users []User `json:"users,omitempty" gorm:"many2many:ai_user_roles;"`
|
||||
}
|
||||
|
||||
// Permission 权限
|
||||
type Permission struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
Name string `json:"name" gorm:"size:50;not null;uniqueIndex"`
|
||||
DisplayName string `json:"display_name" gorm:"size:100;not null"`
|
||||
Description string `json:"description" gorm:"size:255"`
|
||||
Module string `json:"module" gorm:"size:50;not null"` // 模块名称,如:user, product, order
|
||||
Action string `json:"action" gorm:"size:50;not null"` // 操作名称,如:create, read, update, delete
|
||||
Resource string `json:"resource" gorm:"size:50"` // 资源名称
|
||||
Status int `json:"status" gorm:"default:1"` // 0禁用,1正常
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
Roles []Role `json:"roles,omitempty" gorm:"many2many:ai_role_permissions;"`
|
||||
}
|
||||
|
||||
// UserRole 用户角色关联
|
||||
type UserRole struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
UserID uint `json:"user_id" gorm:"not null"`
|
||||
RoleID uint `json:"role_id" gorm:"not null"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
Role Role `json:"role,omitempty" gorm:"foreignKey:RoleID"`
|
||||
}
|
||||
|
||||
// RolePermission 角色权限关联
|
||||
type RolePermission struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
RoleID uint `json:"role_id" gorm:"not null"`
|
||||
PermissionID uint `json:"permission_id" gorm:"not null"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
Role Role `json:"role,omitempty" gorm:"foreignKey:RoleID"`
|
||||
Permission Permission `json:"permission,omitempty" gorm:"foreignKey:PermissionID"`
|
||||
}
|
||||
|
||||
// UserLoginLog 用户登录日志
|
||||
type UserLoginLog struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
UserID uint `json:"user_id" gorm:"not null"`
|
||||
LoginIP string `json:"login_ip" gorm:"size:45"`
|
||||
UserAgent string `json:"user_agent" gorm:"size:500"`
|
||||
LoginTime time.Time `json:"login_time"`
|
||||
Status int `json:"status" gorm:"default:1"` // 1成功,0失败
|
||||
Remark string `json:"remark" gorm:"size:255"`
|
||||
|
||||
// 关联数据
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
}
|
||||
|
||||
// UserOperationLog 用户操作日志
|
||||
type UserOperationLog struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
UserID uint `json:"user_id" gorm:"not null"`
|
||||
Module string `json:"module" gorm:"size:50;not null"` // 模块名称
|
||||
Action string `json:"action" gorm:"size:50;not null"` // 操作名称
|
||||
Description string `json:"description" gorm:"size:255"` // 操作描述
|
||||
IP string `json:"ip" gorm:"size:45"` // 操作IP
|
||||
UserAgent string `json:"user_agent" gorm:"size:500"` // 用户代理
|
||||
RequestData string `json:"request_data" gorm:"type:text"` // 请求数据
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
// 关联数据
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Role) TableName() string {
|
||||
return "ai_roles"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Permission) TableName() string {
|
||||
return "ai_permissions"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (UserRole) TableName() string {
|
||||
return "ai_user_roles"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (RolePermission) TableName() string {
|
||||
return "ai_role_permissions"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (UserLoginLog) TableName() string {
|
||||
return "ai_user_login_logs"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (UserOperationLog) TableName() string {
|
||||
return "ai_user_operation_logs"
|
||||
}
|
||||
45
server/internal/model/service.go
Normal file
45
server/internal/model/service.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// AfterSale 售后服务
|
||||
type AfterSale struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
OrderID uint `json:"order_id" gorm:"not null"`
|
||||
OrderItemID uint `json:"order_item_id" gorm:"not null"`
|
||||
UserID uint `json:"user_id" gorm:"not null"`
|
||||
Type int `json:"type" gorm:"not null"` // 1退货,2换货,3维修
|
||||
Reason string `json:"reason" gorm:"size:255;not null"`
|
||||
Description string `json:"description" gorm:"type:text"`
|
||||
Images JSONSlice `json:"images" gorm:"type:json"`
|
||||
Status int `json:"status" gorm:"default:1"` // 1待审核,2已同意,3已拒绝,4处理中,5已完成
|
||||
AdminRemark string `json:"admin_remark" gorm:"type:text"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
Order Order `json:"order,omitempty" gorm:"foreignKey:OrderID"`
|
||||
OrderItem OrderItem `json:"order_item,omitempty" gorm:"foreignKey:OrderItemID"`
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
}
|
||||
|
||||
// Invoice 发票
|
||||
type Invoice struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
OrderID uint `json:"order_id" gorm:"not null"`
|
||||
UserID uint `json:"user_id" gorm:"not null"`
|
||||
Type int `json:"type" gorm:"not null"` // 1个人,2企业
|
||||
Title string `json:"title" gorm:"size:255;not null"`
|
||||
TaxNumber string `json:"tax_number" gorm:"size:50"`
|
||||
Amount float64 `json:"amount" gorm:"type:decimal(10,2);not null"`
|
||||
Status int `json:"status" gorm:"default:1"` // 1待开具,2已开具,3已邮寄
|
||||
InvoiceNo string `json:"invoice_no" gorm:"size:50"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
Order Order `json:"order,omitempty" gorm:"foreignKey:OrderID"`
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
}
|
||||
99
server/internal/model/user.go
Normal file
99
server/internal/model/user.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// User 用户
|
||||
type User struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
OpenID string `json:"openid" gorm:"column:open_id;type:varchar(50);not null;uniqueIndex"`
|
||||
UnionID string `json:"unionid" gorm:"column:union_id;type:varchar(50)"`
|
||||
Nickname string `json:"nickname" gorm:"size:50"`
|
||||
Avatar string `json:"avatar" gorm:"size:255"`
|
||||
Gender int `json:"gender" gorm:"default:0"` // 0未知,1男,2女
|
||||
Phone string `json:"phone" gorm:"size:20"`
|
||||
Email string `json:"email" gorm:"size:100"`
|
||||
Birthday *time.Time `json:"birthday"`
|
||||
Points int `json:"points" gorm:"default:0"`
|
||||
Level int `json:"level" gorm:"default:1"`
|
||||
Status int `json:"status" gorm:"default:1"` // 0禁用,1正常
|
||||
|
||||
// 微信相关字段(按照官方文档标准)
|
||||
WeChatSessionKey string `json:"-" gorm:"column:wechat_session_key;type:varchar(255);index"` // 不返回给前端,敏感信息
|
||||
SessionExpiry *time.Time `json:"-" gorm:"column:session_expiry;type:timestamp;index"` // 不返回给前端,使用指针类型支持NULL
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `json:"deleted_at,omitempty" gorm:"index"`
|
||||
|
||||
// 关联数据
|
||||
Addresses []UserAddress `json:"addresses,omitempty" gorm:"foreignKey:UserID"`
|
||||
Favorites []UserFavorite `json:"favorites,omitempty" gorm:"foreignKey:UserID"`
|
||||
Coupons []UserCoupon `json:"coupons,omitempty" gorm:"foreignKey:UserID"`
|
||||
Roles []Role `json:"roles,omitempty" gorm:"many2many:ai_user_roles;"`
|
||||
}
|
||||
|
||||
// UserAddress 用户地址
|
||||
type UserAddress struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
UserID uint `json:"user_id" gorm:"not null"`
|
||||
Name string `json:"name" gorm:"size:50;not null"`
|
||||
Phone string `json:"phone" gorm:"size:20;not null"`
|
||||
CountryName string `json:"country_name" gorm:"size:50;default:中国"`
|
||||
ProvinceName string `json:"province_name" gorm:"size:50;not null"`
|
||||
CityName string `json:"city_name" gorm:"size:50;not null"`
|
||||
DistrictName string `json:"district_name" gorm:"size:50;not null"`
|
||||
DetailAddress string `json:"detail_address" gorm:"size:255;not null"`
|
||||
AddressTag string `json:"address_tag" gorm:"size:20"` // 家、公司等标签
|
||||
Latitude float64 `json:"latitude" gorm:"type:decimal(10,6)"`
|
||||
Longitude float64 `json:"longitude" gorm:"type:decimal(10,6)"`
|
||||
IsDefault bool `json:"is_default" gorm:"default:false"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
}
|
||||
|
||||
// UserFavorite 用户收藏
|
||||
type UserFavorite struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
UserID uint `json:"user_id" gorm:"not null"`
|
||||
ProductID uint `json:"product_id" gorm:"not null"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联数据
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
Product Product `json:"product,omitempty" gorm:"foreignKey:ProductID"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (User) TableName() string {
|
||||
return "ai_users"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (UserAddress) TableName() string {
|
||||
return "ai_user_addresses"
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (UserFavorite) TableName() string {
|
||||
return "ai_user_favorites"
|
||||
}
|
||||
|
||||
// BeforeCreate 创建前钩子
|
||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
||||
// 可以在这里添加创建前的逻辑
|
||||
return nil
|
||||
}
|
||||
|
||||
// BeforeUpdate 更新前钩子
|
||||
func (u *User) BeforeUpdate(tx *gorm.DB) error {
|
||||
// 可以在这里添加更新前的逻辑
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user