From 32c7fb6e9ac5decbd0fc5867be2214af07608d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=96=87=E5=B3=B0?= Date: Mon, 13 Apr 2026 18:37:28 +0800 Subject: [PATCH] up --- backend/my_work/main.go | 1 + backend/my_work/models/sql.go | 33 ----- backend/my_work/routers/apiPurchase.go | 122 ++++++++++++------ .../src/views/purchase/addorder.vue | 77 ++++++----- 4 files changed, 132 insertions(+), 101 deletions(-) diff --git a/backend/my_work/main.go b/backend/my_work/main.go index 042e1fb..319b45f 100644 --- a/backend/my_work/main.go +++ b/backend/my_work/main.go @@ -68,6 +68,7 @@ func main() { models.ConfigAllInit() routers.ApiUserInit() //用户表先初始化这是必须的因为后面需要用到用户组 routers.ApiScheduleInit() + routers.ApiPurchaseInit() //创建必要目录 for _, path := range models.ConfigsFile.Pahts { diff --git a/backend/my_work/models/sql.go b/backend/my_work/models/sql.go index cb5209f..6d901de 100644 --- a/backend/my_work/models/sql.go +++ b/backend/my_work/models/sql.go @@ -5,7 +5,6 @@ import ( "time" "github.com/glebarez/sqlite" - "gorm.io/datatypes" "gorm.io/driver/mysql" "gorm.io/driver/postgres" "gorm.io/gorm" @@ -90,34 +89,6 @@ type APIRequestLog_ struct { CreatedAt time.Time `gorm:"column:created_at;type:datetime;default:CURRENT_TIMESTAMP" json:"created_at"` } -type TabPurchaseOrder struct { - 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") @@ -159,9 +130,5 @@ func DatabaseInit() error { DB.AutoMigrate(&APIRequestLog_{}) - DB.AutoMigrate(&TabPurchaseOrder{}) - - DB.AutoMigrate(&TabPurchaseCosts{}) - return nil } diff --git a/backend/my_work/routers/apiPurchase.go b/backend/my_work/routers/apiPurchase.go index d485edf..155c236 100644 --- a/backend/my_work/routers/apiPurchase.go +++ b/backend/my_work/routers/apiPurchase.go @@ -1,13 +1,13 @@ package routers import ( - "encoding/json" "fmt" "ops/models" + "time" "github.com/gin-gonic/gin" "github.com/mitchellh/mapstructure" - "gorm.io/datatypes" + "gorm.io/gorm" ) type CostItem struct { @@ -18,16 +18,51 @@ type CostItem struct { 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"` // 更新时间 + 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"` +} + +func ApiPurchaseInit() { + + models.DB.AutoMigrate(&TabPurchaseOrder{}) + models.DB.AutoMigrate(&TabPurchaseCosts{}) + models.DB.AutoMigrate(&TabPurchaseFileBind{}) + } func ApiPurchase(r *gin.RouterGroup) { @@ -61,11 +96,11 @@ func ApiPurchase(r *gin.RouterGroup) { //读取有多少条目 var count int64 - models.DB.Model(&models.TabPurchaseOrder{}).Count(&count) + models.DB.Model(TabPurchaseOrder{}).Count(&count) //fmt.Println(count) //读取条目 - var getorders []models.TabPurchaseOrder + 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{}{ @@ -97,8 +132,8 @@ func ApiPurchase(r *gin.RouterGroup) { var jsondata From_purchase_addorder if err := mapstructure.Decode(data, &jsondata); err == nil { - jsonStr, _ := json.MarshalIndent(jsondata, "", " ") - fmt.Println("转换后数据:\n", string(jsonStr)) + //jsonStr, _ := json.MarshalIndent(jsondata, "", " ") + //fmt.Println("转换后数据:\n", string(jsonStr)) //数据比较混乱 在这里校验 @@ -106,19 +141,15 @@ func ApiPurchase(r *gin.RouterGroup) { is_data_ok := true if jsondata.Title == "" { is_data_ok = false - - fmt.Println("err1") } //判断数量与价格是否为负数 for i := 0; i < len(jsondata.Costs); i++ { if jsondata.Costs[i].Cost <= 0 { is_data_ok = false - fmt.Println("err2") } if jsondata.Costs[i].Int <= 0 { is_data_ok = false - fmt.Println("err3") } } @@ -133,33 +164,30 @@ func ApiPurchase(r *gin.RouterGroup) { } //判断时间字符串是否合法 - uptime, e := models.StringToTimePtr(jsondata.UpdateTime) - if e != nil { - is_data_ok = false - fmt.Println("err5") - } + // uptime, e := models.StringToTimePtr(jsondata.UpdateTime) + // if e != nil { + // is_data_ok = false + // fmt.Println("err5") + // } 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, + //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 := models.TabPurchaseCosts{ + new_cost_data := TabPurchaseCosts{ Price: jsondata.Costs[i].Cost, Quantity: jsondata.Costs[i].Int, UserID: user.ID, @@ -168,6 +196,24 @@ func ApiPurchase(r *gin.RouterGroup) { 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) + } + + } + + ReturnJson(ctx, "apiOK", nil) + } else { ReturnJson(ctx, "jsonErr_1", nil) } diff --git a/frontend/ops_vue_js/src/views/purchase/addorder.vue b/frontend/ops_vue_js/src/views/purchase/addorder.vue index febd9d9..0643c81 100644 --- a/frontend/ops_vue_js/src/views/purchase/addorder.vue +++ b/frontend/ops_vue_js/src/views/purchase/addorder.vue @@ -115,6 +115,9 @@ const newCost = reactive({ currencyType: "1", // 货币类型:默认人民币 }); +// 费用验证错误状态:点击添加按钮后发现费用为0时触发 +const costError = ref(false); + // ==================== 表单数据 ==================== /** * 订单表单主数据对象 @@ -125,12 +128,12 @@ const form = reactive({ remark: "", // 备注说明 photos: [], // 图片列表(上传后由 dropzone 填充) link: "", // 采购链接 - partname: "", // 配件名称 + //partname: "", // 配件名称 styles: "", // 款式标签 costs: [], // 费用明细(提交前由 costEntries 转换) - tracking_number: "", // 快递单号 - updatetime: "", // 更新时间 - order_status: "1", // 订单状态(默认待下单) + //tracking_number: "", // 快递单号 + //updatetime: "", // 更新时间 + //order_status: "1", // 订单状态(默认待下单) }); /** @@ -146,7 +149,11 @@ const newCostTotal = computed(() => * 条件:单价必须大于0 */ function addCostEntry() { - if (newCost.cost <= 0) return; + if (newCost.cost <= 0) { + costError.value = true; + return; + } + costError.value = false; costEntries.push({ type: newCost.type, int: newCost.int, @@ -178,6 +185,8 @@ watch( (val) => { const fixed = parseFloat(val).toFixed(2); if (parseFloat(fixed) !== val) newCost.cost = parseFloat(fixed); + // 用户开始输入时清除错误状态 + if (val > 0) costError.value = false; }, ); @@ -205,10 +214,11 @@ async function handleSubmit() { // 从 dropzone 组件获取已上传的图片文件名 form.photos = []; - if (photosRef.value?.has_some_files) { - const result = photosRef.value.get_some_files(); - form.photos = result.map((f) => f.name); - } + // if (photosRef.value?.has_some_files) { + // const result = photosRef.value.get_some_files(); + // form.photos = result.map((f) => f.name); + // } + form.photos=photosRef.value?.return_files().map((f)=>f.hash); // 将费用明细转换为提交格式 // 注意:金额需要从"元"转为"分"(乘以100)存储 @@ -219,23 +229,29 @@ async function handleSubmit() { })); // 开始 loading - loading.value = true; - try { - // 调用采购 API 添加订单 - const { errCode } = await purchaseApi.addOrder(form); - if (errCode === 0) { - // 保存成功,显示成功提示 - toast.success(t("message.save_ok")); - } else { - // 服务器错误,显示错误提示 - toast.error(t("message.server_error")); - } - } catch { - // 错误已被 HTTP 拦截器处理,此处无需额外处理 - } finally { - // 无论成功失败,都要关闭 loading - loading.value = false; - } + console.log(form) + purchaseApi.addOrder(form).then((r)=>{ + + console.log(r) + + }) + // loading.value = true; + // try { + // // 调用采购 API 添加订单 + // const { errCode } = await purchaseApi.addOrder(form); + // if (errCode === 0) { + // // 保存成功,显示成功提示 + // toast.success(t("message.save_ok")); + // } else { + // // 服务器错误,显示错误提示 + // toast.error(t("message.server_error")); + // } + // } catch { + // // 错误已被 HTTP 拦截器处理,此处无需额外处理 + // } finally { + // // 无论成功失败,都要关闭 loading + // loading.value = false; + // } } @@ -371,11 +387,11 @@ async function handleSubmit() { {{ item.cost }} {{ item.costt }} - + /> --> {{ currencyOptions[item.currencytype] }} @@ -430,7 +446,8 @@ async function handleSubmit() { @@ -479,7 +496,7 @@ async function handleSubmit() {