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) }