回调
CI / changes (push) Successful in 37s
CI / ad (push) Successful in 30s
CI / admin (push) Successful in 22s
CI / bff (push) Successful in 39s
CI / chore (push) Successful in 20s
CI / equipment (push) Successful in 19s
CI / express (push) Successful in 17s
CI / product (push) Successful in 16s
CI / record (push) Successful in 17s
CI / sale (push) Successful in 16s
CI / task (push) Successful in 16s
CI / user (push) Successful in 17s
CI / wecom (push) Successful in 18s
CI / changes (push) Successful in 37s
CI / ad (push) Successful in 30s
CI / admin (push) Successful in 22s
CI / bff (push) Successful in 39s
CI / chore (push) Successful in 20s
CI / equipment (push) Successful in 19s
CI / express (push) Successful in 17s
CI / product (push) Successful in 16s
CI / record (push) Successful in 17s
CI / sale (push) Successful in 16s
CI / task (push) Successful in 16s
CI / user (push) Successful in 17s
CI / wecom (push) Successful in 18s
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"lone-services/pkg/utils"
|
||||
@@ -32,9 +31,7 @@ const (
|
||||
CtxGroupId ctxKey = "X-Group-Id"
|
||||
CtxGroupName ctxKey = "X-Group-Name"
|
||||
CtxUserType ctxKey = "X-User-Type"
|
||||
CtxCallbackRawBody ctxKey = "callback_raw_body"
|
||||
CtxCallbackHeaders ctxKey = "callback_headers"
|
||||
CtxCallbackErr ctxKey = "callback_read_err"
|
||||
CtxRawBody ctxKey = "X-Raw-Body"
|
||||
)
|
||||
|
||||
var callbackPrefixes = []string{
|
||||
@@ -60,6 +57,7 @@ type UserInfo struct {
|
||||
StoreName string
|
||||
GroupId string
|
||||
GroupName string
|
||||
RawBody string
|
||||
Valid bool
|
||||
}
|
||||
|
||||
@@ -79,6 +77,7 @@ func GetUserInfo(ctx context.Context) UserInfo {
|
||||
storeName, _ := ctx.Value(CtxStoreName).(string)
|
||||
groupId, _ := ctx.Value(CtxGroupId).(string)
|
||||
groupName, _ := ctx.Value(CtxGroupName).(string)
|
||||
rawBody, _ := ctx.Value(CtxRawBody).(string)
|
||||
|
||||
info := UserInfo{
|
||||
RawUID: rawUID,
|
||||
@@ -96,6 +95,7 @@ func GetUserInfo(ctx context.Context) UserInfo {
|
||||
StoreName: storeName,
|
||||
GroupId: groupId,
|
||||
GroupName: groupName,
|
||||
RawBody: rawBody,
|
||||
}
|
||||
if rawUID == "" {
|
||||
return info
|
||||
@@ -122,29 +122,17 @@ func getRealClientIP(r *http.Request) string {
|
||||
return r.RemoteAddr
|
||||
}
|
||||
|
||||
// UserReadMiddleware
|
||||
/** 增加透传的方法
|
||||
* 1、这里加上代码
|
||||
* 2、UserClientInterceptor这个方法里也要写相应的代码对可以
|
||||
*/
|
||||
func UserReadMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
newCtx := r.Context()
|
||||
if isCallbackPath(r.URL.Path) {
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
newCtx = context.WithValue(newCtx, CtxCallbackRawBody, []byte(nil))
|
||||
newCtx = context.WithValue(newCtx, CtxCallbackHeaders, http.Header(nil))
|
||||
newCtx = context.WithValue(newCtx, CtxCallbackErr, err)
|
||||
} else {
|
||||
r.Body = io.NopCloser(bytes.NewBuffer(body))
|
||||
header := make(http.Header)
|
||||
for k, vv := range r.Header {
|
||||
header[k] = vv
|
||||
}
|
||||
newCtx = context.WithValue(newCtx, CtxCallbackRawBody, body)
|
||||
newCtx = context.WithValue(newCtx, CtxCallbackHeaders, header)
|
||||
newCtx = context.WithValue(newCtx, CtxCallbackErr, error(nil))
|
||||
}
|
||||
next(w, r.WithContext(newCtx))
|
||||
return
|
||||
}
|
||||
|
||||
newCtx := r.Context()
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
newCtx = context.WithValue(newCtx, CtxRawBody, string(body))
|
||||
newCtx = context.WithValue(newCtx, CtxUserId, r.Header.Get("X-User-Id"))
|
||||
newCtx = context.WithValue(newCtx, CtxUserName, r.Header.Get("X-User-Name"))
|
||||
newCtx = context.WithValue(newCtx, CtxRefresh, r.Header.Get("X-Refresh"))
|
||||
@@ -160,7 +148,6 @@ func UserReadMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
||||
newCtx = context.WithValue(newCtx, CtxStoreName, r.Header.Get("X-Store-Name"))
|
||||
newCtx = context.WithValue(newCtx, CtxGroupId, r.Header.Get("X-Group-Id"))
|
||||
newCtx = context.WithValue(newCtx, CtxGroupName, r.Header.Get("X-Group-Name"))
|
||||
|
||||
next(w, r.WithContext(newCtx))
|
||||
}
|
||||
}
|
||||
@@ -189,6 +176,7 @@ func UserClientInterceptor(ctx context.Context, method string, req, reply any, c
|
||||
md.Set("x-user-name", url.QueryEscape(user.Name))
|
||||
}
|
||||
|
||||
setMDIfNotEmpty(md, "x-raw-body", user.RawBody)
|
||||
setMDIfNotEmpty(md, "x-refresh", user.Refresh)
|
||||
setMDIfNotEmpty(md, "x-client-ip", user.ClientIP)
|
||||
if user.UserAgent != utils.StringEmpty {
|
||||
|
||||
@@ -2,6 +2,7 @@ package response
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"lone-services/pkg/utils"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -16,6 +17,11 @@ type bodyWriter struct {
|
||||
buf bytes.Buffer
|
||||
}
|
||||
|
||||
type responseDataBack struct {
|
||||
ReturnCode string `json:"returnCode"`
|
||||
ReturnMsg string `json:"returnMsg"`
|
||||
}
|
||||
|
||||
type responseData struct {
|
||||
Code int32 `json:"code"`
|
||||
Data any `json:"data"`
|
||||
@@ -48,8 +54,22 @@ func Wrap(next http.HandlerFunc) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
}
|
||||
if data.Code < utils.NumberOne {
|
||||
var back responseDataBack
|
||||
|
||||
if err := jsoniter.Unmarshal(raw, &back); err != nil {
|
||||
ctrl.Fail(w)
|
||||
return
|
||||
}
|
||||
if len(back.ReturnCode) < utils.NumberOne {
|
||||
ctrl.Fail(w)
|
||||
return
|
||||
}
|
||||
ctrl.OutPutBack(w, back)
|
||||
} else {
|
||||
ctrl.OutPut(w, data.Code, unwrapJSONData(data.Data), data.Msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func unwrapJSONData(v any) any {
|
||||
|
||||
@@ -53,3 +53,10 @@ func (b *BaseController) OutPut(w http.ResponseWriter, code int32, data any, msg
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_ = jsoniter.NewEncoder(w).Encode(out)
|
||||
}
|
||||
|
||||
func (b *BaseController) OutPutBack(w http.ResponseWriter, back responseDataBack) {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_ = jsoniter.NewEncoder(w).Encode(back)
|
||||
}
|
||||
|
||||
+6
-20
@@ -2,7 +2,6 @@ package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
@@ -10,12 +9,6 @@ import (
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
const (
|
||||
CtxCallbackRawBody string = "callback_raw_body"
|
||||
CtxCallbackHeaders string = "callback_headers"
|
||||
CtxCallbackErr string = "callback_read_err"
|
||||
)
|
||||
|
||||
type UserInfo struct {
|
||||
ID int64
|
||||
Name string
|
||||
@@ -38,11 +31,6 @@ type UserInfo struct {
|
||||
Valid bool
|
||||
}
|
||||
|
||||
type HeaderAndBody struct {
|
||||
Header http.Header
|
||||
Body []byte
|
||||
}
|
||||
|
||||
func firstMD(md metadata.MD, keys ...string) string {
|
||||
for _, key := range keys {
|
||||
vals := md.Get(key)
|
||||
@@ -122,13 +110,11 @@ func GetUserFromCtx(ctx context.Context) UserInfo {
|
||||
return userInfo
|
||||
}
|
||||
|
||||
// GetHeaderAndBody 只从ctx拿数据,不写http响应,Err交给handler处理
|
||||
func GetHeaderAndBody(ctx context.Context) HeaderAndBody {
|
||||
rawBody, _ := ctx.Value(CtxCallbackRawBody).([]byte)
|
||||
headers, _ := ctx.Value(CtxCallbackHeaders).(http.Header)
|
||||
|
||||
return HeaderAndBody{
|
||||
Header: headers,
|
||||
Body: rawBody,
|
||||
// GetBody 只从ctx拿数据,不写http响应,Err交给handler处理
|
||||
func GetBody(ctx context.Context) string {
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
return StringEmpty
|
||||
}
|
||||
return firstMD(md, "x-raw-body")
|
||||
}
|
||||
|
||||
+7
-6
@@ -14,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/xuri/excelize/v2"
|
||||
@@ -245,7 +246,7 @@ func RoundMoney(amount float64) float64 {
|
||||
func Decrypt(str string) (string, Error) {
|
||||
str, err := Crypto{}.AESDecryptECB(str)
|
||||
if err != nil {
|
||||
Logger.Error("decrypt str error", str, err)
|
||||
logx.Error("decrypt str error", str, err)
|
||||
return str, err
|
||||
}
|
||||
|
||||
@@ -259,7 +260,7 @@ func DecryptMobile(mobile string) string {
|
||||
|
||||
mobile, err := Decrypt(mobile)
|
||||
if err != nil {
|
||||
Logger.Error("decrypt mobile error", mobile, err)
|
||||
logx.Error("decrypt mobile error", mobile, err)
|
||||
return mobile
|
||||
}
|
||||
|
||||
@@ -488,12 +489,12 @@ func Unique(s []string) []string {
|
||||
func MapToStruct(data map[string]interface{}, target interface{}) error {
|
||||
jsonData, err := jsoniter.Marshal(data) // 将 map 转换为 JSON 字节切片
|
||||
if err != nil {
|
||||
Logger.Error("Error marshalling map to JSON:", err)
|
||||
logx.Error("Error marshalling map to JSON:", err)
|
||||
return err
|
||||
}
|
||||
err = jsoniter.Unmarshal(jsonData, &target) // 将 JSON 字节切片解析到结构体中
|
||||
if err != nil {
|
||||
Logger.Error("Error unmarshalling JSON:", err)
|
||||
logx.Error("Error unmarshalling JSON:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -503,14 +504,14 @@ func MapToStruct(data map[string]interface{}, target interface{}) error {
|
||||
func JsonStringToStruct(jsonStr string, v interface{}) bool {
|
||||
// 1. 校验入参:确保v是指针类型(否则json.Unmarshal无法工作)
|
||||
if v == nil {
|
||||
Logger.Error("传入的结构体指针不能为nil")
|
||||
logx.Error("传入的结构体指针不能为nil")
|
||||
return false
|
||||
}
|
||||
|
||||
// 2. 将JSON字符串转为字节数组,执行解析
|
||||
err := jsoniter.Unmarshal([]byte(jsonStr), v)
|
||||
if err != nil {
|
||||
Logger.Error("JSON解析失败: ", err, jsonStr)
|
||||
logx.Error("JSON解析失败: ", err, jsonStr)
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -14,7 +14,6 @@ message Response {
|
||||
message SfResponse {
|
||||
string return_code = 1;
|
||||
string return_msg = 2;
|
||||
string return_status = 3;
|
||||
}
|
||||
|
||||
message IdResponse {
|
||||
|
||||
@@ -86,7 +86,6 @@ type SfResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ReturnCode string `protobuf:"bytes,1,opt,name=return_code,json=returnCode,proto3" json:"return_code,omitempty"`
|
||||
ReturnMsg string `protobuf:"bytes,2,opt,name=return_msg,json=returnMsg,proto3" json:"return_msg,omitempty"`
|
||||
ReturnStatus string `protobuf:"bytes,3,opt,name=return_status,json=returnStatus,proto3" json:"return_status,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -135,13 +134,6 @@ func (x *SfResponse) GetReturnMsg() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SfResponse) GetReturnStatus() string {
|
||||
if x != nil {
|
||||
return x.ReturnStatus
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type IdResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
@@ -854,14 +846,13 @@ const file_express_express_proto_rawDesc = "" +
|
||||
"\bResponse\x12\x12\n" +
|
||||
"\x04code\x18\x01 \x01(\x05R\x04code\x12\x10\n" +
|
||||
"\x03msg\x18\x02 \x01(\tR\x03msg\x12\x12\n" +
|
||||
"\x04data\x18\x03 \x01(\tR\x04data\"q\n" +
|
||||
"\x04data\x18\x03 \x01(\tR\x04data\"L\n" +
|
||||
"\n" +
|
||||
"SfResponse\x12\x1f\n" +
|
||||
"\vreturn_code\x18\x01 \x01(\tR\n" +
|
||||
"returnCode\x12\x1d\n" +
|
||||
"\n" +
|
||||
"return_msg\x18\x02 \x01(\tR\treturnMsg\x12#\n" +
|
||||
"\rreturn_status\x18\x03 \x01(\tR\freturnStatus\"\x1c\n" +
|
||||
"return_msg\x18\x02 \x01(\tR\treturnMsg\"\x1c\n" +
|
||||
"\n" +
|
||||
"IdResponse\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\"\x0e\n" +
|
||||
|
||||
@@ -2,10 +2,15 @@ package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"lone-services/pkg/modelbase"
|
||||
"lone-services/pkg/utils"
|
||||
|
||||
"lone-services/rpc/express/pb"
|
||||
order "lone-services/rpc/order/pb"
|
||||
"lone-services/services/express/internal/dao"
|
||||
"lone-services/services/express/internal/model"
|
||||
"lone-services/services/express/internal/svc"
|
||||
"lone-services/services/express/internal/transit"
|
||||
"strconv"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -26,7 +31,181 @@ func NewExpressSfBackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Exp
|
||||
}
|
||||
|
||||
func (l *ExpressSfBackLogic) ExpressSfBack(in *express.EmtpyRequest) (*express.SfResponse, error) {
|
||||
info := utils.GetHeaderAndBody(l.ctx)
|
||||
l.Logger.Error("ExpressSfBack", "info", string(info.Body))
|
||||
return &express.SfResponse{}, nil
|
||||
body := utils.GetBody(l.ctx)
|
||||
ret := express.SfResponse{
|
||||
ReturnCode: "1000",
|
||||
ReturnMsg: "系统异常",
|
||||
}
|
||||
if body == utils.StringEmpty {
|
||||
return &ret, nil
|
||||
}
|
||||
l.Logger.Info("SF back data:", body)
|
||||
|
||||
ok := l.Back(body)
|
||||
if ok {
|
||||
ret.ReturnCode = "000"
|
||||
ret.ReturnMsg = "成功"
|
||||
}
|
||||
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
func (l *ExpressSfBackLogic) Back(body string) bool {
|
||||
var result map[string]interface{}
|
||||
ok := utils.JsonStringToStruct(body, &result)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
bodyData, ok := result["Body"].(map[string]interface{})
|
||||
if !ok {
|
||||
l.Logger.Error("back Body interface error ")
|
||||
return false
|
||||
}
|
||||
waybillRoute, ok := bodyData["WaybillRoute"].([]interface{})
|
||||
if !ok || len(waybillRoute) < utils.NumberOne {
|
||||
l.Logger.Error("back body WaybillRoute error empty")
|
||||
return false
|
||||
}
|
||||
items := make(map[string][]dao.ExpressQueryItems)
|
||||
var orderIds []string
|
||||
end := make(map[string]bool)
|
||||
|
||||
for i := utils.NumberZero; i < len(waybillRoute); i++ {
|
||||
route := waybillRoute[i].(map[string]interface{})
|
||||
if _, ok := route["orderid"].(string); !ok {
|
||||
l.Logger.Error("back body WaybillRoute error empty")
|
||||
continue
|
||||
}
|
||||
orderId := route["orderid"].(string)
|
||||
orderIds = append(orderIds, orderId)
|
||||
tmp := dao.ExpressQueryItems{
|
||||
AcceptAddress: route["acceptAddress"].(string),
|
||||
AcceptTime: route["acceptTime"].(string),
|
||||
OpCode: route["opCode"].(string),
|
||||
Remark: route["remark"].(string),
|
||||
}
|
||||
tmp.LastMd5 = utils.MD5Encrypt(tmp.OpCode + tmp.AcceptTime + tmp.Remark)
|
||||
if _, okk := route["secondaryStatusCode"]; okk {
|
||||
tmp.SecondaryStatusCode = route["secondaryStatusCode"].(string)
|
||||
}
|
||||
if _, okk := route["secondaryStatusName"]; okk {
|
||||
tmp.SecondaryStatusName = route["secondaryStatusName"].(string)
|
||||
}
|
||||
if _, okk := route["firstStatusCode"]; okk {
|
||||
tmp.FirstStatusCode = route["firstStatusCode"].(string)
|
||||
}
|
||||
if _, okk := route["firstStatusName"]; okk {
|
||||
tmp.FirstStatusName = route["firstStatusName"].(string)
|
||||
}
|
||||
|
||||
items[orderId] = append(items[orderId], tmp)
|
||||
end[orderId] = false
|
||||
if ok := transit.SfSingedCodeMap[tmp.OpCode]; ok {
|
||||
end[orderId] = true
|
||||
}
|
||||
}
|
||||
if len(orderIds) < utils.NumberOne {
|
||||
l.Logger.Error("no ", orderIds)
|
||||
return false
|
||||
}
|
||||
orderIds = utils.UniqueStr(orderIds)
|
||||
|
||||
modelObj := model.DeliveryOrderModel{}.Init()
|
||||
|
||||
w := modelbase.Params{In: map[string][]string{
|
||||
"order_sn": orderIds,
|
||||
}}
|
||||
var info []dao.DeliveryOrderUpTransit
|
||||
err := modelObj.Items(w, &info)
|
||||
if err != nil {
|
||||
utils.Logger.Error("get deliverGoods error ", err)
|
||||
return false
|
||||
}
|
||||
if len(info) < utils.NumberOne {
|
||||
return false
|
||||
}
|
||||
modelObj.Begin()
|
||||
|
||||
for _, item := range info {
|
||||
if item.Status == dao.SendStatusOver {
|
||||
continue
|
||||
}
|
||||
if end[item.OrderSn] {
|
||||
item.Status = dao.SendStatusOver
|
||||
item.ChangeEstimatedTime = utils.StatusFail
|
||||
|
||||
w = modelbase.Params{Eq: map[string]string{"delivery_order_id": strconv.Itoa(item.Id)}}
|
||||
expEdit := dao.DeliveryExpStatus{
|
||||
Status: utils.StatusOk,
|
||||
}
|
||||
_, err = model.DeliveryOrderExpModel{}.Init().Edit(w, &expEdit)
|
||||
if err != nil {
|
||||
l.Logger.Error("back set deliver exp error ", err)
|
||||
modelObj.Rollback()
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if v, iOk := items[item.OrderSn]; iOk {
|
||||
var old []dao.ExpressQueryItems
|
||||
if utils.JsonStringToStruct(item.TransitQuery, &old) {
|
||||
l.Logger.Error("back set deliver transit error: ", item.TransitQuery)
|
||||
}
|
||||
oldMap := l.getSfMap(old)
|
||||
for i := len(v) - 1; i >= utils.NumberZero; i-- {
|
||||
if cOk := oldMap[v[i].LastMd5]; !cOk {
|
||||
old = append(old, v[i])
|
||||
}
|
||||
}
|
||||
item.TransitQuery = utils.StructToJson(old)
|
||||
w := modelbase.Params{Eq: map[string]string{"id": strconv.Itoa(item.Id)}}
|
||||
if end[item.OrderSn] {
|
||||
item.SignTime = utils.Now()
|
||||
}
|
||||
_, err = modelObj.Edit(w, &item)
|
||||
if err != nil {
|
||||
l.Logger.Error("back set deliver info error ", err)
|
||||
modelObj.Rollback()
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if end[item.OrderSn] {
|
||||
if item.Type == dao.DeliveryTypeOrder {
|
||||
cli, err := svc.GetRpcClient(l.svcCtx.OrderSvcName)
|
||||
if err != nil {
|
||||
modelObj.Rollback()
|
||||
logx.Errorf("get order err: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
client := order.NewOrderClient(cli.Conn())
|
||||
update := order.UpdateOrderDeliverStatusRequest{
|
||||
Id: item.ObjId,
|
||||
DeliverStatus: int32(item.Status),
|
||||
SignTime: utils.Now().GoString(),
|
||||
}
|
||||
_, err = client.UpdateOrderDeliverStatus(l.ctx, &update)
|
||||
if err != nil {
|
||||
modelObj.Rollback()
|
||||
logx.Errorf("get order err: %v", err)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
modelObj.Commit()
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
func (l *ExpressSfBackLogic) getSfMap(items []dao.ExpressQueryItems) map[string]bool {
|
||||
ret := make(map[string]bool)
|
||||
for _, item := range items {
|
||||
ret[item.LastMd5] = true
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user