diff --git a/backend/models/def.go b/backend/models/def.go index e270ff0..9cec2fb 100644 --- a/backend/models/def.go +++ b/backend/models/def.go @@ -5,6 +5,7 @@ import ( "crypto/rand" "encoding/hex" "regexp" + "strings" "time" ) @@ -23,6 +24,15 @@ func GetCurrentTimeString(format ...string) string { return time.Now().Format(layout) } +func StringToTimePtr(str string) (*time.Time, error) { + layout := "2006-01-02 15:04" + t, err := time.Parse(layout, str) + if err != nil { + return nil, err + } + return &t, nil +} + func RandStr32() string { // 生成 32 字节 (256 位) 随机数据 b := make([]byte, 32) @@ -90,3 +100,9 @@ func IsEmailValid(email string) bool { regex := regexp.MustCompile(pattern) return regex.MatchString(email) } + +// 判断字符串是否包含标点符号 +func IsContainsSpecialChar(str string) bool { + specialChars := "!@#$%^&*()-+={}[]|\\:;\"'<>,.?/" + return strings.ContainsAny(str, specialChars) +} diff --git a/backend/models/sql.go b/backend/models/sql.go index d72d0a9..cb5209f 100644 --- a/backend/models/sql.go +++ b/backend/models/sql.go @@ -71,7 +71,7 @@ type TabUserInfo_ struct { type TabCookie_ struct { ID uint `gorm:"primaryKey;autoIncrement"` - UserID uint `gorm:"size:16;not null"` + UserID uint `gorm:"not null"` Name string `gorm:"size:255;not null;index"` Value string `gorm:"size:255;not null;index"` ExpiresAt time.Time `gorm:"type:datetime;index"` @@ -91,23 +91,33 @@ type APIRequestLog_ struct { } type TabPurchaseOrder struct { - ID uint `gorm:"primarykey" json:"id"` - Title string `gorm:"size:200;comment:标题" json:"title"` - Remark string `gorm:"type:text;comment:备注" json:"remark"` - Photos datatypes.JSON `gorm:"type:json;comment:照片哈希数组" json:"photos"` - Link string `gorm:"size:1000;comment:链接" json:"link"` - PartName string `gorm:"size:200;not null;comment:物品名称" json:"part_name"` - Styles datatypes.JSON `gorm:"type:json;comment:样式数组" json:"styles"` - Costs datatypes.JSON `gorm:"type:json;comment:费用明细数组" json:"costs"` - UpdateTime *time.Time `gorm:"type:datetime;autoUpdateTime;comment:更新时间" json:"update_time"` - TrackingNumber string `gorm:"size:100;uniqueIndex;comment:快递单号" json:"tracking_number"` - OrderStatus int8 `gorm:"default:1;comment:订单状态" json:"order_status"` + ID uint `gorm:"primarykey"` + UserID uint `gorm:"not null"` + Title string `gorm:"size:200;comment:标题"` + Remark string `gorm:"type:text;comment:备注"` + Photos datatypes.JSON `gorm:"type:json;comment:照片哈希数组"` + Link string `gorm:"size:1000;comment:链接"` + PartName string `gorm:"size:200;not null;comment:物品名称"` + Styles string `gorm:"type:text;comment:样式数组"` + //Costs datatypes.JSON `gorm:"type:json;comment:费用明细数组"` + UpdateTime *time.Time `gorm:"type:datetime;autoUpdateTime;comment:更新时间"` + TrackingNumber string `gorm:"size:100;Index;comment:快递单号"` + OrderStatus string `gorm:"default:1;comment:订单状态"` 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"` + CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"` +} + func DatabaseInit() error { var err error fmt.Println("database_init") @@ -149,5 +159,9 @@ func DatabaseInit() error { DB.AutoMigrate(&APIRequestLog_{}) + DB.AutoMigrate(&TabPurchaseOrder{}) + + DB.AutoMigrate(&TabPurchaseCosts{}) + return nil } diff --git a/backend/routers/apiPurchase.go b/backend/routers/apiPurchase.go index 2e94606..5eb02c1 100644 --- a/backend/routers/apiPurchase.go +++ b/backend/routers/apiPurchase.go @@ -1,30 +1,32 @@ package routers import ( - "fmt" + "encoding/json" + "ops/models" "github.com/gin-gonic/gin" "github.com/mitchellh/mapstructure" + "gorm.io/datatypes" ) type CostItem struct { - Cost float64 `json:"cost" binding:"required,min=0"` // 必须,非负 - CostT float64 `json:"cost_t" binding:"required,min=0"` // 必须,非负 - CurrencyType string `json:"currency_type" binding:"required"` // 必须 - Int int `json:"int" binding:"required"` // 必须 - Type string `json:"type" binding:"required"` // 必须 + 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" binding:"required"` // - PartName string `json:"part_name"` // 可选 - Photos []string `json:"photos"` // 可选 - Remark string `json:"remark"` // 可选 - Styles string `json:"styles"` // 可选 - Title string `json:"title" binding:"required"` // 必须 - TrackingNumber string `json:"tracking_number"` // 可选 - UpdateTime string `json:"update_time"` // 可选 + 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"` // 可选 } func ApiPurchase(r *gin.RouterGroup) { @@ -35,12 +37,78 @@ func ApiPurchase(r *gin.RouterGroup) { //需要处理提交的数据,接口有固定的数据格式,不允许乱搞 //fmt.Println(isAuth) - fmt.Println(user) + //fmt.Println(user) //DebugPrintJson(data) var jsondata From_purchase_addorder if err := mapstructure.Decode(data, &jsondata); err == nil { - fmt.Println("转换后数据:\n", jsondata) + //fmt.Println("转换后数据:\n", jsondata) + + //数据比较混乱 在这里校验 + + //判断标题不为空 + 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 + } + + } + + //判断时间字符串是否合法 + uptime, e := models.StringToTimePtr(jsondata.UpdateTime) + if e != nil { + is_data_ok = false + } + + if is_data_ok { + //校验通过 + //载入数据库 + + photos, _ := json.Marshal(jsondata.Photos) //把图片数组转换成字符串 + new_data := models.TabPurchaseOrder{ + UserID: user.ID, + Title: jsondata.Title, + Remark: jsondata.Remark, + Photos: datatypes.JSON(photos), + Link: jsondata.Link, + PartName: jsondata.PartName, + Styles: jsondata.Styles, + UpdateTime: uptime, + TrackingNumber: jsondata.TrackingNumber, + OrderStatus: jsondata.OrderStatus, + } + models.DB.Create(&new_data) + + for i := 0; i < len(jsondata.Costs); i++ { + new_cost_data := models.TabPurchaseCosts{ + Price: jsondata.Costs[i].Cost, + Quantity: jsondata.Costs[i].Int, + UserID: user.ID, + OrderID: new_data.ID, + } + models.DB.Create(&new_cost_data) + } + + } else { + ReturnJson(ctx, "jsonErr", nil) + } } else { ReturnJson(ctx, "jsonErr", nil) diff --git a/frontent/ops_vue_js/src/i18n/en.json b/frontent/ops_vue_js/src/i18n/en.json index bb0008d..0bd997e 100644 --- a/frontent/ops_vue_js/src/i18n/en.json +++ b/frontent/ops_vue_js/src/i18n/en.json @@ -80,6 +80,7 @@ "currency": "Currency", "operation": "Operation", "remove": "Remove", + "change": "Change", "fee_type": "Fee type", "input_quantity": "Quantity", "input_fee": "Fee", diff --git a/frontent/ops_vue_js/src/i18n/zh-CN.json b/frontent/ops_vue_js/src/i18n/zh-CN.json index 38ff795..7d8a6e0 100644 --- a/frontent/ops_vue_js/src/i18n/zh-CN.json +++ b/frontent/ops_vue_js/src/i18n/zh-CN.json @@ -80,6 +80,7 @@ "currency": "货币", "operation": "操作", "remove": "移除", + "change": "修改", "fee_type": "费用类型", "input_quantity": "数量", "input_fee": "费用", diff --git a/frontent/ops_vue_js/src/views/purchase/addorder.vue b/frontent/ops_vue_js/src/views/purchase/addorder.vue index 3344dc7..1c67e7c 100644 --- a/frontent/ops_vue_js/src/views/purchase/addorder.vue +++ b/frontent/ops_vue_js/src/views/purchase/addorder.vue @@ -79,19 +79,29 @@ const cost_sheet = reactive({ }); function del_cost(key) { + cost_sheet.type = cost_sheet_tab[key].type; + cost_sheet.int = cost_sheet_tab[key].int; + cost_sheet.cost = cost_sheet_tab[key].cost; + cost_sheet.cost_t = cost_sheet_tab[key].cost_t; + cost_sheet.currency_type = cost_sheet_tab[key].currency_type; + cost_sheet_tab.splice(key, 1); } function add_cost() { - // 四舍五入到2位小数 - // const fixed = parseFloat(newVal).toFixed(2); - // if (parseFloat(fixed) !== newVal) { - // cost_sheet.cost = parseFloat(fixed); - // } + if (cost_sheet.cost <= 0) { + } else { + // 四舍五入到2位小数 + var t = parseFloat((cost_sheet.int * cost_sheet.cost).toFixed(2)); + cost_sheet.cost_t = t; - var t = parseFloat((cost_sheet.int * cost_sheet.cost).toFixed(2)); - cost_sheet.cost_t = t; + cost_sheet_tab.push(JSON.parse(JSON.stringify(cost_sheet))); - cost_sheet_tab.push(JSON.parse(JSON.stringify(cost_sheet))); + cost_sheet.type = "1"; + cost_sheet.int = 1; + cost_sheet.cost = 0.0; + cost_sheet.cost_t = 0.0; + cost_sheet.currency_type = "1"; + } } const submit_sheet = reactive({ @@ -99,12 +109,12 @@ const submit_sheet = reactive({ remark: "", photos: [], link: "", - part_name: "", + partname: "", styles: "", costs: [], - update_time: "", - tracking_number: "", - order_status: "1", + updatetime: "", + trackingnumber: "", + orderstatus: "1", }); function submit_order() { @@ -130,7 +140,14 @@ function submit_order() { //载入价格表 submit_sheet.costs = []; for (var i = 0; i < cost_sheet_tab.length; i++) { - submit_sheet.costs.push(cost_sheet_tab[i]); + //var t=cost_sheet_tab[i] + submit_sheet.costs.push(JSON.parse(JSON.stringify(cost_sheet_tab[i]))); + } + + //修改价格表里的小数,将所有价值*100去掉小数 + for (var i = 0; i < submit_sheet.costs.length; i++) { + submit_sheet.costs[i].cost *= 100; + submit_sheet.costs[i].cost_t *= 100; } console.log(submit_sheet); @@ -262,7 +279,7 @@ watch( class="form-control" name="example-text-input" :placeholder="t('purchase_addorder.part_name')" - v-model="submit_sheet.part_name" + v-model="submit_sheet.partname" />
@@ -313,7 +330,7 @@ watch( class="btn btn-outline-danger" @click="del_cost(key)" > - {{ t("purchase_addorder.remove") }} + {{ t("purchase_addorder.change") }} @@ -409,7 +426,7 @@ watch( t("purchase_addorder.update_time") }}
@@ -422,7 +439,7 @@ watch( :placeholder=" t('purchase_addorder.input_tracking_number') " - v-model="submit_sheet.tracking_number" + v-model="submit_sheet.trackingnumber" />
@@ -431,7 +448,7 @@ watch( ref="select_beast" class="form-control" autocompvare="off" - v-model="submit_sheet.order_status" + v-model="submit_sheet.orderstatus" >