262 lines
7.1 KiB
Go
262 lines
7.1 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{}
|
|
|
|
// GetLogisticsList 获取物流模板列表
|
|
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
|
|
}
|
|
|
|
// GetLogisticsByID 获取物流模板详情
|
|
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
|
|
}
|
|
|
|
// CreateLogistics 创建物流模板
|
|
// 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
|
|
}
|
|
|
|
// CreateLogistics 创建物流模板
|
|
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
|
|
}
|
|
|
|
// UpdateLogistics 修改物流模板
|
|
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
|
|
}
|
|
|
|
// DeleteLogistics 删除物流模板
|
|
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
|
|
}
|