增加状态切换

This commit is contained in:
2026-04-13 20:01:40 +08:00
parent 16f33e4beb
commit c8715b8724
9 changed files with 745 additions and 78 deletions
+239 -61
View File
@@ -12,11 +12,11 @@ import (
)
type CostItem struct {
Cost int `json:"cost"` // 费用
Cost int `json:"cost"` // 费用(分)
CostT int `json:"costt"` // 总价
CurrencyType string `json:"currencytype"` // 货币类型
CurrencyType int `json:"currencytype"` // 货币类型: 1-CNY 2-MOP 3-HKD 4-USD
Int int `json:"int"` // 数量
Type string `json:"type"` // 费用类型
Type int `json:"type"` // 费用类型: 1-单价 2-运费
}
type From_purchase_addorder struct {
Costs []CostItem `json:"costs"` // 成本
@@ -32,22 +32,26 @@ type From_purchase_addorder struct {
}
type TabPurchaseOrder struct {
ID uint `gorm:"primarykey"`
UserID uint `gorm:"not null"`
Title string `gorm:"size:200;comment:标题"`
Remark string `gorm:"type:text;comment:备注"`
Link string `gorm:"size:1000;comment:链接"`
Styles string `gorm:"type:text;comment:样式数组"`
CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"`
DeletedAt gorm.DeletedAt `gorm:"index"`
ID uint `gorm:"primarykey"`
UserID uint `gorm:"not null"`
Title string `gorm:"size:200;comment:标题"`
Remark string `gorm:"type:text;comment:备注"`
Link string `gorm:"size:1000;comment:链接"`
Styles string `gorm:"type:text;comment:样式数组"`
OrderStatus string `gorm:"size:50;default:pending;comment:订单状态: pending-待处理 ordered-已下单 arrived-已到达 received-已收件"`
CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"`
UpdatedAt *time.Time `gorm:"type:datetime;autoUpdateTime"`
DeletedAt gorm.DeletedAt `gorm:"index"`
}
type TabPurchaseCosts struct {
ID uint `gorm:"primarykey"`
OrderID uint `gorm:"not null"`
UserID uint `gorm:"not null"`
Price int `gorm:"not null"`
Quantity int `gorm:"not null"`
ID uint `gorm:"primarykey"`
OrderID uint `gorm:"not null"`
UserID uint `gorm:"not null"`
Price int `gorm:"not null"`
Quantity int `gorm:"not null"`
CurrencyType int `gorm:"default:1;comment:货币类型: 1-CNY 2-MOP 3-HKD 4-USD"`
CostType int `gorm:"default:1;comment:费用类型: 1-单价 2-运费"`
CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"`
}
@@ -58,6 +62,19 @@ type TabPurchaseFileBind struct {
CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"`
}
// TabPurchaseCommit 记录订单状态变更及评论
type TabPurchaseCommit struct {
ID uint `gorm:"primarykey"`
OrderID uint `gorm:"not null;index;comment:关联订单ID"`
UserID uint `gorm:"not null;comment:操作人ID"`
Action string `gorm:"size:50;not null;comment:操作类型: create-创建 create_status-状态变更"`
Status string `gorm:"size:50;comment:变更后的状态"`
OldStatus string `gorm:"size:50;comment:变更前的状态"`
Comment string `gorm:"type:text;comment:评论/备注"`
IP string `gorm:"size:50;comment:操作IP"`
CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"`
}
type TabPurchaseLog struct {
ID uint `gorm:"primarykey"`
OrderID uint `gorm:"not null;index;comment:关联OrderID"`
@@ -77,11 +94,152 @@ func ApiPurchaseInit() {
models.DB.AutoMigrate(&TabPurchaseCosts{})
models.DB.AutoMigrate(&TabPurchaseFileBind{})
models.DB.AutoMigrate(&TabPurchaseLog{})
models.DB.AutoMigrate(&TabPurchaseCommit{})
}
func ApiPurchase(r *gin.RouterGroup) {
r.POST("/getorder", func(ctx *gin.Context) {
isAuth, _, data := AuthenticationAuthority(ctx)
if !isAuth {
ReturnJson(ctx, "userCookieError", nil)
return
}
type FromGetOrder struct {
ID uint `json:"id"`
}
var from FromGetOrder
if err := mapstructure.Decode(data, &from); err != nil || from.ID == 0 {
ReturnJson(ctx, "jsonErr", nil)
return
}
var order TabPurchaseOrder
if err := models.DB.Where("id = ?", from.ID).First(&order).Error; err != nil {
ReturnJson(ctx, "order_not_found", nil)
return
}
// 查询关联费用
var costs []TabPurchaseCosts
models.DB.Where("order_id = ?", from.ID).Find(&costs)
// 查询关联图片
var binds []TabPurchaseFileBind
models.DB.Where("order_id = ?", from.ID).Find(&binds)
var fileIDs []uint
for _, b := range binds {
fileIDs = append(fileIDs, b.FileID)
}
var files []models.TabFileInfo_
if len(fileIDs) > 0 {
models.DB.Where("id IN ?", fileIDs).Find(&files)
}
// 查询状态变更记录
var commits []TabPurchaseCommit
models.DB.Where("order_id = ?", from.ID).Order("created_at DESC").Find(&commits)
ReturnJson(ctx, "apiOK", gin.H{
"order": order,
"costs": costs,
"photos": files,
"commits": commits,
})
})
// 更新订单状态(可附带评论)
r.POST("/updatestatus", func(ctx *gin.Context) {
isAuth, user, data := AuthenticationAuthority(ctx)
if !isAuth {
ReturnJson(ctx, "userCookieError", nil)
return
}
type FromUpdateStatus struct {
ID uint `json:"id"`
Status string `json:"status" binding:"required"`
Comment string `json:"comment"`
}
var from FromUpdateStatus
if err := mapstructure.Decode(data, &from); err != nil || from.ID == 0 {
ReturnJson(ctx, "jsonErr", nil)
return
}
// 校验状态值
validStatuses := map[string]bool{
"pending": true,
"ordered": true,
"arrived": true,
"received": true,
}
if !validStatuses[from.Status] {
ReturnJson(ctx, "invalid_status", nil)
return
}
var order TabPurchaseOrder
if err := models.DB.Where("id = ?", from.ID).First(&order).Error; err != nil {
ReturnJson(ctx, "order_not_found", nil)
return
}
oldStatus := order.OrderStatus
if oldStatus == from.Status {
ReturnJson(ctx, "status_no_change", nil)
return
}
// 更新状态
updates := map[string]interface{}{
"order_status": from.Status,
}
if err := models.DB.Model(&order).Updates(updates).Error; err != nil {
ReturnJson(ctx, "apiErr", nil)
return
}
// 写状态变更 commit
comment := from.Comment
if comment == "" {
comment = "状态变更为: " + from.Status
}
commit := TabPurchaseCommit{
OrderID: order.ID,
UserID: user.ID,
Action: "create_status",
Status: from.Status,
OldStatus: oldStatus,
Comment: comment,
IP: ctx.ClientIP(),
}
models.DB.Create(&commit)
// 写操作日志
newContent, _ := json.Marshal(map[string]string{
"status": from.Status,
"comment": comment,
})
oldContent, _ := json.Marshal(map[string]string{
"status": oldStatus,
})
tosqllog := TabPurchaseLog{
UserID: user.ID,
OrderID: order.ID,
ActionType: "update_status",
NewContent: string(newContent),
OldContent: string(oldContent),
IP: ctx.ClientIP(),
Remark: comment,
}
models.DB.Create(&tosqllog)
ReturnJson(ctx, "apiOK", nil)
})
r.POST("/getorders", func(ctx *gin.Context) {
isAuth, _, data := AuthenticationAuthority(ctx)
if isAuth {
@@ -185,59 +343,79 @@ func ApiPurchase(r *gin.RouterGroup) {
// fmt.Println("err5")
// }
if is_data_ok {
//校验通过
//载入数据库
if is_data_ok {
//校验通过
//photos, _ := json.Marshal(jsondata.Photos)
new_data := TabPurchaseOrder{
UserID: user.ID,
Title: jsondata.Title,
Remark: jsondata.Remark,
Link: jsondata.Link,
Styles: jsondata.Styles,
OrderStatus: "pending", // 默认待处理
}
models.DB.Create(&new_data)
//fmt.Println("yes")
//photos, _ := json.Marshal(jsondata.Photos) //把图片数组转换成字符串
new_data := TabPurchaseOrder{
UserID: user.ID,
Title: jsondata.Title,
Remark: jsondata.Remark,
Link: jsondata.Link,
Styles: jsondata.Styles,
for i := 0; i < len(jsondata.Costs); i++ {
currencyType := jsondata.Costs[i].CurrencyType
if currencyType <= 0 {
currencyType = 1 // 默认 CNY
}
models.DB.Create(&new_data)
costType := jsondata.Costs[i].Type
if costType <= 0 {
costType = 1 // 默认单价
}
new_cost_data := TabPurchaseCosts{
Price: jsondata.Costs[i].Cost,
Quantity: jsondata.Costs[i].Int,
UserID: user.ID,
OrderID: new_data.ID,
CurrencyType: currencyType,
CostType: costType,
}
models.DB.Create(&new_cost_data)
}
for i := 0; i < len(jsondata.Costs); i++ {
new_cost_data := TabPurchaseCosts{
Price: jsondata.Costs[i].Cost,
Quantity: jsondata.Costs[i].Int,
UserID: user.ID,
OrderID: new_data.ID,
//绑定文件
for i := 0; i < len(jsondata.Photos); i++ {
findFile := models.TabFileInfo_{
Sha256: jsondata.Photos[i],
Type: "image",
}
if models.DB.Where(&findFile).First(&findFile).Error == nil {
bind := TabPurchaseFileBind{
OrderID: new_data.ID,
FileID: findFile.ID,
}
models.DB.Create(&new_cost_data)
models.DB.Create(&bind)
}
}
//绑定文件
for i := 0; i < len(jsondata.Photos); i++ {
findFile := models.TabFileInfo_{
Sha256: jsondata.Photos[i],
Type: "image",
}
if models.DB.Where(&findFile).First(&findFile).Error == nil {
bind := TabPurchaseFileBind{
OrderID: new_data.ID,
FileID: findFile.ID,
}
models.DB.Create(&bind)
}
// 写创建日志
newContent, _ := json.Marshal(jsondata)
tosqllog := TabPurchaseLog{
UserID: user.ID,
OrderID: new_data.ID,
ActionType: "create",
NewContent: string(newContent),
OldContent: "",
IP: ctx.ClientIP(),
}
models.DB.Create(&tosqllog)
}
newContent, _ := json.Marshal(jsondata) // 👈 转 JSON
tosqllog := TabPurchaseLog{
UserID: user.ID,
OrderID: new_data.ID,
ActionType: "create",
NewContent: string(newContent), // 👈 直接赋值
OldContent: "",
IP: ctx.ClientIP(),
}
models.DB.Debug().Create(&tosqllog)
// 写状态创建 commit
commitLog := TabPurchaseCommit{
OrderID: new_data.ID,
UserID: user.ID,
Action: "create",
Status: "pending",
OldStatus: "",
Comment: "订单创建",
IP: ctx.ClientIP(),
}
models.DB.Create(&commitLog)
ReturnJson(ctx, "apiOK", nil)
ReturnJson(ctx, "apiOK", nil)
} else {
ReturnJson(ctx, "jsonErr_1", nil)