print
CI / changes (push) Successful in 1m30s
CI / ad (push) Successful in 31s
CI / admin (push) Successful in 22s
CI / bff (push) Successful in 20s
CI / chore (push) Successful in 21s
CI / equipment (push) Successful in 22s
CI / express (push) Successful in 21s
CI / factory (push) Successful in 19s
CI / message (push) Successful in 18s
CI / order (push) Successful in 19s
CI / payment (push) Successful in 20s
CI / percutaneous (push) Successful in 19s
CI / product (push) Successful in 20s
CI / record (push) Successful in 19s
CI / sale (push) Successful in 19s
CI / support (push) Successful in 19s
CI / task (push) Successful in 18s
CI / user (push) Successful in 19s
CI / wecom (push) Successful in 20s
CI / changes (push) Successful in 1m30s
CI / ad (push) Successful in 31s
CI / admin (push) Successful in 22s
CI / bff (push) Successful in 20s
CI / chore (push) Successful in 21s
CI / equipment (push) Successful in 22s
CI / express (push) Successful in 21s
CI / factory (push) Successful in 19s
CI / message (push) Successful in 18s
CI / order (push) Successful in 19s
CI / payment (push) Successful in 20s
CI / percutaneous (push) Successful in 19s
CI / product (push) Successful in 20s
CI / record (push) Successful in 19s
CI / sale (push) Successful in 19s
CI / support (push) Successful in 19s
CI / task (push) Successful in 18s
CI / user (push) Successful in 19s
CI / wecom (push) Successful in 20s
This commit is contained in:
@@ -597,6 +597,19 @@ func UniqueStr(arr []string) []string {
|
||||
return res
|
||||
}
|
||||
|
||||
func initRandGenerator() {
|
||||
// 创建随机数源
|
||||
source := rand.NewSource(time.Now().UnixNano())
|
||||
// 基于源创建生成器
|
||||
randGen = rand.New(source)
|
||||
}
|
||||
func GetRandNum(number int) int {
|
||||
// 首次调用时初始化,后续调用直接复用,无重复初始化开销
|
||||
once.Do(initRandGenerator)
|
||||
// 生成0-9999随机数,格式化补零为4位
|
||||
return randGen.Intn(number)
|
||||
}
|
||||
|
||||
// Float 泛型约束,只允许 float32 / float64
|
||||
type Float interface {
|
||||
~float32 | ~float64
|
||||
|
||||
@@ -2,6 +2,7 @@ package dao
|
||||
|
||||
const (
|
||||
CodeStatusBind = 3 //为绑定
|
||||
BacCode = "Lone"
|
||||
)
|
||||
|
||||
type CodeCreate struct {
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"lone-services/pkg/utils"
|
||||
"lone-services/rpc/express/pb"
|
||||
"lone-services/services/express/internal/svc"
|
||||
"lone-services/services/express/validator"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ExpressCompanyLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
BaseLogic
|
||||
}
|
||||
|
||||
func NewExpressCompanyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ExpressCompanyLogic {
|
||||
return &ExpressCompanyLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// ExpressCompany 获取可选的打印公司
|
||||
func (l *ExpressCompanyLogic) ExpressCompany(in *express.ExpressCompanyRequest) (*express.Response, error) {
|
||||
var v validator.CompanyItemsValidator
|
||||
if fail := l.checkParams(in, &v); fail != nil {
|
||||
return fail, nil
|
||||
}
|
||||
adminInfo := utils.GetUserFromCtx(l.ctx)
|
||||
if adminInfo.ID < utils.NumberOne {
|
||||
return l.fail(utils.ErrorNoLoginInfo)
|
||||
}
|
||||
sf := utils.GetConfigInt("transit.sf_send_code_" + in.Code)
|
||||
jd := utils.GetConfigInt("transit.jd_send_code_" + in.Code)
|
||||
if sf < utils.NumberOne || jd < utils.NumberOne {
|
||||
return l.fail(utils.ErrorNotFund)
|
||||
}
|
||||
type retData struct {
|
||||
Name string `json:"name"`
|
||||
Id int `json:"id"`
|
||||
}
|
||||
var data []retData
|
||||
data = append(data, retData{
|
||||
Name: "顺丰",
|
||||
Id: sf,
|
||||
})
|
||||
data = append(data, retData{
|
||||
Name: "京东",
|
||||
Id: jd,
|
||||
})
|
||||
return l.ok(data)
|
||||
}
|
||||
@@ -2,6 +2,13 @@ package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"lone-services/pkg/utils"
|
||||
"lone-services/services/express/internal/dao"
|
||||
"lone-services/services/express/internal/model"
|
||||
"lone-services/services/express/validator"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"lone-services/rpc/express/pb"
|
||||
"lone-services/services/express/internal/svc"
|
||||
@@ -13,6 +20,7 @@ type PrintBarCodeLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
BaseLogic
|
||||
}
|
||||
|
||||
func NewPrintBarCodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PrintBarCodeLogic {
|
||||
@@ -24,7 +32,45 @@ func NewPrintBarCodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Prin
|
||||
}
|
||||
|
||||
func (l *PrintBarCodeLogic) PrintBarCode(in *express.PrintBarCodeRequest) (*express.Response, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
var v validator.PrintBarCodeValidator
|
||||
if fail := l.checkParams(in, &v); fail != nil {
|
||||
return fail, nil
|
||||
}
|
||||
adminInfo := utils.GetUserFromCtx(l.ctx)
|
||||
if adminInfo.ID < utils.NumberOne {
|
||||
return l.fail(utils.ErrorNoLoginInfo)
|
||||
}
|
||||
|
||||
return &express.Response{}, nil
|
||||
var info []dao.CodeInfo
|
||||
modelObj := model.CodeModel{}.Init()
|
||||
for i := utils.NumberOne; i <= int(in.Number); i++ {
|
||||
tmp := dao.CodeCreate{
|
||||
Code: l.getCode(in.ProductId, adminInfo.ID),
|
||||
ProductId: int(in.ProductId),
|
||||
AdminId: int(adminInfo.ID),
|
||||
AdminName: adminInfo.Name,
|
||||
Status: utils.StatusOk,
|
||||
}
|
||||
err := modelObj.Create(&tmp)
|
||||
if err != nil {
|
||||
l.Logger.Error(err)
|
||||
} else {
|
||||
info = append(info, dao.CodeInfo{
|
||||
Id: tmp.Id,
|
||||
ProductId: tmp.ProductId,
|
||||
Code: tmp.Code,
|
||||
Status: utils.StatusOk,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return l.ok(info)
|
||||
}
|
||||
|
||||
func (l *PrintBarCodeLogic) getCode(productId, uId int64) string {
|
||||
now := time.Now()
|
||||
code := dao.BacCode + fmt.Sprintf("%04d", productId) +
|
||||
fmt.Sprintf("%04d", uId) + now.Format("20060102150405") +
|
||||
strconv.Itoa(utils.GetRandNum(1000))
|
||||
return code
|
||||
}
|
||||
|
||||
@@ -2,6 +2,12 @@ package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"lone-services/pkg/modelbase"
|
||||
"lone-services/pkg/utils"
|
||||
"lone-services/services/express/internal/dao"
|
||||
"lone-services/services/express/internal/model"
|
||||
"lone-services/services/express/validator"
|
||||
"strconv"
|
||||
|
||||
"lone-services/rpc/express/pb"
|
||||
"lone-services/services/express/internal/svc"
|
||||
@@ -13,6 +19,7 @@ type PrintBarCodePrintLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
BaseLogic
|
||||
}
|
||||
|
||||
func NewPrintBarCodePrintLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PrintBarCodePrintLogic {
|
||||
@@ -24,7 +31,33 @@ func NewPrintBarCodePrintLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
||||
}
|
||||
|
||||
func (l *PrintBarCodePrintLogic) PrintBarCodePrint(in *express.PrintBarCodePrintRequest) (*express.Response, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
var v validator.PrintBarCodeUseValidator
|
||||
if fail := l.checkParams(in, &v); fail != nil {
|
||||
return fail, nil
|
||||
}
|
||||
adminInfo := utils.GetUserFromCtx(l.ctx)
|
||||
if adminInfo.ID < utils.NumberOne {
|
||||
return l.fail(utils.ErrorNoLoginInfo)
|
||||
}
|
||||
|
||||
return &express.Response{}, nil
|
||||
var info dao.CodeCreate
|
||||
w := modelbase.Params{Eq: map[string]string{"status": utils.StatusFailString, "id": strconv.Itoa(int(in.Id))}}
|
||||
err := model.CodeModel{}.Init().GetOne(w, &info)
|
||||
if err != nil {
|
||||
l.Logger.Error(err)
|
||||
return l.fail(utils.Fail)
|
||||
}
|
||||
if info.Id < utils.NumberOne {
|
||||
return l.fail(utils.ErrorNotFund)
|
||||
}
|
||||
info.Status = utils.StatusOk
|
||||
info.AdminId = int(adminInfo.ID)
|
||||
info.AdminName = adminInfo.Name
|
||||
_, err = model.CodeModel{}.Init().Edit(w, &info)
|
||||
if err != nil {
|
||||
l.Logger.Error(err)
|
||||
return l.fail(utils.Fail)
|
||||
}
|
||||
|
||||
return l.ok(utils.NumberOne)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"lone-services/services/express/validator"
|
||||
|
||||
"lone-services/rpc/express/pb"
|
||||
"lone-services/services/express/internal/svc"
|
||||
@@ -13,6 +14,7 @@ type PrintBindLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
BaseLogic
|
||||
}
|
||||
|
||||
func NewPrintBindLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PrintBindLogic {
|
||||
@@ -25,7 +27,10 @@ func NewPrintBindLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PrintBi
|
||||
|
||||
// 不需要登录
|
||||
func (l *PrintBindLogic) PrintBind(in *express.PrintBindRequest) (*express.Response, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
var v validator.PrintTransitBindValidator
|
||||
if fail := l.checkParams(in, &v); fail != nil {
|
||||
return fail, nil
|
||||
}
|
||||
|
||||
return &express.Response{}, nil
|
||||
}
|
||||
|
||||
@@ -2,9 +2,14 @@ package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"lone-services/pkg/modelbase"
|
||||
"lone-services/pkg/utils"
|
||||
"lone-services/rpc/express/pb"
|
||||
"lone-services/services/express/internal/dao"
|
||||
"lone-services/services/express/internal/model"
|
||||
"lone-services/services/express/internal/svc"
|
||||
"lone-services/services/express/validator"
|
||||
"strconv"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -13,6 +18,7 @@ type PrintExpressLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
BaseLogic
|
||||
}
|
||||
|
||||
func NewPrintExpressLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PrintExpressLogic {
|
||||
@@ -24,7 +30,59 @@ func NewPrintExpressLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Prin
|
||||
}
|
||||
|
||||
func (l *PrintExpressLogic) PrintExpress(in *express.PrintExpressRequest) (*express.Response, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
var v validator.PrintOrderValidator
|
||||
if fail := l.checkParams(in, &v); fail != nil {
|
||||
return fail, nil
|
||||
}
|
||||
adminInfo := utils.GetUserFromCtx(l.ctx)
|
||||
if adminInfo.ID < utils.NumberOne {
|
||||
return l.fail(utils.ErrorNoLoginInfo)
|
||||
}
|
||||
|
||||
return &express.Response{}, nil
|
||||
var info []dao.DeliveryOrderPrint
|
||||
w := modelbase.Params{
|
||||
In: map[string][]string{"status": {strconv.Itoa(dao.SendStatusOk), strconv.Itoa(dao.SendStatusIn), strconv.Itoa(dao.SendStatusWait)}},
|
||||
}
|
||||
if v.Status == utils.NumberOne {
|
||||
w.Page = utils.NumberOne
|
||||
w.Size = utils.SIZE
|
||||
w.Order = "id desc"
|
||||
}
|
||||
|
||||
if v.Status == utils.NumberZero {
|
||||
w.Page = utils.NumberOne
|
||||
w.Size = utils.SIZE
|
||||
w.Order = "print_status desc, id desc"
|
||||
}
|
||||
|
||||
w.Eq = make(map[string]string)
|
||||
if v.Status > utils.NumberZero {
|
||||
w.Eq["print_status"] = strconv.Itoa(int(v.Status))
|
||||
}
|
||||
|
||||
if len(v.OrderSn) > utils.NumberZero {
|
||||
w.Eq["obj_sn"] = v.OrderSn
|
||||
}
|
||||
|
||||
startTime, endTime := utils.TimeToStartAndEnd(v.Time, utils.NumberOne)
|
||||
if len(startTime) > utils.NumberZero {
|
||||
betweenTimeKey := "create_time"
|
||||
if v.Status == utils.NumberOne {
|
||||
betweenTimeKey = "update_time"
|
||||
}
|
||||
w.Between = map[string][2]string{betweenTimeKey: {startTime, endTime}}
|
||||
}
|
||||
|
||||
items, err := model.DeliveryOrderModel{}.Init().Page(w, &info)
|
||||
|
||||
if err != nil {
|
||||
l.Logger.Error(err)
|
||||
return l.fail(utils.Fail)
|
||||
}
|
||||
|
||||
obj := svc.Print{}
|
||||
obj.GetOrderInfo(l.svcCtx.ProductSvcName, &info)
|
||||
items.Items = info
|
||||
|
||||
return l.ok(items)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,19 @@ package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"lone-services/pkg/modelbase"
|
||||
"lone-services/pkg/utils"
|
||||
"lone-services/services/express/internal/dao"
|
||||
"lone-services/services/express/internal/model"
|
||||
"lone-services/services/express/internal/transit"
|
||||
"lone-services/services/express/validator"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"lone-services/rpc/express/pb"
|
||||
"lone-services/services/express/internal/svc"
|
||||
@@ -13,6 +26,7 @@ type PrintExpressPrintLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
BaseLogic
|
||||
}
|
||||
|
||||
func NewPrintExpressPrintLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PrintExpressPrintLogic {
|
||||
@@ -24,7 +38,248 @@ func NewPrintExpressPrintLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
||||
}
|
||||
|
||||
func (l *PrintExpressPrintLogic) PrintExpressPrint(in *express.PrintExpressPrintRequest) (*express.Response, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
var v validator.PrintOrderUseValidator
|
||||
if fail := l.checkParams(in, &v); fail != nil {
|
||||
return fail, nil
|
||||
}
|
||||
adminInfo := utils.GetUserFromCtx(l.ctx)
|
||||
if adminInfo.ID < utils.NumberOne {
|
||||
return l.fail(utils.ErrorNoLoginInfo)
|
||||
}
|
||||
|
||||
return &express.Response{}, nil
|
||||
var itemsEdit []dao.DeliveryOrderPrintEdit
|
||||
w := modelbase.Params{
|
||||
Eq: map[string]string{"id": strconv.FormatInt(in.Id, utils.NumberTen)}}
|
||||
modelObj := model.DeliveryOrderModel{}.Init()
|
||||
err := modelObj.Items(w, &itemsEdit)
|
||||
if err != nil {
|
||||
l.Logger.Error(err)
|
||||
return l.fail(utils.Fail)
|
||||
}
|
||||
|
||||
if len(itemsEdit) < utils.NumberOne {
|
||||
return l.fail(utils.ErrorNotFund)
|
||||
}
|
||||
|
||||
if itemsEdit[utils.NumberZero].Status == dao.SendStatusOk ||
|
||||
itemsEdit[utils.NumberZero].Status == dao.SendStatusOver {
|
||||
return l.fail(utils.SetError(utils.ErrorNotFund, "该订单已完结"))
|
||||
}
|
||||
|
||||
if in.TransitId < utils.NumberOne {
|
||||
in.TransitId = int64(utils.GetConfigInt("transit.send_id"))
|
||||
}
|
||||
tw := modelbase.Params{Eq: map[string]string{"id": strconv.FormatInt(in.TransitId, utils.NumberTen)}}
|
||||
var transitInfo dao.ExpressSend
|
||||
err = model.ExpressModel{}.Init().GetOne(tw, &transitInfo)
|
||||
if err != nil {
|
||||
l.Logger.Error("发货地址信息没有找到", in.TransitId, err)
|
||||
return l.fail(utils.SetError(utils.ErrorNotFund, "没有查询到发货信息"))
|
||||
}
|
||||
if transitInfo.Id < utils.NumberOne {
|
||||
return l.fail(utils.SetError(utils.ErrorNotFund, "没有查询到发货信息"))
|
||||
}
|
||||
|
||||
var items []dao.DeliveryOrderPrint
|
||||
items = append(items, dao.DeliveryOrderPrint{
|
||||
DeliveryOrderPrintEdit: itemsEdit[utils.NumberZero],
|
||||
})
|
||||
svc.Print{}.GetOrderInfo(l.svcCtx.ProductSvcName, &items)
|
||||
info := itemsEdit[utils.NumberZero]
|
||||
//更新使用的快递类型
|
||||
info.TransitType = transitInfo.TransitId
|
||||
|
||||
info.OrderSn = svc.Print{}.GetOrderSn(info.TransitType, int(adminInfo.ID))
|
||||
items[utils.NumberZero].OrderSn = info.OrderSn
|
||||
client, res, cErr := l.createTransit(items[utils.NumberZero], transitInfo)
|
||||
if cErr != utils.Ok {
|
||||
return l.fail(cErr)
|
||||
}
|
||||
info.TransitInfo = res.PostInfo
|
||||
info.TransitContent = res.RequestInfo
|
||||
info.TransitSn = strings.Join(res.WaybillNo, utils.DecollatorComma)
|
||||
|
||||
items[utils.NumberZero].AdminName = adminInfo.Name
|
||||
res2, gErr := l.getDown(client, res.WaybillNo, items[utils.NumberZero])
|
||||
if gErr != nil {
|
||||
retStatus := svc.Cancel(client, w, info, dao.SendStatusCancel, l.svcCtx.OrderSvcName)
|
||||
if retStatus != utils.Ok {
|
||||
return l.fail(retStatus)
|
||||
}
|
||||
l.Logger.Error(res2, gErr)
|
||||
return l.fail(utils.SetError(utils.ErrorNotFund, "下载发货单出错"))
|
||||
}
|
||||
|
||||
info.Express = utils.StructToJson(res2.Files)
|
||||
info.PrintStatus = utils.StatusOk
|
||||
info.AdminId = int(adminInfo.ID)
|
||||
info.AdminName = adminInfo.Name
|
||||
info.TransitId = int(in.TransitId)
|
||||
info.TransitName = transitInfo.Name
|
||||
info.Status = dao.SendStatusOk
|
||||
info.SendTime = utils.Now()
|
||||
|
||||
items[utils.NumberZero].PrintStatus = info.PrintStatus
|
||||
items[utils.NumberZero].AdminId = info.AdminId
|
||||
items[utils.NumberZero].AdminName = info.AdminName
|
||||
items[utils.NumberZero].TransitId = info.TransitId
|
||||
items[utils.NumberZero].TransitInfo = info.TransitInfo
|
||||
items[utils.NumberZero].TransitContent = info.TransitContent
|
||||
items[utils.NumberZero].TransitSn = info.TransitSn
|
||||
items[utils.NumberZero].TransitName = info.TransitName
|
||||
items[utils.NumberZero].Status = info.Status
|
||||
items[utils.NumberZero].Express = info.Express
|
||||
|
||||
var history dao.DeliveryHistoryCreate
|
||||
history.DeliverId = info.Id
|
||||
history.TransitName = dao.DeliverySendType[info.TransitType]
|
||||
history.TransitInfo = info.TransitInfo
|
||||
history.TransitContent = info.TransitContent
|
||||
history.TransitType = info.TransitType
|
||||
history.OrderSn = info.OrderSn
|
||||
|
||||
var exps []dao.DeliveryExpCreate
|
||||
for i := 0; i < len(res.WaybillNo); i++ {
|
||||
exps = append(exps, dao.DeliveryExpCreate{
|
||||
DeliveryOrderId: info.Id,
|
||||
TransitType: info.TransitType,
|
||||
ExpSn: res.WaybillNo[i],
|
||||
OrderSn: info.OrderSn,
|
||||
})
|
||||
}
|
||||
|
||||
sErr := l.saveDelever(w, &info, &history, &exps)
|
||||
if sErr != utils.Ok {
|
||||
retStatus := svc.Cancel(client, w, info, dao.SendStatusCancel, l.svcCtx.OrderSvcName)
|
||||
if retStatus != utils.Ok {
|
||||
return l.fail(retStatus)
|
||||
}
|
||||
l.Logger.Error(res2, sErr)
|
||||
return l.fail(sErr)
|
||||
}
|
||||
|
||||
return l.ok(items[utils.NumberZero])
|
||||
}
|
||||
|
||||
func (l *PrintExpressPrintLogic) createTransit(info dao.DeliveryOrderPrint, transitInfo dao.ExpressSend) (transit.Transit, transit.TransitResult, utils.Status) {
|
||||
var client transit.Transit
|
||||
switch transitInfo.TransitId {
|
||||
case dao.ExpressCompanySf:
|
||||
client = transit.NewSfClient(transitInfo)
|
||||
case dao.ExpressCompanyJd:
|
||||
client = transit.NewJdClient(transitInfo)
|
||||
default:
|
||||
return client, transit.TransitResult{}, utils.SetError(utils.Fail, "不支持的快递公司")
|
||||
}
|
||||
res, err := client.Create(info)
|
||||
if err != nil || res.ErrorCode != utils.StringStatusOk {
|
||||
l.Logger.Error("create transit err", err, res)
|
||||
return client, res, utils.SetError(utils.Fail, res.ApiErrorMsg)
|
||||
}
|
||||
|
||||
return client, res, utils.Ok
|
||||
}
|
||||
|
||||
func (l *PrintExpressPrintLogic) getDown(client transit.Transit, orders []string, info dao.DeliveryOrderPrint) (transit.TransitResult, error) {
|
||||
ret, err := client.DownSheet(orders, info)
|
||||
if err != nil || len(ret.Files) < utils.NumberOne {
|
||||
l.Logger.Error("get down err ", orders, err, ret)
|
||||
if len(ret.Files) < utils.NumberOne {
|
||||
err = errors.New("files is empty")
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
path := utils.GetConfigString("transit.path") + "/"
|
||||
var tmpFiles []transit.TransitFiles
|
||||
for i := 0; i < len(ret.Files); i++ {
|
||||
tName := ret.Files[i].WaybillNo + ".pdf"
|
||||
err := l.downloadSfPDF(ret.Files[i], path+tName)
|
||||
if err != nil {
|
||||
l.Logger.Error("get down err ", orders, err, ret)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
tmpFiles = append(tmpFiles, transit.TransitFiles{
|
||||
File: tName,
|
||||
WaybillNo: ret.Files[i].WaybillNo,
|
||||
})
|
||||
}
|
||||
|
||||
ret.Files = tmpFiles
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (l *PrintExpressPrintLogic) downloadSfPDF(file transit.TransitFiles, path string) error {
|
||||
req, err := http.NewRequest("GET", file.Url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. 必须加这个请求头(顺丰强制)
|
||||
req.Header.Add("X-Auth-token", file.Token)
|
||||
// 3. 发送请求
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
err := Body.Close()
|
||||
if err != nil {
|
||||
utils.Logger.Error(err)
|
||||
}
|
||||
}(resp.Body)
|
||||
// 4. 创建目录
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
// 5. 创建文件并保存
|
||||
outFile, err := os.Create(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(outFile *os.File) {
|
||||
err = outFile.Close()
|
||||
if err != nil {
|
||||
utils.Logger.Error(err)
|
||||
}
|
||||
}(outFile)
|
||||
// 6. 拷贝数据
|
||||
_, err = io.Copy(outFile, resp.Body)
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *PrintExpressPrintLogic) saveDelever(w modelbase.Params, info *dao.DeliveryOrderPrintEdit, history *dao.DeliveryHistoryCreate, exps *[]dao.DeliveryExpCreate) utils.Status {
|
||||
modelObj := model.DeliveryOrderModel{}.Init()
|
||||
modelObj.Begin()
|
||||
edit, err := modelObj.Edit(w, info)
|
||||
if err != nil || edit < utils.NumberOne {
|
||||
modelObj.Rollback()
|
||||
l.Logger.Error("save deliver goods err ", err)
|
||||
return utils.SetError(utils.Fail, "生成快递单失败")
|
||||
}
|
||||
|
||||
err = model.DeliveryOrderExpModel{}.Init().CreateMulti(exps)
|
||||
if err != nil {
|
||||
modelObj.Rollback()
|
||||
l.Logger.Error("save exp err ", err)
|
||||
return utils.SetError(utils.Fail, "生成EXP失败")
|
||||
}
|
||||
|
||||
err = model.DeliveryHistoryModel{}.Init().Create(history)
|
||||
if err != nil {
|
||||
modelObj.Rollback()
|
||||
l.Logger.Error("save history err ", err)
|
||||
return utils.SetError(utils.Fail, "生成订单历史失败")
|
||||
}
|
||||
s := svc.UpOrderDeliverStatus(l.svcCtx.OrderSvcName, info.ObjId, int(info.Type), int32(info.Status))
|
||||
if s != utils.Ok {
|
||||
modelObj.Rollback()
|
||||
l.Logger.Error("save update order err ", err)
|
||||
return s
|
||||
}
|
||||
|
||||
modelObj.Commit()
|
||||
return utils.Ok
|
||||
}
|
||||
|
||||
@@ -2,9 +2,14 @@ package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"lone-services/pkg/utils"
|
||||
"lone-services/rpc/express/pb"
|
||||
product "lone-services/rpc/product/pb"
|
||||
"lone-services/services/express/internal/dao"
|
||||
"lone-services/services/express/internal/svc"
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -13,6 +18,7 @@ type PrintProductLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
BaseLogic
|
||||
}
|
||||
|
||||
func NewPrintProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PrintProductLogic {
|
||||
@@ -24,7 +30,76 @@ func NewPrintProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Prin
|
||||
}
|
||||
|
||||
func (l *PrintProductLogic) PrintProduct(in *express.EmtpyRequest) (*express.Response, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
adminInfo := utils.GetUserFromCtx(l.ctx)
|
||||
if adminInfo.ID < utils.NumberOne {
|
||||
return l.fail(utils.ErrorNoLoginInfo)
|
||||
}
|
||||
|
||||
return &express.Response{}, nil
|
||||
items, err := l.getProducts()
|
||||
if err != utils.Ok {
|
||||
return l.fail(err)
|
||||
}
|
||||
|
||||
return l.ok(items)
|
||||
}
|
||||
|
||||
func (l *PrintProductLogic) getProducts() ([]dao.ProductPrint, utils.Status) {
|
||||
cli, err := svc.GetRpcClient(l.svcCtx.ProductSvcName)
|
||||
if err != nil {
|
||||
l.Logger.Error(err)
|
||||
return nil, utils.ErrorInternalServer
|
||||
}
|
||||
|
||||
var Type []uint32
|
||||
Status := []uint32{utils.StatusOk, utils.StatusFail}
|
||||
productClient := product.NewProductClient(cli.Conn())
|
||||
productItems, err := productClient.InternalItems(l.ctx, &product.InternalItemsReq{Status: Status, Type: Type})
|
||||
if err != nil {
|
||||
logx.Errorf("get products err: %v", err)
|
||||
return nil, utils.SetError(utils.Fail, "获取产品信息错误")
|
||||
}
|
||||
|
||||
var info []dao.ProductPrint
|
||||
for _, val := range productItems.Items {
|
||||
client := &http.Client{
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
resp, err := client.Get(val.Waybill)
|
||||
if err != nil {
|
||||
return info, utils.Fail
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
err := Body.Close()
|
||||
if err != nil {
|
||||
utils.Logger.Error(err)
|
||||
}
|
||||
}(resp.Body)
|
||||
|
||||
// 读取图片二进制内容
|
||||
imgData, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
utils.Logger.Error(err)
|
||||
return info, utils.Fail
|
||||
}
|
||||
|
||||
// 自动识别图片类型(png/jpg/gif 等)
|
||||
contentType := http.DetectContentType(imgData)
|
||||
|
||||
// 转 base64
|
||||
base64Str := base64.StdEncoding.EncodeToString(imgData)
|
||||
|
||||
// 拼接成可直接在 img 标签显示的格式
|
||||
imageBase64 := "data:" + contentType + ";base64," + base64Str
|
||||
info = append(info, dao.ProductPrint{
|
||||
Id: int(val.Id),
|
||||
Name: val.Name,
|
||||
Weight: float32(val.Weight),
|
||||
Cubage: val.Cubage,
|
||||
Waybill: imageBase64,
|
||||
})
|
||||
}
|
||||
|
||||
return info, utils.Ok
|
||||
}
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"lone-services/pkg/utils"
|
||||
product "lone-services/rpc/product/pb"
|
||||
"lone-services/services/express/internal/dao"
|
||||
"lone-services/services/express/internal/transit"
|
||||
"math"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type Print struct {
|
||||
}
|
||||
|
||||
func (s Print) GetOrderInfo(name string, items *[]dao.DeliveryOrderPrint) {
|
||||
products := s.getProducts(name)
|
||||
for value, item := range *items {
|
||||
obj := &(*items)[value]
|
||||
mobile, aErr := utils.Crypto{}.AESDecryptECB(item.Mobile)
|
||||
if aErr == nil {
|
||||
obj.Mobile = mobile
|
||||
}
|
||||
obj.Url = utils.GetConfigString("transit.url")
|
||||
obj.Number, obj.Weight, obj.ProductItems = s.getProductInfo(item.ObjSn, item.ProductInfo, &products)
|
||||
}
|
||||
}
|
||||
|
||||
func (s Print) getProducts(name string) map[int]dao.ProductPrint {
|
||||
products := make(map[int]dao.ProductPrint)
|
||||
|
||||
cli, err := GetRpcClient(name)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return products
|
||||
}
|
||||
|
||||
var Type []uint32
|
||||
var status []uint32
|
||||
productClient := product.NewProductClient(cli.Conn())
|
||||
productItems, err := productClient.InternalItems(context.Background(), &product.InternalItemsReq{Status: status, Type: Type})
|
||||
if err != nil {
|
||||
logx.Errorf("get products err: %v", err)
|
||||
return products
|
||||
}
|
||||
|
||||
for _, item := range productItems.Items {
|
||||
products[int(item.Id)] = dao.ProductPrint{
|
||||
Id: int(item.Id),
|
||||
Name: item.Name,
|
||||
Weight: float32(item.Weight),
|
||||
Cubage: item.Cubage,
|
||||
Waybill: item.Waybill,
|
||||
}
|
||||
}
|
||||
|
||||
return products
|
||||
}
|
||||
|
||||
func (s Print) getProductInfo(orderSn string, info string, product *map[int]dao.ProductPrint) (int, float32, []dao.DeliveryOrderProduct) {
|
||||
var items []dao.DeliveryOrderProduct
|
||||
totalNum := 0
|
||||
totalWeight := float32(0)
|
||||
|
||||
if len(info) == utils.NumberZero {
|
||||
return totalNum, totalWeight, items
|
||||
}
|
||||
|
||||
// 1. 解析JSON
|
||||
data, err := s.jsonToMap(info)
|
||||
if err != nil {
|
||||
logx.Error("JSON解析商品信息失败", err, info)
|
||||
return totalNum, totalWeight, items
|
||||
}
|
||||
|
||||
for _, item := range data {
|
||||
itemMap, ok := item.(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
tmp := s.orderInfo(orderSn, itemMap, product)
|
||||
items = append(items, tmp)
|
||||
|
||||
// 统计总数、总重量
|
||||
totalNum += tmp.ProductNumber
|
||||
totalWeight += tmp.ProductWeight
|
||||
}
|
||||
|
||||
return totalNum, totalWeight, items
|
||||
}
|
||||
|
||||
// 解析JSON数组
|
||||
func (s Print) jsonToMap(info string) ([]interface{}, error) {
|
||||
var data []interface{}
|
||||
err := json.Unmarshal([]byte(info), &data)
|
||||
return data, err
|
||||
}
|
||||
|
||||
// 构建单个商品对象
|
||||
func (s Print) orderInfo(orderSn string, itemMap map[string]interface{}, product *map[int]dao.ProductPrint) dao.DeliveryOrderProduct {
|
||||
tmp := dao.DeliveryOrderProduct{OrderSn: orderSn}
|
||||
|
||||
s.getProduct(itemMap, &tmp)
|
||||
s.getBox(&tmp, product)
|
||||
|
||||
return tmp
|
||||
}
|
||||
|
||||
func (s Print) getProduct(itemMap map[string]interface{}, tmp *dao.DeliveryOrderProduct) {
|
||||
if val, ok := itemMap["product_id"].(float64); ok {
|
||||
tmp.ProductId = int(val)
|
||||
}
|
||||
if val, ok := itemMap["number"].(float64); ok {
|
||||
tmp.ProductNumber = int(val)
|
||||
}
|
||||
if val, ok := itemMap["product_name"].(string); ok {
|
||||
tmp.ProductName = val
|
||||
}
|
||||
if val, ok := itemMap["price"].(float64); ok {
|
||||
tmp.Price = float32(val)
|
||||
}
|
||||
}
|
||||
|
||||
// 长度高
|
||||
func (s Print) getBoxInfo(cubage []string, index int) float32 {
|
||||
if index >= len(cubage) {
|
||||
return utils.NumberZero
|
||||
}
|
||||
|
||||
val, err := strconv.ParseFloat(strings.TrimSpace(cubage[index]), 64)
|
||||
if err != nil {
|
||||
return utils.NumberZero
|
||||
}
|
||||
|
||||
return s.toFixed3(float32(val))
|
||||
}
|
||||
|
||||
// 保留3位小数
|
||||
func (s Print) toFixed3(f float32) float32 {
|
||||
return float32(math.Round(float64(f)*1000) / 1000)
|
||||
}
|
||||
|
||||
func (s Print) GetOrderSn(orderType uint8, adminId int) string {
|
||||
first := dao.DeliverySendType[orderType]
|
||||
|
||||
sn := first + time.Now().Format("20060102150405")
|
||||
sn += fmt.Sprintf("%d%d", orderType, adminId)
|
||||
randomNum := rand.Intn(90000000) + 10000000
|
||||
sn += fmt.Sprintf("%d", randomNum)
|
||||
|
||||
return sn
|
||||
}
|
||||
|
||||
func (s Print) getTransitInfo(transitInfo dao.ExpressSend) (transit.Transit, utils.Status) {
|
||||
var client transit.Transit
|
||||
switch transitInfo.TransitId {
|
||||
case dao.ExpressCompanySf:
|
||||
client = transit.NewSfClient(transitInfo)
|
||||
case dao.ExpressCompanyJd:
|
||||
client = transit.NewJdClient(transitInfo)
|
||||
default:
|
||||
return client, utils.SetError(utils.ErrorNotFund, "没有找到快递公司")
|
||||
}
|
||||
|
||||
return client, utils.Ok
|
||||
}
|
||||
|
||||
func (s Print) getSfMap(items []dao.ExpressQueryItems) map[string]bool {
|
||||
ret := make(map[string]bool)
|
||||
for _, item := range items {
|
||||
ret[item.LastMd5] = true
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// 体积
|
||||
func (s Print) getBox(tmp *dao.DeliveryOrderProduct, product *map[int]dao.ProductPrint) {
|
||||
if product == nil {
|
||||
return
|
||||
}
|
||||
|
||||
p, exists := (*product)[tmp.ProductId]
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
|
||||
tmp.ProductWeight = s.toFixed3(p.Weight * float32(tmp.ProductNumber))
|
||||
|
||||
cubage := strings.Split(p.Cubage, "*")
|
||||
tmp.ProductLength = s.getBoxInfo(cubage, 0)
|
||||
tmp.ProductWidth = s.getBoxInfo(cubage, 1)
|
||||
tmp.ProductHeight = s.getBoxInfo(cubage, 2)
|
||||
|
||||
// 计算体积
|
||||
tmp.ProductCubage = s.toFixed3(tmp.ProductLength * tmp.ProductWidth * tmp.ProductHeight)
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package validator
|
||||
import "lone-services/pkg/validate"
|
||||
|
||||
type PrintLoginValidator struct {
|
||||
Username int `form:"username" json:"username" validate:"required"`
|
||||
Password int `form:"password" json:"password" validate:"required"`
|
||||
Username string `form:"username" json:"username" validate:"required"`
|
||||
Password string `form:"password" json:"password" validate:"required"`
|
||||
}
|
||||
|
||||
// GetMessage 提示消息
|
||||
@@ -25,12 +25,12 @@ func (p PrintExpressTransitValidator) GetMessage() validate.ValidatorMessages {
|
||||
}
|
||||
}
|
||||
|
||||
type PrintETransitBindValidator struct {
|
||||
Codes string `form:"codes" json:"c" binding:"required"`
|
||||
type PrintTransitBindValidator struct {
|
||||
Codes string `form:"codes" json:"codes" binding:"required"`
|
||||
}
|
||||
|
||||
// GetMessage 提示消息
|
||||
func (p PrintETransitBindValidator) GetMessage() validate.ValidatorMessages {
|
||||
func (p PrintTransitBindValidator) GetMessage() validate.ValidatorMessages {
|
||||
return validate.ValidatorMessages{
|
||||
"Codes.required": "codes不能为空",
|
||||
}
|
||||
@@ -38,8 +38,8 @@ func (p PrintETransitBindValidator) GetMessage() validate.ValidatorMessages {
|
||||
|
||||
// PrintBarCodeValidator 创建产品
|
||||
type PrintBarCodeValidator struct {
|
||||
Number int `form:"number" json:"number"`
|
||||
ProductId int `form:"product_id" json:"product_id" validate:"required"`
|
||||
Number int32 `form:"number" json:"number"`
|
||||
ProductId int64 `form:"product_id" json:"product_id" validate:"required"`
|
||||
}
|
||||
|
||||
// GetMessage 提示消息
|
||||
@@ -50,7 +50,7 @@ func (p PrintBarCodeValidator) GetMessage() validate.ValidatorMessages {
|
||||
}
|
||||
|
||||
type PrintBarCodeUseValidator struct {
|
||||
Id int `form:"id" json:"id" validate:"required"`
|
||||
Id int64 `form:"id" json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
// GetMessage 提示消息
|
||||
@@ -61,7 +61,7 @@ func (p PrintBarCodeUseValidator) GetMessage() validate.ValidatorMessages {
|
||||
}
|
||||
|
||||
type PrintOrderValidator struct {
|
||||
Status uint8 `form:"status" json:"status"`
|
||||
Status int32 `form:"status" json:"status"`
|
||||
OrderSn string `form:"order_sn" json:"order_sn"`
|
||||
Time string `form:"time" json:"time"`
|
||||
}
|
||||
@@ -72,8 +72,8 @@ func (p PrintOrderValidator) GetMessage() validate.ValidatorMessages {
|
||||
}
|
||||
|
||||
type PrintOrderUseValidator struct {
|
||||
Id int `form:"id" json:"id" validate:"required"`
|
||||
TransitId int `form:"transit_id" json:"transit_id"`
|
||||
Id int64 `form:"id" json:"id" validate:"required"`
|
||||
TransitId int64 `form:"transit_id" json:"transit_id"`
|
||||
}
|
||||
|
||||
// GetMessage 提示消息
|
||||
|
||||
Reference in New Issue
Block a user