修改订购数量
This commit is contained in:
parent
ec19b6bba5
commit
0e7879a9c1
@ -77,3 +77,22 @@ func (r *SalesApi) GetSalesOrderDetailList(c *gin.Context) {
|
|||||||
"data": result,
|
"data": result,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ModifySalesOrderQuantity 修改销售订单明细订购数量
|
||||||
|
func (r *SalesApi) ModifySalesOrderQuantity(c *gin.Context) {
|
||||||
|
var req systemReq.ModifySalesOrderQuantityRequest
|
||||||
|
|
||||||
|
if err := c.ShouldBind(&req); err != nil {
|
||||||
|
ValidAndFail(constant.LoggerChannelRequest, "修改订购数量请求参数异常", "参数错误: "+err.Error(), c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userInfo := utils.GetUserInfo(c)
|
||||||
|
err := salesService.ModifySalesOrderQuantity(req, userInfo.ID, userInfo.Role, database.GetDB(c))
|
||||||
|
if err != nil {
|
||||||
|
utils.FailWithRequestLog(constant.LoggerChannelWork, "修改订购数量异常", err, c, req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
systemRes.OkWithMessage("修改订购数量成功", c)
|
||||||
|
}
|
||||||
|
|||||||
@ -337,6 +337,11 @@ func migrateTenantTables(db *gorm.DB) {
|
|||||||
log.Printf("UserDailyStat表迁移警告: %v", err)
|
log.Printf("UserDailyStat表迁移警告: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = db.Set("gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品销毁日志表'").AutoMigrate(&models.ProductDestroyLog{})
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("ProductDestroyLog表迁移警告: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
log.Println("租户业务表迁移完成")
|
log.Println("租户业务表迁移完成")
|
||||||
|
|
||||||
// 重置旺店通运行中的任务(服务重启后清理)
|
// 重置旺店通运行中的任务(服务重启后清理)
|
||||||
@ -458,6 +463,15 @@ func migrateIncrementalTenantTables(db *gorm.DB) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !db.Migrator().HasTable(&models.ProductDestroyLog{}) {
|
||||||
|
err := db.Set("gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品销毁日志表'").AutoMigrate(&models.ProductDestroyLog{})
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("ProductDestroyLog表增量迁移警告: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Println("ProductDestroyLog表增量迁移成功")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 重置旺店通运行中的任务(服务重启后清理)
|
// 重置旺店通运行中的任务(服务重启后清理)
|
||||||
resetWangdianRunningTasks(db)
|
resetWangdianRunningTasks(db)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,3 +36,11 @@ type GetSalesOrderDetailListRequest struct {
|
|||||||
LogisticsNo string `form:"logistics_no"`
|
LogisticsNo string `form:"logistics_no"`
|
||||||
ShopType int `form:"shop_type" json:"shop_type"`
|
ShopType int `form:"shop_type" json:"shop_type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ModifySalesOrderQuantityRequest 修改销售订单明细订购数量请求
|
||||||
|
type ModifySalesOrderQuantityRequest struct {
|
||||||
|
SalesOrderID int64 `form:"sales_order_id" json:"sales_order_id" binding:"required"`
|
||||||
|
SalesOrderItemID int64 `form:"sales_order_item_id" json:"sales_order_item_id" binding:"required"`
|
||||||
|
AdditionalQty int64 `form:"additional_quantity" json:"additional_quantity" binding:"required,min=1"`
|
||||||
|
Remark string `form:"remark" json:"remark"`
|
||||||
|
}
|
||||||
|
|||||||
@ -234,9 +234,10 @@ func initRouter() (r *gin.Engine) {
|
|||||||
auth.GET("/receiving-order/list", receivingApi.GetReceivingOrderList) // 获取入库订单列表
|
auth.GET("/receiving-order/list", receivingApi.GetReceivingOrderList) // 获取入库订单列表
|
||||||
auth.GET("/receiving-order/detail", receivingApi.GetReceivingOrderDetail) // 获取入库订单详情
|
auth.GET("/receiving-order/detail", receivingApi.GetReceivingOrderDetail) // 获取入库订单详情
|
||||||
// 销售订单管理
|
// 销售订单管理
|
||||||
auth.GET("/sales-order/list", salesApi.GetSalesOrderList) // 获取销售订单列表
|
auth.GET("/sales-order/list", salesApi.GetSalesOrderList) // 获取销售订单列表
|
||||||
auth.GET("/sales-order/detail", salesApi.GetSalesOrderDetail) // 获取销售订单详情
|
auth.GET("/sales-order/detail", salesApi.GetSalesOrderDetail) // 获取销售订单详情
|
||||||
auth.GET("/sales-order/detaillist", salesApi.GetSalesOrderDetailList) // 获取销售订单详情列表
|
auth.GET("/sales-order/detaillist", salesApi.GetSalesOrderDetailList) // 获取销售订单详情列表
|
||||||
|
auth.POST("/sales-order/modify-quantity", salesApi.ModifySalesOrderQuantity) // 修改销售订单明细订购数量
|
||||||
// 出库单管理
|
// 出库单管理
|
||||||
auth.GET("/outbound-order/list", outboundApi.GetOutboundOrderList) // 获取出库订单列表
|
auth.GET("/outbound-order/list", outboundApi.GetOutboundOrderList) // 获取出库订单列表
|
||||||
auth.GET("/outbound-order/detail", outboundApi.GetOutboundOrderDetail) // 获取出库订单详情
|
auth.GET("/outbound-order/detail", outboundApi.GetOutboundOrderDetail) // 获取出库订单详情
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"gorm.io/datatypes"
|
"gorm.io/datatypes"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"psi/database"
|
"psi/database"
|
||||||
"psi/models"
|
"psi/models"
|
||||||
@ -23,6 +24,7 @@ type BookService struct{}
|
|||||||
func (s *BookService) GetBookInfo(req systemReq.BookRequest) (*systemRes.ESBook, error) {
|
func (s *BookService) GetBookInfo(req systemReq.BookRequest) (*systemRes.ESBook, error) {
|
||||||
// 调用ES接口
|
// 调用ES接口
|
||||||
isbn := req.Isbn
|
isbn := req.Isbn
|
||||||
|
log.Printf("[GetBookInfo] 请求 ISBN: %s", isbn)
|
||||||
apiURL := fmt.Sprintf("https://book.center.yushutx.com/api/es/searchByISBNtoPsi?isbn=%s", isbn)
|
apiURL := fmt.Sprintf("https://book.center.yushutx.com/api/es/searchByISBNtoPsi?isbn=%s", isbn)
|
||||||
resp, err := http.Get(apiURL)
|
resp, err := http.Get(apiURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -36,15 +38,19 @@ func (s *BookService) GetBookInfo(req systemReq.BookRequest) (*systemRes.ESBook,
|
|||||||
return nil, fmt.Errorf("[ERROR] 读取响应失败:%v\n", err)
|
return nil, fmt.Errorf("[ERROR] 读取响应失败:%v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("[GetBookInfo] ES 返回原始数据: %s", string(body))
|
||||||
|
|
||||||
var esResp systemRes.GetEsBookResponse
|
var esResp systemRes.GetEsBookResponse
|
||||||
if err := json.Unmarshal(body, &esResp); err != nil {
|
if err := json.Unmarshal(body, &esResp); err != nil {
|
||||||
return nil, fmt.Errorf("[ERROR] 解析响应失败:%v\n", err)
|
return nil, fmt.Errorf("[ERROR] 解析响应失败:%v\n", err)
|
||||||
}
|
}
|
||||||
// 如果ES接口没有返回数据,返回空对象
|
// 如果ES接口没有返回数据,返回空对象
|
||||||
if esResp.Data.BookName.Value == "" && esResp.Data.ISBN == "" {
|
if esResp.Data.BookName.Value == "" && esResp.Data.ISBN == "" {
|
||||||
|
log.Printf("[GetBookInfo] ES 无数据,返回 nil")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("[GetBookInfo] 解析成功, 书名: %s, ISBN: %s", esResp.Data.BookName.Value, esResp.Data.ISBN)
|
||||||
return &esResp.Data, nil
|
return &esResp.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,24 +43,29 @@ func (s *CarService) GetCarList(req systemReq.QueryCarRequest, db ...*gorm.DB) (
|
|||||||
return nil, 0, errors.New("查询小车列表失败")
|
return nil, 0, errors.New("查询小车列表失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 批量查询所有车的关联店铺,避免 N+1
|
||||||
|
carIDs := make([]int64, len(cars))
|
||||||
|
for i, car := range cars {
|
||||||
|
carIDs[i] = car.ID
|
||||||
|
}
|
||||||
|
var allShops []models.CarShop
|
||||||
|
if len(carIDs) > 0 {
|
||||||
|
databaseConn.Where("car_id IN ? AND is_del = ?", carIDs, 0).Find(&allShops)
|
||||||
|
}
|
||||||
|
shopMap := make(map[int64][]systemRes.CarShopInfo)
|
||||||
|
for _, cs := range allShops {
|
||||||
|
shopMap[cs.CarID] = append(shopMap[cs.CarID], systemRes.CarShopInfo{
|
||||||
|
ShopID: strconv.FormatInt(cs.ShopID, 10),
|
||||||
|
ShopName: cs.ShopName,
|
||||||
|
ShopType: cs.ShopType,
|
||||||
|
ShopTypeText: getShopTypeText(cs.ShopType),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
responses := make([]systemRes.CarResponse, 0, len(cars))
|
responses := make([]systemRes.CarResponse, 0, len(cars))
|
||||||
for _, car := range cars {
|
for _, car := range cars {
|
||||||
resp := systemRes.ConvertCarToResponse(car)
|
resp := systemRes.ConvertCarToResponse(car)
|
||||||
|
resp.Shops = shopMap[car.ID]
|
||||||
var carShops []models.CarShop
|
|
||||||
if err := databaseConn.Where("car_id = ? AND is_del = ?", car.ID, 0).Find(&carShops).Error; err == nil {
|
|
||||||
shops := make([]systemRes.CarShopInfo, 0, len(carShops))
|
|
||||||
for _, cs := range carShops {
|
|
||||||
shops = append(shops, systemRes.CarShopInfo{
|
|
||||||
ShopID: strconv.FormatInt(cs.ShopID, 10),
|
|
||||||
ShopName: cs.ShopName,
|
|
||||||
ShopType: cs.ShopType,
|
|
||||||
ShopTypeText: getShopTypeText(cs.ShopType),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
resp.Shops = shops
|
|
||||||
}
|
|
||||||
|
|
||||||
responses = append(responses, resp)
|
responses = append(responses, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3265,10 +3265,19 @@ func (s *ProductService) AuditProductLog(req systemReq.AuditProductLogRequest, u
|
|||||||
|
|
||||||
// 审核通过时,同步更新 ES 中的商品字段
|
// 审核通过时,同步更新 ES 中的商品字段
|
||||||
if req.Status == 1 {
|
if req.Status == 1 {
|
||||||
|
fmt.Printf("[DEBUG] 审核通过, NewLiveImage=%v, NewPageCount=%d, NewWordCount=%d\n", req.NewLiveImage, req.NewPageCount, req.NewWordCount)
|
||||||
if err := s.syncApprovedLogToES(log.Barcode, req); err != nil {
|
if err := s.syncApprovedLogToES(log.Barcode, req); err != nil {
|
||||||
// ES 同步失败只记日志,不阻断审核流程
|
// ES 同步失败只记日志,不阻断审核流程
|
||||||
fmt.Printf("[WARN] 审核后同步 ES 失败 (product_log_id=%d, barcode=%s): %v\r\n", req.ID, log.Barcode, err)
|
fmt.Printf("[WARN] 审核后同步 ES 失败 (product_log_id=%d, barcode=%s): %v\r\n", req.ID, log.Barcode, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 同步更新 product 表的 live_image,解决其他平台从 product 表读不到新图片的问题
|
||||||
|
if len(req.NewLiveImage) > 0 {
|
||||||
|
liveImageJSON, _ := json.Marshal(req.NewLiveImage)
|
||||||
|
if err := database.DB.Model(&models.Product{}).Where("barcode = ?", log.Barcode).Update("live_image", datatypes.JSON(liveImageJSON)).Error; err != nil {
|
||||||
|
fmt.Printf("[WARN] 审核后更新 product 表 live_image 失败 (product_log_id=%d, barcode=%s): %v\r\n", req.ID, log.Barcode, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -3302,6 +3311,21 @@ func (s *ProductService) syncApprovedLogToES(barcode string, req systemReq.Audit
|
|||||||
data["publication_time"] = req.NewPublicationTime
|
data["publication_time"] = req.NewPublicationTime
|
||||||
}
|
}
|
||||||
data["is_suit"] = req.NewIsSuit
|
data["is_suit"] = req.NewIsSuit
|
||||||
|
if len(req.NewLiveImage) > 0 {
|
||||||
|
data["book_pic"] = map[string]string{
|
||||||
|
"localPath": "",
|
||||||
|
"pddPath": req.NewLiveImage[0],
|
||||||
|
}
|
||||||
|
data["book_pic_b"] = req.NewLiveImage[0]
|
||||||
|
}
|
||||||
|
if req.NewPageCount > 0 {
|
||||||
|
data["page_count"] = strconv.FormatInt(req.NewPageCount, 10)
|
||||||
|
data["pages"] = strconv.FormatInt(req.NewPageCount, 10)
|
||||||
|
}
|
||||||
|
if req.NewWordCount > 0 {
|
||||||
|
data["word_count"] = strconv.FormatInt(req.NewWordCount, 10)
|
||||||
|
data["words"] = strconv.FormatInt(req.NewWordCount, 10)
|
||||||
|
}
|
||||||
|
|
||||||
payload := map[string]interface{}{
|
payload := map[string]interface{}{
|
||||||
"isbn": barcode,
|
"isbn": barcode,
|
||||||
@ -3313,6 +3337,9 @@ func (s *ProductService) syncApprovedLogToES(barcode string, req systemReq.Audit
|
|||||||
return fmt.Errorf("序列化请求参数失败:%w", err)
|
return fmt.Errorf("序列化请求参数失败:%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Printf("[DEBUG] ES更新请求 URL: %s\n", esURL)
|
||||||
|
fmt.Printf("[DEBUG] ES更新请求 payload: %s\n", string(jsonBytes))
|
||||||
|
|
||||||
resp, err := http.Post(esURL, "application/json", bytes.NewReader(jsonBytes))
|
resp, err := http.Post(esURL, "application/json", bytes.NewReader(jsonBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("调用 ES 更新接口失败:%w", err)
|
return fmt.Errorf("调用 ES 更新接口失败:%w", err)
|
||||||
@ -3320,6 +3347,8 @@ func (s *ProductService) syncApprovedLogToES(barcode string, req systemReq.Audit
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, _ := io.ReadAll(resp.Body)
|
body, _ := io.ReadAll(resp.Body)
|
||||||
|
fmt.Printf("[DEBUG] ES更新响应 status=%d body: %s\n", resp.StatusCode, string(body))
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return fmt.Errorf("ES 更新接口返回非200状态码[%d]: %s", resp.StatusCode, string(body))
|
return fmt.Errorf("ES 更新接口返回非200状态码[%d]: %s", resp.StatusCode, string(body))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -394,3 +394,46 @@ func (s *SalesService) GetSalesOrderDetail(id int64, creatorID int64, role int64
|
|||||||
detail := systemRes.ConvertSalesOrderToDetail(order.SalesOrder, order.CustomerName, order.WarehouseName, detailItems)
|
detail := systemRes.ConvertSalesOrderToDetail(order.SalesOrder, order.CustomerName, order.WarehouseName, detailItems)
|
||||||
return &detail, nil
|
return &detail, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ModifySalesOrderQuantity 修改销售订单明细订购数量
|
||||||
|
func (s *SalesService) ModifySalesOrderQuantity(req systemReq.ModifySalesOrderQuantityRequest, creatorID int64, role int64, db ...*gorm.DB) error {
|
||||||
|
databaseConn := database.OptionalDB(db...)
|
||||||
|
|
||||||
|
var salesOrder models.SalesOrder
|
||||||
|
if err := databaseConn.Where("id = ? AND is_del = ?", req.SalesOrderID, 0).First(&salesOrder).Error; err != nil {
|
||||||
|
return utils.NewError("销售订单不存在")
|
||||||
|
}
|
||||||
|
|
||||||
|
if role == 128 && salesOrder.SalesPersonID != creatorID {
|
||||||
|
return utils.NewError("无权操作该销售订单")
|
||||||
|
}
|
||||||
|
|
||||||
|
if salesOrder.Status == 6 {
|
||||||
|
return utils.NewError("已取消的订单无法修改订购数量")
|
||||||
|
}
|
||||||
|
|
||||||
|
var item models.SalesOrderItem
|
||||||
|
if err := databaseConn.Where("id = ? AND sales_order_id = ? AND is_del = ?", req.SalesOrderItemID, req.SalesOrderID, 0).First(&item).Error; err != nil {
|
||||||
|
return utils.NewError("订单明细不存在")
|
||||||
|
}
|
||||||
|
|
||||||
|
newQuantity := req.AdditionalQty
|
||||||
|
newAmount := item.UnitPrice * newQuantity
|
||||||
|
amountDiff := newAmount - item.Amount
|
||||||
|
|
||||||
|
return databaseConn.Transaction(func(tx *gorm.DB) error {
|
||||||
|
if err := tx.Model(&item).Updates(map[string]interface{}{
|
||||||
|
"quantity": newQuantity,
|
||||||
|
"amount": newAmount,
|
||||||
|
}).Error; err != nil {
|
||||||
|
return utils.NewError("更新订单明细失败")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.Model(&models.SalesOrder{}).Where("id = ?", req.SalesOrderID).
|
||||||
|
Update("total_amount", salesOrder.TotalAmount+amountDiff).Error; err != nil {
|
||||||
|
return utils.NewError("更新订单总金额失败")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user