package routers import ( "encoding/json" "fmt" "ops/models" "time" "github.com/gin-gonic/gin" "github.com/mitchellh/mapstructure" "gorm.io/gorm" ) type CostItem struct { Cost int `json:"cost"` // 费用 CostT int `json:"costt"` // 总价 CurrencyType string `json:"currencytype"` // 货币类型 Int int `json:"int"` // 数量 Type string `json:"type"` // 费用类型 } type From_purchase_addorder struct { Costs []CostItem `json:"costs"` // 成本 Link string `json:"link"` // 链接 OrderStatus string `json:"order_status"` // 订单状态 //PartName string `json:"partname"` // 物件名称 Photos []string `json:"photos"` // 图片备注 Remark string `json:"remark"` // 备注 Styles string `json:"styles"` // 样式备注 Title string `json:"title"` // 标题 //TrackingNumber string `json:"tracking_number"` // 快递单号 //UpdateTime string `json:"update_time"` // 更新时间 } 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"` } 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"` CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"` } type TabPurchaseFileBind struct { ID uint `gorm:"primarykey"` OrderID uint `gorm:"not null"` FileID uint `gorm:"not null"` CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"` } type TabPurchaseLog struct { ID uint `gorm:"primarykey"` OrderID uint `gorm:"not null;index;comment:关联OrderID"` UserID uint `gorm:"not null;comment:操作人ID"` ActionType string `gorm:"size:50;not null;comment:操作类型: create-创建 update-修改 delete-删除 query-查询"` OldContent string `gorm:"type:text;comment:修改前内容(JSON)"` NewContent string `gorm:"type:text;comment:修改后内容(JSON)"` IP string `gorm:"size:50;comment:操作IP"` Remark string `gorm:"size:500;comment:备注/操作描述"` CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime;comment:操作时间"` } func ApiPurchaseInit() { models.DB.AutoMigrate(&TabPurchaseOrder{}) models.DB.AutoMigrate(&TabPurchaseCosts{}) models.DB.AutoMigrate(&TabPurchaseFileBind{}) models.DB.AutoMigrate(&TabPurchaseLog{}) } func ApiPurchase(r *gin.RouterGroup) { r.POST("/getorders", func(ctx *gin.Context) { isAuth, _, data := AuthenticationAuthority(ctx) if isAuth { //fmt.Println(user) // DebugPrintJson(data) type From_purchase_getorders struct { Search string Entries int Page int } var jsondata From_purchase_getorders if err := mapstructure.Decode(data, &jsondata); err == nil { fmt.Println(jsondata) is_data_ok := true if jsondata.Entries <= 0 || jsondata.Entries > 300 { is_data_ok = false } if jsondata.Page <= 0 { is_data_ok = false } if is_data_ok { //读取有多少条目 var count int64 models.DB.Model(TabPurchaseOrder{}).Count(&count) //fmt.Println(count) //读取条目 var getorders []TabPurchaseOrder models.DB.Order("created_at DESC").Offset(jsondata.Entries * (jsondata.Page - 1)).Limit(jsondata.Entries).Find(&getorders) ReturnJson(ctx, "apiOK", map[string]interface{}{ "all_count": count, "all_orders": getorders, }) } else { ReturnJson(ctx, "jsonErr_1", nil) } } else { ReturnJson(ctx, "jsonErr", nil) } } else { ReturnJson(ctx, "userCookieError", nil) } }) r.POST("/addorder", func(ctx *gin.Context) { isAuth, user, data := AuthenticationAuthority(ctx) if isAuth { //需要处理提交的数据,接口有固定的数据格式,不允许乱搞 //fmt.Println(isAuth) //fmt.Println(user) //DebugPrintJson(data) var jsondata From_purchase_addorder if err := mapstructure.Decode(data, &jsondata); err == nil { //jsonStr, _ := json.MarshalIndent(jsondata, "", " ") //fmt.Println("转换后数据:\n", string(jsonStr)) //数据比较混乱 在这里校验 //判断标题不为空 is_data_ok := true if jsondata.Title == "" { is_data_ok = false } //判断数量与价格是否为负数 for i := 0; i < len(jsondata.Costs); i++ { if jsondata.Costs[i].Cost <= 0 { is_data_ok = false } if jsondata.Costs[i].Int <= 0 { is_data_ok = false } } //判断图片是否为哈希值 for i := 0; i < len(jsondata.Photos); i++ { //判断字符串是否包含标点符号 if models.IsContainsSpecialChar(jsondata.Photos[i]) { is_data_ok = false fmt.Println("err4") } } //判断时间字符串是否合法 // uptime, e := models.StringToTimePtr(jsondata.UpdateTime) // if e != nil { // is_data_ok = false // fmt.Println("err5") // } if is_data_ok { //校验通过 //载入数据库 //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, } models.DB.Create(&new_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, } models.DB.Create(&new_cost_data) } //绑定文件 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) // 👈 转 JSON tosqllog := TabPurchaseLog{ UserID: user.ID, OrderID: new_data.ID, ActionType: "create", NewContent: string(newContent), // 👈 直接赋值 OldContent: "", IP: ctx.ClientIP(), } models.DB.Debug().Create(&tosqllog) ReturnJson(ctx, "apiOK", nil) } else { ReturnJson(ctx, "jsonErr_1", nil) } } else { ReturnJson(ctx, "jsonErr", nil) } } else { ReturnJson(ctx, "userCookieError", nil) } //ReturnJson(ctx, "apiErr", nil) }) }