增加同步物流模块
修改现有架构,改为分模块( 简易版)
This commit is contained in:
1 parent
15e11618c9
commit
fa03add754
120 files changed
+9438
-299
No files matched your search
@@ -0,0 +1,253 @@
|
||||
using MAX.Core.Commons;
|
||||
using MAX.Core.Cryptography;
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Helpers;
|
||||
using MAX.Core.Logger;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Store.VirtualLogistics.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace Store.VirtualLogistics.Apis;
|
||||
|
||||
public class VirtualLogisticsApi : ISingletonDependency
|
||||
{
|
||||
private const string Host = "https://yuncang.df8899.top";
|
||||
private readonly ILoggerFacade _logger;
|
||||
protected string UserName = "18756025201";
|
||||
protected string Passworkd = "aj123456";
|
||||
public VirtualLogisticsApi(ILoggerFacade logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
public string GetSign(long unix)
|
||||
{
|
||||
string pwd = MD5Helper.Md5_Lower32(MD5Helper.Md5_Lower32(Passworkd));
|
||||
string s = $"{UserName}{pwd}{unix}";
|
||||
string sign = MD5Helper.Md5_Lower32(s);
|
||||
return sign;
|
||||
}
|
||||
|
||||
public List<ExpressItem> GetExpressList()
|
||||
{
|
||||
var ret = ServerRequest<List<ExpressItem>>(new HttpItem
|
||||
{
|
||||
URL = "/api/lipin/list",
|
||||
Method = MethodType.Post
|
||||
});
|
||||
return ret.Data;
|
||||
}
|
||||
public UserMoney GetUserMoney()
|
||||
{
|
||||
var ret = ServerRequest<UserMoney>(new HttpItem
|
||||
{
|
||||
URL = "/api/user/index",
|
||||
Method = MethodType.Post
|
||||
});
|
||||
return ret.Data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取仓库列表及价格
|
||||
/// </summary>
|
||||
public List<CangItem> GetCangList()
|
||||
{
|
||||
var ret = ServerRequest<List<CangItem>>(new HttpItem
|
||||
{
|
||||
URL = "/api/lipin/cang",
|
||||
Method = MethodType.Post
|
||||
});
|
||||
return ret.Data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取礼品列表及价格
|
||||
/// </summary>
|
||||
/// <param name="kuaidiId">快递ID,可选</param>
|
||||
public List<GoodsItem> GetGoodsList(string kuaidiId = null)
|
||||
{
|
||||
var ret = ServerRequest<List<GoodsItem>>(new HttpItem
|
||||
{
|
||||
URL = "/api/lipin/goods",
|
||||
Method = MethodType.Post
|
||||
});
|
||||
return ret.Data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 购买快递
|
||||
/// </summary>
|
||||
public Result<List<BuyResultItem>> Buy(BuyRequest request)
|
||||
{
|
||||
var res = ServerRequest<Dictionary<string, BuyResultItem>>(new HttpItem
|
||||
{
|
||||
URL = $"/api/lipin/buy",
|
||||
Postdata = JsonConvert.SerializeObject(request),
|
||||
Method = MethodType.Post,
|
||||
ContentType = "application/json",
|
||||
});
|
||||
var ret = new Result<List<BuyResultItem>>()
|
||||
{
|
||||
Code = res.Code,
|
||||
Success = res.Success,
|
||||
Msg = res.Msg,
|
||||
};
|
||||
if (res.Success)
|
||||
{
|
||||
ret.Data = res.Data.Values.ToList();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/// <summary>
|
||||
/// 查询快递订单信息及状态
|
||||
/// </summary>
|
||||
/// <param name="query">查询参数</param>
|
||||
/// <returns></returns>
|
||||
public Result<List<OrderStatusResultItem>> QueryOrderStatus(string[] orderIds)
|
||||
{
|
||||
var res = ServerRequest<Dictionary<string, OrderStatusResultItem>>(new HttpItem
|
||||
{
|
||||
URL = "/api/lipin/status",
|
||||
Postdata = JsonConvert.SerializeObject(new
|
||||
{
|
||||
order_sn = orderIds
|
||||
}),
|
||||
Method = MethodType.Post
|
||||
});
|
||||
var ret = new Result<List<OrderStatusResultItem>>()
|
||||
{
|
||||
Code = res.Code,
|
||||
Success = res.Success,
|
||||
Msg = res.Msg,
|
||||
};
|
||||
if (res.Success)
|
||||
{
|
||||
ret.Data = res.Data.Values.ToList();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/// <summary>
|
||||
/// 上传取件码
|
||||
/// </summary>
|
||||
public Result<List<PickupResultItem>> UploadPickup(List<PickupItem> data)
|
||||
{
|
||||
string postdata = $"username={UserName}&data={WebUtility.UrlEncode(Serialize(data))}";
|
||||
return ServerRequest<List<PickupResultItem>>(new HttpItem
|
||||
{
|
||||
URL = "/api/lipin/uploadPickup",
|
||||
Postdata = postdata,
|
||||
Method = MethodType.Post
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用蛇形命名序列化对象,忽略空值,用于拼接表单参数
|
||||
/// </summary>
|
||||
private static string Serialize(object obj)
|
||||
{
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new SnakeCaseNamingStrategy()
|
||||
},
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
return JsonConvert.SerializeObject(obj, settings);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 服务器请求
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public Result<T> ServerRequest<T>(HttpItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!item.URL.StartsWith("http"))
|
||||
{
|
||||
item.URL = Host + item.URL;
|
||||
}
|
||||
item.Encoding = Encoding.UTF8;
|
||||
|
||||
item.ProxyIp = "127.0.0.1:8080";
|
||||
|
||||
long unix = DateHelper.GetCurrentUnixTimestampInSeconds();
|
||||
|
||||
string sign = GetSign(unix);
|
||||
HttpHelper http = new HttpHelper();
|
||||
item.ContentType = "application/json";
|
||||
var auth = new
|
||||
{
|
||||
username = UserName,
|
||||
sid = unix,
|
||||
sign = sign,
|
||||
};
|
||||
if (string.IsNullOrWhiteSpace(item.Postdata))
|
||||
{
|
||||
item.Postdata = JsonConvert.SerializeObject(auth);
|
||||
}
|
||||
else
|
||||
{
|
||||
var obj = JObject.Parse(item.Postdata);
|
||||
obj["username"] = auth.username;
|
||||
obj["sid"] = auth.sid;
|
||||
obj["sign"] = auth.sign;
|
||||
item.Postdata = obj.ToString();
|
||||
}
|
||||
if (item.ContentType != "application/json")
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.Postdata))
|
||||
{
|
||||
if (item.Postdata.StartsWith("&") == false) item.Postdata = "&" + item.Postdata;
|
||||
}
|
||||
item.Postdata = $"username={UserName}&sid={unix}&sign={sign}" + item.Postdata;
|
||||
}
|
||||
item.PostDataType = PostDataType.String;
|
||||
item.PostEncoding = Encoding.UTF8;
|
||||
HttpResult result = http.GetHtml(item);
|
||||
if (result.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new SnakeCaseNamingStrategy()
|
||||
}
|
||||
};
|
||||
var res = JsonConvert.DeserializeObject<Result<JToken>>(result.Html, settings);
|
||||
if (res.Code == 0)
|
||||
{
|
||||
return new Result<T>
|
||||
{
|
||||
Success = true,
|
||||
Code = res.Code,
|
||||
Msg = res.Msg,
|
||||
Data = res.Data.ToObject<T>(JsonSerializer.CreateDefault(settings))
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"{res.Msg}:{res.Data["error"]?.ToString() ?? ""}");
|
||||
}
|
||||
}
|
||||
throw new Exception(result.Html);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex, $"VirtualLogisticsApi:{item.URL}\n{item.Postdata}");
|
||||
return new Result<T>
|
||||
{
|
||||
Code = -1,
|
||||
Msg = ex.Message,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
using Store.Framework.Base;
|
||||
using Store.Framework.Models;
|
||||
using Store.VirtualLogistics.Apis;
|
||||
using Store.VirtualLogistics.Entitys;
|
||||
using Store.VirtualLogistics.Models;
|
||||
using Store.VirtualLogistics.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace Store.VirtualLogistics.Controllers;
|
||||
|
||||
[RoutePrefix("wxxd_vlc")]
|
||||
[Route("{action}")]
|
||||
public class LogisticsController : ApiControllerBase
|
||||
{
|
||||
private readonly VirtualLogisticsService _logisticsService;
|
||||
|
||||
public LogisticsController(VirtualLogisticsService logisticsService)
|
||||
{
|
||||
_logisticsService = logisticsService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取账户余额
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
[HttpGet]
|
||||
public IHttpActionResult GetUserMoney()
|
||||
{
|
||||
ApiResultBase ret = ApiResult.Fail();
|
||||
try
|
||||
{
|
||||
var money = _logisticsService.GetUserMoney();
|
||||
ret = ApiResult.Success(money);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ret = ApiResult.Fail(ex.Message);
|
||||
}
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取快递列表
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public IHttpActionResult GetExpressList()
|
||||
{
|
||||
try
|
||||
{
|
||||
var list = _logisticsService.GetExpressList();
|
||||
return Ok(ApiResult.Success(list));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(ApiResult.Fail(ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取仓库列表及价格
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public IHttpActionResult GetCangList()
|
||||
{
|
||||
try
|
||||
{
|
||||
var list = _logisticsService.GetCangList();
|
||||
return Ok(ApiResult.Success(list));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(ApiResult.Fail(ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取礼品列表及价格
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public IHttpActionResult GetGoodsList(string kuaidiId = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var list = _logisticsService.GetGoodsList(kuaidiId);
|
||||
return Ok(ApiResult.Success(list));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(ApiResult.Fail(ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 购买快递
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public IHttpActionResult Buy(string orderId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = _logisticsService.Buy(orderId, "");
|
||||
return Ok(ApiResult.Success(result));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(ApiResult.Fail(ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传取件码
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public IHttpActionResult UploadPickup(List<PickupItem> data)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = _logisticsService.UploadPickup(data);
|
||||
return Ok(result.Success
|
||||
? ApiResult<List<PickupResultItem>>.Success(result.Data, result.Msg)
|
||||
: ApiResult<List<PickupResultItem>>.Fail(result.Msg, ResultCode.BusinessError, result.Data));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(ApiResult.Fail(ex.Message));
|
||||
}
|
||||
}
|
||||
[HttpPost]
|
||||
public IHttpActionResult GetSyncLogistics(string orderId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = _logisticsService.GetSyncLogistics(orderId);
|
||||
return Ok(ApiResult.Success(result));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(ApiResult.Fail(ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.VirtualLogistics.Entitys;
|
||||
|
||||
/// <summary>
|
||||
/// 同步物流记录表
|
||||
/// </summary>
|
||||
[Table(Name = "wxxd.yh_sync_logistics")]
|
||||
public class YhSyncLogisticsEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// id
|
||||
/// </summary>
|
||||
[Column(Name = "id", IsPrimary = true, IsIdentity = true)]
|
||||
[JsonIgnore]
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单id
|
||||
/// </summary>
|
||||
[Column(Name = "order_id")]
|
||||
public string OrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 同步物流编号
|
||||
/// </summary>
|
||||
[Column(Name = "tracking_number")]
|
||||
public string TrackingNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原始物流编号
|
||||
/// </summary>
|
||||
[Column(Name = "source_tracking_number")]
|
||||
public string SourceTrackingNumber { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.VirtualLogistics.Models;
|
||||
|
||||
public class BuyRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 接入账号:本站注册账号
|
||||
/// </summary>
|
||||
[JsonProperty("username")]
|
||||
public string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前时间戳:1574769204
|
||||
/// </summary>
|
||||
[JsonProperty("sid")]
|
||||
public string Sid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[JsonProperty("sign")]
|
||||
public string Sign { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 快递ID
|
||||
/// </summary>
|
||||
[JsonProperty("kuaidi_id")]
|
||||
public string KuaidiId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品ID
|
||||
/// </summary>
|
||||
[JsonProperty("goods_id")]
|
||||
public string GoodsId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仓库ID
|
||||
/// </summary>
|
||||
[JsonProperty("cang_id")]
|
||||
public string CangId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 平台,1淘宝 2拼多多 3京东 4抖音 5快手 6视频号 7阿里 8小红书 9淘工厂
|
||||
/// </summary>
|
||||
[JsonProperty("platform")]
|
||||
public int Platform { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否授权下单,1是0否
|
||||
/// </summary>
|
||||
[JsonProperty("auth")]
|
||||
public int Auth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发货人
|
||||
/// </summary>
|
||||
[JsonProperty("send_name")]
|
||||
public string SendName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发货人手机
|
||||
/// </summary>
|
||||
[JsonProperty("send_mobile")]
|
||||
public string SendMobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发货人省份
|
||||
/// </summary>
|
||||
[JsonProperty("send_province")]
|
||||
public string SendProvince { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发货人城市
|
||||
/// </summary>
|
||||
[JsonProperty("send_city")]
|
||||
public string SendCity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发货人区/县/镇
|
||||
/// </summary>
|
||||
[JsonProperty("send_district")]
|
||||
public string SendDistrict { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发货人详细地址
|
||||
/// </summary>
|
||||
[JsonProperty("send_address")]
|
||||
public string SendAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货地址列表,每次可传1000条;圆通实时包,每次最多100个
|
||||
/// </summary>
|
||||
[JsonProperty("rec_list")]
|
||||
public List<RecItem> RecList { get; set; } = new List<RecItem>();
|
||||
}
|
||||
public class RecItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 唯一订单号,生成一个不重复的字符串,字符串长度为16~40
|
||||
/// </summary>
|
||||
[JsonProperty("order_sn")]
|
||||
public string OrderSn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货人
|
||||
/// </summary>
|
||||
[JsonProperty("rec_name")]
|
||||
public string RecName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货人手机
|
||||
/// </summary>
|
||||
[JsonProperty("rec_mobile")]
|
||||
public string RecMobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货人省份
|
||||
/// </summary>
|
||||
[JsonProperty("rec_province")]
|
||||
public string RecProvince { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货人城市
|
||||
/// </summary>
|
||||
[JsonProperty("rec_city")]
|
||||
public string RecCity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货人区/县/镇
|
||||
/// </summary>
|
||||
[JsonProperty("rec_district")]
|
||||
public string RecDistrict { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货人详细地址
|
||||
/// </summary>
|
||||
[JsonProperty("rec_address")]
|
||||
public string RecAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 授权下单必填,淘宝或拼多多等第三方平台订单号
|
||||
/// </summary>
|
||||
[JsonProperty("shop_order")]
|
||||
public string ShopOrder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 无货源必填,补发单号
|
||||
/// </summary>
|
||||
[JsonProperty("other_kuaidi_sn")]
|
||||
public string OtherKuaidiSn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 店铺名称
|
||||
/// </summary>
|
||||
[JsonProperty("shop_name")]
|
||||
public string ShopName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 淘宝授权发货必填
|
||||
/// </summary>
|
||||
[JsonProperty("oaid")]
|
||||
public string Oaid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货详细地址密文,拼多多、抖音授权发货必填
|
||||
/// </summary>
|
||||
[JsonProperty("rec_address_encrypt")]
|
||||
public string RecAddressEncrypt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货人姓名密文,拼多多、抖音授权发货必填
|
||||
/// </summary>
|
||||
[JsonProperty("rec_name_encrypt")]
|
||||
public string RecNameEncrypt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货人手机密文,拼多多、抖音授权发货必填
|
||||
/// </summary>
|
||||
[JsonProperty("rec_phone_encrypt")]
|
||||
public string RecPhoneEncrypt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货人手机号密文,京东授权发货必填
|
||||
/// </summary>
|
||||
[JsonProperty("desen_mobile")]
|
||||
public string DesenMobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收货人手机号密文,京东授权发货必填
|
||||
/// </summary>
|
||||
[JsonProperty("desen_telephone")]
|
||||
public string DesenTelephone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单店铺ID,快手授权发货必填
|
||||
/// </summary>
|
||||
[JsonProperty("seller_open_id")]
|
||||
public string SellerOpenId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单店铺昵称,快手授权发货必填
|
||||
/// </summary>
|
||||
[JsonProperty("seller_nick")]
|
||||
public string SellerNick { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 授权发货必填
|
||||
/// </summary>
|
||||
[JsonProperty("encrypt_datas")]
|
||||
public EncryptDatas EncryptDatas { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 编码,供应商代发时必填
|
||||
/// </summary>
|
||||
[JsonProperty("ewaybill_order_code")]
|
||||
public string EwaybillOrderCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展参数,视频号供应商代发时必填
|
||||
/// </summary>
|
||||
[JsonProperty("extend_params")]
|
||||
public ExtendParams ExtendParams { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class EncryptDatas
|
||||
{
|
||||
/// <summary>
|
||||
/// 供应商订单ID,视频号供应商代发时必填
|
||||
/// </summary>
|
||||
[JsonProperty("ds_order_id")]
|
||||
public string DsOrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 视频号必填,自研时传店铺 appId,供应商传相应该的值
|
||||
/// </summary>
|
||||
[JsonProperty("from_shop_code")]
|
||||
public string FromShopCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单商品sku_id,视频号必填
|
||||
/// </summary>
|
||||
[JsonProperty("sku_id")]
|
||||
public string SkuId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单商品id,视频号必填
|
||||
/// </summary>
|
||||
[JsonProperty("product_id")]
|
||||
public string ProductId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单商品数量,视频号必填
|
||||
/// </summary>
|
||||
[JsonProperty("sku_cnt")]
|
||||
public string SkuCnt { get; set; }
|
||||
}
|
||||
public class ExtendParams
|
||||
{
|
||||
/// <summary>
|
||||
/// 供应商订单ID,视频号供应商代发时必填
|
||||
/// </summary>
|
||||
[JsonProperty("token")]
|
||||
public string Token { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 供应商编码,取决上家快递使用供应商,视频号供应商代发时必填
|
||||
/// </summary>
|
||||
[JsonProperty("api")]
|
||||
public string Api { get; set; }
|
||||
/// <summary>
|
||||
/// 供应商订单ID,视频号供应商代发时必填
|
||||
/// </summary>
|
||||
[JsonProperty("ds_order_id")]
|
||||
public string DsOrderId { get; set; }
|
||||
}
|
||||
public class BuyResultItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 原传入的唯一订单号
|
||||
/// </summary>
|
||||
public string OrderSn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 快递单号
|
||||
/// </summary>
|
||||
public string KuaidiSn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 快递状态:2待揽件 3已揽件
|
||||
/// </summary>
|
||||
public string Status { get; set; }
|
||||
|
||||
public string OtherKuaidiSn { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.VirtualLogistics.Models;
|
||||
|
||||
public class CangItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 仓库ID
|
||||
/// </summary>
|
||||
public string CangId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 省
|
||||
/// </summary>
|
||||
public string SendProvince { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 市
|
||||
/// </summary>
|
||||
public string SendCity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区
|
||||
/// </summary>
|
||||
public string SendDistrict { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址
|
||||
/// </summary>
|
||||
public string SendAddress { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.VirtualLogistics.Models;
|
||||
|
||||
public class ExpressItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 快递名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 快递价格
|
||||
/// </summary>
|
||||
public string Price { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 快递说明
|
||||
/// </summary>
|
||||
public string Tips { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上次交单时间,实时快递忽略;该字段一般用于快递同步发货判定
|
||||
/// </summary>
|
||||
public string ExportTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否允许取消 1是 0否
|
||||
/// </summary>
|
||||
public string IsCancel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否淘宝专用 1是 0否
|
||||
/// </summary>
|
||||
public string IsTb { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否天猫专用 1是 0否
|
||||
/// </summary>
|
||||
public string IsTm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否阿里专用 1是 0否
|
||||
/// </summary>
|
||||
public string IsAl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否京东专用 1是 0否
|
||||
/// </summary>
|
||||
public string IsJd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否拼多多专用 1是 0否
|
||||
/// </summary>
|
||||
public string IsPdd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否菜鸟面单、无界面单、电子面单 1是 0否
|
||||
/// </summary>
|
||||
public string IsDz { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要上传单号 1是 0否
|
||||
/// </summary>
|
||||
public string IsZy { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.VirtualLogistics.Models;
|
||||
|
||||
public class GoodsItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 礼品ID
|
||||
/// </summary>
|
||||
public string GoodsId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 礼品名称
|
||||
/// </summary>
|
||||
public string GoodsName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 礼品重量
|
||||
/// </summary>
|
||||
public string GoodsWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 礼品价格
|
||||
/// </summary>
|
||||
public string Price { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 礼品图片
|
||||
/// </summary>
|
||||
public string GoodsPic { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.VirtualLogistics.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 查询快递订单信息及状态 - 请求参数
|
||||
/// </summary>
|
||||
public class OrderStatusQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询唯一订单号(支持多个)
|
||||
/// </summary>
|
||||
public List<string> order_sn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 查询唯一订单号(支持多个)
|
||||
/// </summary>
|
||||
public List<string> kuaidi_sn { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 查询快递订单信息及状态 - 响应结果项
|
||||
/// </summary>
|
||||
public class OrderStatusResultItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 原传入唯一订单号
|
||||
/// </summary>
|
||||
public string OrderSn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 快递单号
|
||||
/// </summary>
|
||||
public string KuaidiSn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 快递状态:2待揽件 3已揽件
|
||||
/// </summary>
|
||||
public string Status { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.VirtualLogistics.Models;
|
||||
|
||||
public class PickupItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 上家快递单号
|
||||
/// </summary>
|
||||
public string BufaSn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 取件码
|
||||
/// </summary>
|
||||
public string PickupCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 驿站地址
|
||||
/// </summary>
|
||||
public string Address { get; set; }
|
||||
}
|
||||
|
||||
public class PickupResultItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 上家单号
|
||||
/// </summary>
|
||||
public string BufaSn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否成功
|
||||
/// </summary>
|
||||
public bool Success { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.VirtualLogistics.Models;
|
||||
|
||||
public class UserMoney
|
||||
{
|
||||
public decimal Money { get; set; }
|
||||
public decimal ExpendMoney { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.VirtualLogistics.Services;
|
||||
|
||||
internal static class RandomNameHelper
|
||||
{
|
||||
private static readonly string[] Surnames =
|
||||
{
|
||||
"赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈",
|
||||
"褚", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许",
|
||||
"何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏",
|
||||
"陶", "姜", "戚", "谢", "邹", "喻", "柏", "水", "窦", "章",
|
||||
"苏", "潘", "葛", "奚", "范", "彭", "郎", "鲁", "韦", "昌"
|
||||
};
|
||||
|
||||
private static readonly string[] Titles = { "先生", "女士" };
|
||||
|
||||
private static readonly Random _random = new Random();
|
||||
|
||||
/// <summary>
|
||||
/// 随机获取 姓+先生/女士
|
||||
/// </summary>
|
||||
public static string GetRandomName()
|
||||
{
|
||||
var surname = Surnames[_random.Next(Surnames.Length)];
|
||||
var title = Titles[_random.Next(Titles.Length)];
|
||||
return $"{surname}{title}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量随机获取
|
||||
/// </summary>
|
||||
public static List<string> GetRandomNames(int count)
|
||||
{
|
||||
var list = new List<string>(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
list.Add(GetRandomName());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
using MAX.Core.Commons;
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Logger;
|
||||
using Store.Contracts.Order.Entitys;
|
||||
using Store.VirtualLogistics.Apis;
|
||||
using Store.VirtualLogistics.Entitys;
|
||||
using Store.VirtualLogistics.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.VirtualLogistics.Services;
|
||||
|
||||
|
||||
public class VirtualLogisticsService : ITransientDependency
|
||||
{
|
||||
private IFreeSql _freeSql;
|
||||
private readonly ILoggerFacade _logger;
|
||||
private readonly VirtualLogisticsApi _api;
|
||||
|
||||
public VirtualLogisticsService(VirtualLogisticsApi api, IFreeSql freeSql, ILoggerFacade logger)
|
||||
{
|
||||
_freeSql = freeSql ?? throw new ArgumentNullException(nameof(freeSql));
|
||||
_logger = logger;
|
||||
_api = api;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取账户余额
|
||||
/// </summary>
|
||||
public decimal GetUserMoney()
|
||||
{
|
||||
var user = _api.GetUserMoney();
|
||||
return user.Money;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取快递列表
|
||||
/// </summary>
|
||||
public List<ExpressItem> GetExpressList()
|
||||
{
|
||||
return _api.GetExpressList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取仓库列表及价格
|
||||
/// </summary>
|
||||
public List<CangItem> GetCangList()
|
||||
{
|
||||
return _api.GetCangList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取礼品列表及价格
|
||||
/// </summary>
|
||||
/// <param name="kuaidiId">快递ID,可选</param>
|
||||
public List<GoodsItem> GetGoodsList(string kuaidiId = null)
|
||||
{
|
||||
return _api.GetGoodsList(kuaidiId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 购买快递
|
||||
/// </summary>
|
||||
public List<YhSyncLogisticsEntity> Buy(string orderId, string ds_orderId)
|
||||
{
|
||||
var item = _freeSql.Select<OrderPddBuyerOrderEntity>()
|
||||
.Where(a => a.OrderSn == orderId)
|
||||
.First();
|
||||
if (item == null) throw new Exception("错误的订单号");
|
||||
|
||||
var w_order = _freeSql.Select<WeiOrderEntity>()
|
||||
.Where(a => a.OrderId == item.WxOrderId)
|
||||
.First();
|
||||
|
||||
if (w_order == null) throw new Exception("错误的订单号");
|
||||
var productItem = _freeSql.Select<WeiOrderItemEntity>()
|
||||
.Where(a => a.OrderId == w_order.OrderId)
|
||||
.First();
|
||||
if (productItem == null) throw new Exception("错误的订单详情号");
|
||||
|
||||
BuyRequest request = new BuyRequest()
|
||||
{
|
||||
KuaidiId = "874",
|
||||
GoodsId = "8473",
|
||||
CangId = "914",
|
||||
Platform = 6,
|
||||
Auth = 1,
|
||||
SendName = RandomNameHelper.GetRandomName(),
|
||||
SendMobile = "13024622251",
|
||||
SendProvince = "上海市",
|
||||
SendCity = "上海市",
|
||||
SendDistrict = "普陀区",
|
||||
SendAddress = "真如镇街道真北路2653弄F区808号楼",
|
||||
RecList = [
|
||||
new RecItem
|
||||
{
|
||||
OrderSn = orderId,
|
||||
RecName = w_order.UserName,
|
||||
RecMobile = w_order.TelNumber,
|
||||
RecProvince = w_order.ProvinceName,
|
||||
RecCity = w_order.CityName,
|
||||
RecDistrict = w_order.CountyName,
|
||||
RecAddress = w_order.DetailInfo,
|
||||
EncryptDatas=new EncryptDatas
|
||||
{
|
||||
DsOrderId=ds_orderId,
|
||||
SkuId = productItem.SkuId,
|
||||
ProductId = productItem.ProductId,
|
||||
SkuCnt = productItem.SkuCnt.ToString(),
|
||||
},
|
||||
OtherKuaidiSn= "6738192431"//item.TrackingNumber,
|
||||
|
||||
}
|
||||
]
|
||||
};
|
||||
Result<List<BuyResultItem>> ret = _api.Buy(request);
|
||||
if (ret.Success == false)
|
||||
{
|
||||
_logger.Error($"购买同步单错误:{ret.Msg}");
|
||||
throw new Exception("购买同步单失败");
|
||||
}
|
||||
|
||||
|
||||
List<YhSyncLogisticsEntity> yhSyncs = new List<YhSyncLogisticsEntity>();
|
||||
foreach (var sync in ret.Data)
|
||||
{
|
||||
yhSyncs.Add(new YhSyncLogisticsEntity
|
||||
{
|
||||
OrderId = sync.OrderSn,
|
||||
TrackingNumber = sync.KuaidiSn,
|
||||
SourceTrackingNumber = sync.OtherKuaidiSn
|
||||
});
|
||||
}
|
||||
|
||||
var count = _freeSql.Insert<YhSyncLogisticsEntity>(yhSyncs).ExecuteAffrows();
|
||||
if (count != yhSyncs.Count)
|
||||
{
|
||||
_logger.Error("购买同步单提交到数据库错误");
|
||||
throw new Exception("记录同步单失败");
|
||||
}
|
||||
return yhSyncs;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传取件码
|
||||
/// </summary>
|
||||
public Result<List<PickupResultItem>> UploadPickup(List<PickupItem> data)
|
||||
{
|
||||
return _api.UploadPickup(data);
|
||||
}
|
||||
|
||||
public YhSyncLogisticsEntity GetSyncLogistics(string orderId)
|
||||
{
|
||||
var item = _freeSql.Select<YhSyncLogisticsEntity>()
|
||||
.Where(a => a.OrderId == orderId).First();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.3.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MAX.Core\MAX.Core.csproj" />
|
||||
<ProjectReference Include="..\Store.Contracts\Store.Contracts.csproj" />
|
||||
<ProjectReference Include="..\Store.Framework\Store.Framework.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in new issue
Block a user