daShangDao_psiServer/service/logistics.go
2026-06-15 13:47:39 +08:00

256 lines
6.9 KiB
Go

package service
import (
"encoding/json"
"errors"
"gorm.io/gorm"
"log"
"math"
"psi/database"
"psi/models"
"psi/models/request"
"psi/models/response"
"strconv"
"time"
)
type LogisticsService struct{}
func (s *LogisticsService) GetLogisticsList(req request.QueryLogisticsRequest, db ...*gorm.DB) ([]response.LogisticsResponse, int64, error) {
databaseConn := database.OptionalDB(db...)
if req.Page < 1 {
req.Page = 1
}
if req.PageSize < 1 || req.PageSize > 100 {
req.PageSize = 20
}
query := databaseConn.Model(&models.Logistics{}).Where("del_flag = ?", "0")
if req.Keyword != "" {
query = query.Where("template_name LIKE ? OR delivery_province LIKE ? OR delivery_city LIKE ?",
"%"+req.Keyword+"%", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
}
if req.Status != nil {
query = query.Where("status = ?", *req.Status)
}
// === debug: 打印完整SQL ===
log.Printf("[GetLogisticsList] 请求参数 page=%d pageSize=%d keyword=%q", req.Page, req.PageSize, req.Keyword)
// === debug end ===
var total int64
if err := query.Debug().Count(&total).Error; err != nil {
return nil, 0, errors.New("查询物流模板总数失败")
}
var logistics []models.Logistics
offset := (req.Page - 1) * req.PageSize
if err := query.Debug().Order("id DESC").Offset(offset).Limit(req.PageSize).Find(&logistics).Error; err != nil {
return nil, 0, errors.New("查询物流模板列表失败")
}
responses := make([]response.LogisticsResponse, 0, len(logistics))
for _, item := range logistics {
resp := response.ConvertLogisticsToResponse(item)
responses = append(responses, resp)
}
return responses, total, nil
}
func (s *LogisticsService) GetLogisticsByID(id uint64, db ...*gorm.DB) (*response.LogisticsResponse, error) {
databaseConn := database.OptionalDB(db...)
var logistics models.Logistics
if err := databaseConn.Where("id = ? AND del_flag = ?", id, "0").First(&logistics).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("物流模板不存在")
}
return nil, errors.New("查询物流模板失败")
}
resp := response.ConvertLogisticsToResponse(logistics)
return &resp, nil
}
// calculateMinFirstFee 从 shipping_range JSON 中计算最小首费
func (s *LogisticsService) calculateMinFirstFee(shippingRange string) (float64, error) {
if shippingRange == "" {
return 0, errors.New("运送范围不能为空")
}
var rangeMap map[string][]interface{}
if err := json.Unmarshal([]byte(shippingRange), &rangeMap); err != nil {
return 0, errors.New("运送范围格式错误")
}
minFee := math.MaxFloat64
found := false
for _, values := range rangeMap {
if len(values) < 2 {
continue
}
// values[1] 是首费,可能是 string 或 float64
var fee float64
switch v := values[1].(type) {
case float64:
fee = v
case string:
var err error
fee, err = strconv.ParseFloat(v, 64)
if err != nil {
continue
}
default:
continue
}
if fee < minFee {
minFee = fee
}
found = true
}
if !found {
return 0, errors.New("运送范围数据格式错误")
}
return minFee, nil
}
func (s *LogisticsService) CreateLogistics(req request.CreateLogisticsRequest, db ...*gorm.DB) (uint64, error) {
databaseConn := database.OptionalDB(db...)
var count int64
databaseConn.Model(&models.Logistics{}).
Where("template_name = ? AND del_flag = ?", req.TemplateName, "0").
Count(&count)
if count > 0 {
return 0, errors.New("物流模板名称已存在")
}
// 计算最小首费
minFirPrice, err := s.calculateMinFirstFee(req.ShippingRange)
if err != nil {
return 0, err
}
now := time.Now()
logistics := models.Logistics{
TemplateName: req.TemplateName,
DeliveryProvince: req.DeliveryProvince,
DeliveryCity: req.DeliveryCity,
DeliveryArea: req.DeliveryArea,
DeliveryAddress: req.DeliveryAddress,
PricingMethod: req.PricingMethod,
Shipping: req.Shipping,
FirWbv: req.FirWbv,
FirPrice: minFirPrice,
ContinueWbv: req.ContinueWbv,
ContinuePrice: req.ContinuePrice,
Contact: req.Contact,
PhoneNumber: req.PhoneNumber,
FullAddress: req.FullAddress,
ShippingRange: req.ShippingRange,
WarehouseId: req.WarehouseId,
Remark: req.Remark,
Status: req.Status,
DelFlag: "0",
CreateTime: &now,
UpdateTime: &now,
}
if logistics.Status == "" {
logistics.Status = "0"
}
if err := databaseConn.Create(&logistics).Error; err != nil {
return 0, errors.New("创建物流模板失败")
}
return logistics.Id, nil
}
func (s *LogisticsService) UpdateLogistics(req request.UpdateLogisticsRequest, db ...*gorm.DB) error {
databaseConn := database.OptionalDB(db...)
var logistics models.Logistics
if err := databaseConn.Where("id = ? AND del_flag = ?", req.Id, "0").First(&logistics).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return errors.New("物流模板不存在")
}
return errors.New("查询物流模板失败")
}
var count int64
databaseConn.Model(&models.Logistics{}).
Where("template_name = ? AND id != ? AND del_flag = ?", req.TemplateName, req.Id, "0").
Count(&count)
if count > 0 {
return errors.New("物流模板名称已存在")
}
// 计算最小首费
minFirPrice, err := s.calculateMinFirstFee(req.ShippingRange)
if err != nil {
return err
}
now := time.Now()
updates := map[string]interface{}{
"template_name": req.TemplateName,
"delivery_province": req.DeliveryProvince,
"delivery_city": req.DeliveryCity,
"delivery_area": req.DeliveryArea,
"delivery_address": req.DeliveryAddress,
"pricing_method": req.PricingMethod,
"shipping": req.Shipping,
"fir_wbv": req.FirWbv,
"fir_price": minFirPrice,
"continue_wbv": req.ContinueWbv,
"continue_price": req.ContinuePrice,
"contact": req.Contact,
"phone_number": req.PhoneNumber,
"full_address": req.FullAddress,
"shipping_range": req.ShippingRange,
"warehouse_id": req.WarehouseId,
"remark": req.Remark,
"status": req.Status,
"update_time": &now,
}
if err := databaseConn.Model(&logistics).Updates(updates).Error; err != nil {
return errors.New("更新物流模板失败")
}
return nil
}
func (s *LogisticsService) DeleteLogistics(id uint64, db ...*gorm.DB) error {
databaseConn := database.OptionalDB(db...)
if id == 0 {
return errors.New("物流模板ID不能为空")
}
var logistics models.Logistics
if err := databaseConn.Where("id = ? AND del_flag = ?", id, "0").First(&logistics).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return errors.New("物流模板不存在")
}
return errors.New("查询物流模板失败")
}
now := time.Now()
if err := databaseConn.Model(&logistics).Update("del_flag", "1").Update("update_time", &now).Error; err != nil {
return errors.New("删除物流模板失败")
}
return nil
}