This commit is contained in:
wule committed 2026-10-31 13:19:32 +08:00
commit 881a317720
30 files changed
+4381 -161

No files matched your search

+1 -1
View File
@@ -31,7 +31,7 @@ namespace AllBase
/// <summary>
/// 版本ID
/// </summary>
public static int VersionCount = 1366;
public static int VersionCount = 1369;
public static string MainPath = "29wx";
//public static string MainPath = "29wx";
//public static string MainPath = "29pdd";
+10 -1
View File
@@ -133,5 +133,14 @@ namespace AllBase.Helper
/// 微信使用软件设置的默认上货地址
/// </summary>
public bool IsWxUseSoftwareDefaultAddress { get; set; } = true;
}
/// <summary>自动上报违规商品</summary>
public bool AutoReportViolationProducts { get; set; } = true;
/// <summary>上货自动剔除违规商品</summary>
public bool AutoExcludeViolationProductsOnUpload { get; set; } = true;
/// <summary>自动下架违规商品</summary>
public bool AutoDelistViolationProducts { get; set; } = true;
}
}
File diff suppressed because it is too large. Load diff
+3
View File
@@ -44,6 +44,9 @@
<Compile Update="InitForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="KJDForms\SystemForms\SystemViolationDetectionForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="PDDForms\AdminForms\RandomComProductForm.cs">
<SubType>Form</SubType>
</Compile>
+5 -2
View File
@@ -29,8 +29,9 @@
private void InitializeComponent()
{
System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("解除限制");
System.Windows.Forms.TreeNode violationNode = new System.Windows.Forms.TreeNode("违规检测");
System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("系统设置", new System.Windows.Forms.TreeNode[] {
treeNode1});
treeNode1, violationNode});
this.panel1 = new System.Windows.Forms.Panel();
this.panel3 = new System.Windows.Forms.Panel();
this.panel2 = new System.Windows.Forms.Panel();
@@ -103,6 +104,8 @@
this.tv.Name = "tv";
treeNode1.Name = "解除限制";
treeNode1.Text = "解除限制";
violationNode.Name = "违规检测";
violationNode.Text = "违规检测";
treeNode2.Name = "系统设置";
treeNode2.Text = "系统设置";
this.tv.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
@@ -162,4 +165,4 @@
private UserComponent.UcTreeView tv;
private System.Windows.Forms.SplitContainer splitContainer1;
}
}
}
@@ -15,6 +15,7 @@ namespace TemuKJD.KJDForms.SystemForms
public partial class SystemForm : BaseForm
{
public Lazy<SystemRemoveRestrictionsForm> systemRemoveRestrictionsForm = new Lazy<SystemRemoveRestrictionsForm>();
public Lazy<SystemViolationDetectionForm> systemViolationDetectionForm = new Lazy<SystemViolationDetectionForm>();
public SystemForm()
{
InitializeComponent();
@@ -46,6 +47,9 @@ namespace TemuKJD.KJDForms.SystemForms
case "解除限制":
SetForm(systemRemoveRestrictionsForm.Value);
break;
case "违规检测":
SetForm(systemViolationDetectionForm.Value);
break;
//case "商品管理":
// SetForm(shopProductForm.Value);
// break;
@@ -0,0 +1,61 @@
namespace TemuKJD.KJDForms.SystemForms
{
partial class SystemViolationDetectionForm
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && components != null)
components.Dispose();
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.chkAutoReport = new TemuKJD.UserComponent.UcCheckBox(this.components);
this.chkAutoExcludeOnUpload = new TemuKJD.UserComponent.UcCheckBox(this.components);
this.chkAutoDelist = new TemuKJD.UserComponent.UcCheckBox(this.components);
this.SuspendLayout();
// chkAutoReport
this.chkAutoReport.AutoSize = true;
this.chkAutoReport.Location = new System.Drawing.Point(24, 24);
this.chkAutoReport.Name = "chkAutoReport";
this.chkAutoReport.TabIndex = 0;
this.chkAutoReport.Text = "自动上报违规商品";
this.chkAutoReport.UseVisualStyleBackColor = true;
// chkAutoExcludeOnUpload
this.chkAutoExcludeOnUpload.AutoSize = true;
this.chkAutoExcludeOnUpload.Location = new System.Drawing.Point(24, 64);
this.chkAutoExcludeOnUpload.Name = "chkAutoExcludeOnUpload";
this.chkAutoExcludeOnUpload.TabIndex = 1;
this.chkAutoExcludeOnUpload.Text = "上货自动剔除违规商品";
this.chkAutoExcludeOnUpload.UseVisualStyleBackColor = true;
// chkAutoDelist
this.chkAutoDelist.AutoSize = true;
this.chkAutoDelist.Location = new System.Drawing.Point(24, 104);
this.chkAutoDelist.Name = "chkAutoDelist";
this.chkAutoDelist.TabIndex = 2;
this.chkAutoDelist.Text = "自动下架违规商品";
this.chkAutoDelist.UseVisualStyleBackColor = true;
// SystemViolationDetectionForm
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.AutoScroll = true;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.chkAutoReport);
this.Controls.Add(this.chkAutoExcludeOnUpload);
this.Controls.Add(this.chkAutoDelist);
this.Font = new System.Drawing.Font("微软雅黑", 9F);
this.Name = "SystemViolationDetectionForm";
this.Text = "违规检测";
this.ResumeLayout(false);
this.PerformLayout();
}
private UserComponent.UcCheckBox chkAutoReport;
private UserComponent.UcCheckBox chkAutoExcludeOnUpload;
private UserComponent.UcCheckBox chkAutoDelist;
}
}
@@ -0,0 +1,32 @@
using System;
using AllBase.Helper;
using TemuKJD.BaseForms;
namespace TemuKJD.KJDForms.SystemForms
{
public partial class SystemViolationDetectionForm : BaseForm
{
public SystemViolationDetectionForm()
{
InitializeComponent();
var settings = GlobalConfig.GlobalSettings;
chkAutoReport.Checked = settings.AutoReportViolationProducts;
chkAutoExcludeOnUpload.Checked = settings.AutoExcludeViolationProductsOnUpload;
chkAutoDelist.Checked = settings.AutoDelistViolationProducts;
chkAutoReport.CheckedChanged += Settings_CheckedChanged;
chkAutoExcludeOnUpload.CheckedChanged += Settings_CheckedChanged;
chkAutoDelist.CheckedChanged += Settings_CheckedChanged;
}
private void Settings_CheckedChanged(object sender, EventArgs e)
{
var settings = GlobalConfig.GlobalSettings;
settings.AutoReportViolationProducts = chkAutoReport.Checked;
settings.AutoExcludeViolationProductsOnUpload = chkAutoExcludeOnUpload.Checked;
settings.AutoDelistViolationProducts = chkAutoDelist.Checked;
StartUp.SaveGlobalSettings();
}
}
}
@@ -12,168 +12,177 @@ using System.Threading.Tasks;
using TemuKJD.BLL;
using TemuKJD.WXForms.ProductForms;
using Work;
using Work.Services;
namespace TemuKJD.PDDForms.ProductForms
{
// 微信店铺违规商品抓取
public class WXProdViolationManage
{
public void GetShopProdViolation()
{
Task.Run(() =>
{
if (!Directory.Exists("wxProdViolation"))
Directory.CreateDirectory("wxProdViolation");
// 微信店铺违规商品抓取
public class WXProdViolationManage
{
public void GetShopProdViolation()
{
Task.Run(() =>
{
if (!Directory.Exists("wxProdViolation"))
Directory.CreateDirectory("wxProdViolation");
while (true)
{
//break;
foreach (var shop in GlobalConfig.ShopLoginList)
{
if (shop.LoginStatus != "登录成功")
continue;
while (true)
{
//break;
foreach (var shop in GlobalConfig.ShopLoginList)
{
if (shop.LoginStatus != "登录成功")
continue;
Thread.Sleep(Randomx.GetId(500, 1500));
// 开启自动下架时,后台检测当前店铺在售商品并下架违规商品。
if (GlobalConfig.GlobalSettings.AutoDelistViolationProducts)
CloudGoodsService.CheckAndOffShelfViolations(shop);
WXProdViolationGetInfo info = new WXProdViolationGetInfo() { shopId = shop.ShopId, updateDay = DateTime.Now.ToString("yyMMdd") };
try
{
info = NaiBa.Util.Helper.ConfigHelper.LoadConfig<WXProdViolationGetInfo>("wxProdViolation\\" + shop.ShopId);
if (info == null)
info = new WXProdViolationGetInfo() { shopId = shop.ShopId, updateDay = DateTime.MinValue.ToString("yyMMdd") };
Thread.Sleep(Randomx.GetId(500, 1500));
if (info.updateDay == DateTime.Now.ToString("yyMMdd"))
{
// 今日同步过,跳过,暂时关闭改为每次打开立即读取
//continue;
}
WXProdViolationGetInfo info = new WXProdViolationGetInfo() { shopId = shop.ShopId, updateDay = DateTime.Now.ToString("yyMMdd") };
try
{
info = NaiBa.Util.Helper.ConfigHelper.LoadConfig<WXProdViolationGetInfo>("wxProdViolation\\" + shop.ShopId);
if (info == null)
info = new WXProdViolationGetInfo() { shopId = shop.ShopId, updateDay = DateTime.MinValue.ToString("yyMMdd") };
info.failReason = "";
if (info.updateDay == DateTime.Now.ToString("yyMMdd"))
{
// 今日同步过,跳过,暂时关闭改为每次打开立即读取
//continue;
}
var result = getShopiolationProd(shop);
Thread.Sleep(Randomx.GetId(1000, 2000));
if (!result.Contains("\"code\":0"))
{
WXForms.ShopForms.WXShopListForm.CheckShopLogin(shop);
info.failReason = "";
info.failReason = "读取失败";
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxProdViolation\\" + shop.ShopId, info);
continue;
}
var result = getShopiolationProd(shop);
// 开启自动上报时,后台解析店铺处罚记录并上报违规商品。
if (GlobalConfig.GlobalSettings.AutoReportViolationProducts)
CloudGoodsService.ReportViolationsFromJson(result, shop);
JObject recordObj = JsonHelper.JObjectParse(result)["record"] as JObject;
JArray jArr = JsonHelper.JObjectParse(result)["record"]["items"] as JArray;
if (recordObj != null && jArr == null)
{
jArr = new JArray();
}
foreach(var jObj in jArr)
{
string sVioInfo = JsonHelper.SerializeObject(jObj);
var punishUuid = BaseRegex.GetStringJson(ref sVioInfo, "punishUuid");
var punishReason = BaseRegex.GetStringJson(ref sVioInfo, "punishReason");
var punishTime = BaseClass.StampToDateTime(BaseRegex.GetIntJson(ref sVioInfo, "punishTime"));
var productId = BaseRegex.GetStringJson(ref sVioInfo, "productId");
var productDesc = BaseRegex.GetStringJson(ref sVioInfo, "productDesc");
//相似同款低质商品 不当使用他人权利
if (!punishReason.Contains("发布违禁信息") && !punishReason.Contains("材质夸大宣传") && !punishReason.Contains("相似同款低质商品") &&
!punishReason.Contains("价格违规") && !punishReason.Contains("售假") && !punishReason.Contains("品牌资质问题") &&
!punishReason.Contains("不当使用他人权利") && !punishReason.Contains("用户反馈虚假宣传"))
continue;
if (!string.IsNullOrWhiteSpace(productDesc) && !string.IsNullOrWhiteSpace(productId))
{
var url = BaseClass.BuildPDDObjString("product/mdy_violation_prod");
var data = UserLogin.GetSignaturex();
data += "&wx_safe_status=违规商品";
data += "&notes=" + GetHtml.UrlEncodeUtf8(("违规轮询-" + shop.ShopId + "-" + punishUuid + "-" + punishReason + "-" + punishTime.ToString("yy/MM/dd HH:mm")).Trim());
data += "&product_name=" + productDesc;
var html = GetHtml.PostUtf8(url, data);
if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200"))
html = GetHtml.PostUtf8(url, data);
if (!html.Contains("\"code\":200"))
{
info.failReason = "更新商品状态失败";
break;
}
Thread.Sleep(Randomx.GetId(1000, 2000));
if (!result.Contains("\"code\":0"))
{
WXForms.ShopForms.WXShopListForm.CheckShopLogin(shop);
if(html.Contains("商品不存在"))
{
var getProdRst = WXUpload.searchProductWithTitle(shop, GetHtml.UrlEncodeUtf8(productDesc));
var spuCode = BaseRegex.GetStringJson(ref getProdRst, "spuCode");
var secrec_spu_id = "";
var spu_id = "";
if (string.IsNullOrEmpty(spuCode) || spuCode.Length < 10)
{
continue;
}
if (spuCode.StartsWith("EC1") && spuCode.EndsWith("A"))
{
spu_id = spuCode.Substring(3, spuCode.Length - 4);
}
else if (spuCode.StartsWith("P1-"))
{
spu_id = spuCode.Substring(3);
}
else
{
secrec_spu_id = spuCode;
}
info.failReason = "读取失败";
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxProdViolation\\" + shop.ShopId, info);
continue;
}
url = BaseClass.BuildPDDObjString("product/mdy_violation_prod");
data = UserLogin.GetSignaturex();
data += "&wx_safe_status=违规商品";
data += "&notes=" + ("违规轮询-" + shop.ShopId + "-" + punishUuid + "-" + punishReason).Trim();
data += "&secret_spu_id=" + secrec_spu_id;
data += "&spu_id=" + spu_id;
html = GetHtml.PostUtf8(url, data);
if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200"))
html = GetHtml.PostUtf8(url, data);
if (!html.Contains("\"code\":200"))
{
info.failReason = "更新商品状态失败";
break;
}
}
}
}
JObject recordObj = JsonHelper.JObjectParse(result)["record"] as JObject;
JArray jArr = JsonHelper.JObjectParse(result)["record"]["items"] as JArray;
if (recordObj != null && jArr == null)
{
jArr = new JArray();
}
foreach (var jObj in jArr)
{
string sVioInfo = JsonHelper.SerializeObject(jObj);
var punishUuid = BaseRegex.GetStringJson(ref sVioInfo, "punishUuid");
var punishReason = BaseRegex.GetStringJson(ref sVioInfo, "punishReason");
var punishTime = BaseClass.StampToDateTime(BaseRegex.GetIntJson(ref sVioInfo, "punishTime"));
var productId = BaseRegex.GetStringJson(ref sVioInfo, "productId");
var productDesc = BaseRegex.GetStringJson(ref sVioInfo, "productDesc");
//相似同款低质商品 不当使用他人权利
if (!punishReason.Contains("发布违禁信息") && !punishReason.Contains("材质夸大宣传") && !punishReason.Contains("相似同款低质商品") &&
!punishReason.Contains("价格违规") && !punishReason.Contains("售假") && !punishReason.Contains("品牌资质问题") &&
!punishReason.Contains("不当使用他人权利") && !punishReason.Contains("用户反馈虚假宣传"))
continue;
if (!string.IsNullOrWhiteSpace(productDesc) && !string.IsNullOrWhiteSpace(productId))
{
var url = BaseClass.BuildPDDObjString("product/mdy_violation_prod");
var data = UserLogin.GetSignaturex();
data += "&wx_safe_status=违规商品";
data += "&notes=" + GetHtml.UrlEncodeUtf8(("违规轮询-" + shop.ShopId + "-" + punishUuid + "-" + punishReason + "-" + punishTime.ToString("yy/MM/dd HH:mm")).Trim());
data += "&product_name=" + productDesc;
var html = GetHtml.PostUtf8(url, data);
if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200"))
html = GetHtml.PostUtf8(url, data);
if (!html.Contains("\"code\":200"))
{
info.failReason = "更新商品状态失败";
break;
}
if (string.IsNullOrEmpty(info.failReason))
info.updateDay = DateTime.Now.ToString("yyMMdd");
if (html.Contains("商品不存在"))
{
var getProdRst = WXUpload.searchProductWithTitle(shop, GetHtml.UrlEncodeUtf8(productDesc));
var spuCode = BaseRegex.GetStringJson(ref getProdRst, "spuCode");
var secrec_spu_id = "";
var spu_id = "";
if (string.IsNullOrEmpty(spuCode) || spuCode.Length < 10)
{
continue;
}
if (spuCode.StartsWith("EC1") && spuCode.EndsWith("A"))
{
spu_id = spuCode.Substring(3, spuCode.Length - 4);
}
else if (spuCode.StartsWith("P1-"))
{
spu_id = spuCode.Substring(3);
}
else
{
secrec_spu_id = spuCode;
}
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxProdViolation\\" + shop.ShopId, info);
Thread.Sleep(5000);
}
catch (Exception ex)
{
try
{
if (info == null)
info = new WXProdViolationGetInfo() { shopId = shop.ShopId, updateDay = DateTime.Now.ToString("yyMMdd") };
info.failReason = ex.Message;
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxProdViolation\\" + shop.ShopId, info);
}
catch { }
}
}
// 休眠两个小时
Thread.Sleep(1000 * 60 * 60 * 2);
}
});
}
url = BaseClass.BuildPDDObjString("product/mdy_violation_prod");
data = UserLogin.GetSignaturex();
data += "&wx_safe_status=违规商品";
data += "&notes=" + ("违规轮询-" + shop.ShopId + "-" + punishUuid + "-" + punishReason).Trim();
data += "&secret_spu_id=" + secrec_spu_id;
data += "&spu_id=" + spu_id;
html = GetHtml.PostUtf8(url, data);
if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200"))
html = GetHtml.PostUtf8(url, data);
if (!html.Contains("\"code\":200"))
{
info.failReason = "更新商品状态失败";
break;
}
}
}
}
public static string getShopiolationProd(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeviolationsec/violation/cgi/get?token=&lang=zh_CN&violationType=finder&shopId=";
string referer = "https://store.weixin.qq.com/shop/violation/home";
var result = WXHttpResponseBLL.WeiXinGetResponse(shop, url, referer);
return result;
}
}
if (string.IsNullOrEmpty(info.failReason))
info.updateDay = DateTime.Now.ToString("yyMMdd");
public class WXProdViolationGetInfo
{
public string shopId { get; set; }
public string updateDay { get; set; } // yyMMdd
public string failReason { get; set; } // "", "掉线"...
}
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxProdViolation\\" + shop.ShopId, info);
Thread.Sleep(5000);
}
catch (Exception ex)
{
try
{
if (info == null)
info = new WXProdViolationGetInfo() { shopId = shop.ShopId, updateDay = DateTime.Now.ToString("yyMMdd") };
info.failReason = ex.Message;
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wxProdViolation\\" + shop.ShopId, info);
}
catch { }
}
}
// 休眠两个小时
Thread.Sleep(1000 * 60 * 60 * 2);
}
});
}
public static string getShopiolationProd(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeviolationsec/violation/cgi/get?token=&lang=zh_CN&violationType=finder&shopId=";
string referer = "https://store.weixin.qq.com/shop/violation/home";
var result = WXHttpResponseBLL.WeiXinGetResponse(shop, url, referer);
return result;
}
}
public class WXProdViolationGetInfo
{
public string shopId { get; set; }
public string updateDay { get; set; } // yyMMdd
public string failReason { get; set; } // "", "掉线"...
}
}
@@ -675,7 +675,7 @@ namespace TemuKJD.WXForms.ProductForms
item.Cells["colSelect"].Value = wxUploadRule.SelectedShopIds.Contains(shopId);
}
}
isInit = true;
}
@@ -1715,6 +1715,32 @@ namespace TemuKJD.WXForms.ProductForms
}));
}
// 开启上货自动剔除时,上传前检测违规状态;仅服务端明确返回违规时禁止上传。
if (GlobalConfig.GlobalSettings.AutoExcludeViolationProductsOnUpload)
{
Invoke(new Action(() => cell.Value = "商品违规检测..."));
try
{
long goodsId = 0;
if ((!long.TryParse(dbProd.spu_id, out goodsId) || goodsId <= 0) &&
(!long.TryParse(dbProd.skc_id, out goodsId) || goodsId <= 0))
throw new Exception("商品ID无效");
var statuses = CloudGoodsService.GetViolationStatus(new List<long> { goodsId });
var status = statuses.FirstOrDefault(item => item.GoodsId == goodsId);
if (status == null)
throw new Exception("未返回当前商品的违规状态");
if (status.IsViolation)
return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"当前商品违规,禁止上传\"}";
}
catch (Exception ex)
{
Debug.WriteLine("商品违规检测失败,继续上传:" + ex.Message);
if (cell != null)
Invoke(new Action(() => cell.Value = "商品违规检测失败,继续上传"));
}
}
#region 裂变标题
if (BaseClass.UserAuthority.Contains("裂变调试") && chkFissionGoodsName.Checked)
{
+141
View File
@@ -0,0 +1,141 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店平台活动报名及活动商品接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxActivityApi
{
/// <summary>取消商品活动报名;沿用原订单页面指定的活动请求结构。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="activityData">取消报名请求 JSON 对象,字段结构沿用活动接口。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.cancelActivity。
/// 保留旧页面 Referer 中的活动 ID 1016;实际提交内容取自 activityData。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string CancelActivity(ShopLoginInfo shop, JObject activityData)
{
string url = "https://store.weixin.qq.com/shop-faas/mmeckolmarketingnode/activity/cgi/updateRequestProductList?token=&lang=zh_CN";
string body = JsonHelper.SerializeObject(activityData);
string refere = "https://store.weixin.qq.com/shop/marketingkol/activity/detail?id=1016&curTab=2";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>获取店铺针对指定平台活动的报名信息。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="activityId">微信平台活动 ID;默认值沿用原活动页面,其他活动须显式传入。 默认值:&quot;1269&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\ActivityForms\WXActivity618Form.cs,WXActivity.getShopCanActivity。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetShopCanActivity(ShopLoginInfo shop, string activityId = "1269")
{
string url = "https://store.weixin.qq.com/shop-faas/mmeckolmarketingnode/activity/cgi/queryShopPlatformActivity?token=&lang=zh_CN&platformActivityId=" + activityId;
string refere = "https://store.weixin.qq.com/shop/marketingkol/activity/detail?id=" + activityId + "&curTab=2";
var result = WxHttpClient.Get(shop, url, refere);
return result;
}
/// <summary>提交店铺参加平台活动的申请。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="activityId">微信平台活动 ID;默认值沿用原活动页面,其他活动须显式传入。 默认值:&quot;1269&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\ActivityForms\WXActivity618Form.cs,WXActivity.applyShopActivity。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string ApplyShopActivity(ShopLoginInfo shop, string activityId = "1269")
{
string url = "https://store.weixin.qq.com/shop-faas/mmeckolmarketingnode/activity/cgi/applyShopPlatformActivity?token=&lang=zh_CN";
string refere = "https://store.weixin.qq.com/shop/marketingkol/activity/detail?id=" + activityId + "&curTab=2";
string data = @"{""platformActivityId"":""" + activityId + @""",""finderCommunicationInfo"":{}}";
var result = WxHttpClient.Post(shop, url, data, refere);
return result;
}
/// <summary>扫描可参加指定平台活动的商品。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="page">页码,从 1 开始。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:10。</param>
/// <param name="activityId">微信平台活动 ID;默认值沿用原活动页面,其他活动须显式传入。 默认值:&quot;1269&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\ActivityForms\WXActivity618Form.cs,WXActivity.getActivityProdList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetActivityProdList(ShopLoginInfo shop, int page, int pageSize = 10, string activityId = "1269")
{
string url = "https://store.weixin.qq.com/shop-faas/mmeckolmarketingnode/activity/cgi/scanProductForPlatformInvestment?token=&lang=zh_CN";
string refere = "https://store.weixin.qq.com/shop/marketingkol/activity/detail?id=" + activityId + "&goToUploadProduct=1";
string data = @"{""keyword"":"""",""pageNum"":" + page + @",""pageSize"":" + pageSize + @",""platformActivityId"":""" + activityId + @"""}";
var result = WxHttpClient.Post(shop, url, data, refere);
return result;
}
/// <summary>提交平台活动商品报名或更新报名商品列表。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodData">活动商品报名 JSON 对象,按原活动接口结构填写。</param>
/// <param name="activityId">微信平台活动 ID;默认值沿用原活动页面,其他活动须显式传入。 默认值:&quot;1269&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\ActivityForms\WXActivity618Form.cs,WXActivity.signWxActivity。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SignWxActivity(ShopLoginInfo shop, JObject prodData, string activityId = "1269")
{
string url = "https://store.weixin.qq.com/shop-faas/mmeckolmarketingnode/activity/cgi/updateRequestProductList?token=&lang=zh_CN";
string refere = "https://store.weixin.qq.com/shop/marketingkol/activity/detail?id=" + activityId + "&goToUploadProduct=1";
string data = JsonHelper.SerializeObject(prodData);
var result = WxHttpClient.Post(shop, url, data, refere);
return result;
}
/// <summary>查询已经进入指定平台活动的商品列表。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="page">页码,从 1 开始。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:10。</param>
/// <param name="activityId">微信平台活动 ID;默认值沿用原活动页面,其他活动须显式传入。 默认值:&quot;1269&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\ActivityForms\WXActivity618Form.cs,WXActivity.getProdInActivityList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetProdInActivityList(ShopLoginInfo shop, int page, int pageSize = 10, string activityId = "1269")
{
string url = "https://store.weixin.qq.com/shop-faas/mmeckolmarketingnode/activity/cgi/getPlatformInvestmentProductInfoList?token=&lang=zh_CN";
string refere = "https://store.weixin.qq.com/shop/marketingkol/activity/detail?id=" + activityId + "&curTab=2";
string data = @"{""platformActivityId"":""" + activityId + @""",""pageNum"":" + page + @",""pageSize"":" + pageSize + @",""auditStatus"":0,""productId"":""""}";
var result = WxHttpClient.Post(shop, url, data, refere);
return result;
}
/// <summary>分页查询店铺可报名参加指定平台活动的商品。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="page">页码,从 1 开始。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:10。</param>
/// <param name="activityId">微信平台活动 ID;默认值沿用原活动页面,其他活动须显式传入。 默认值:&quot;1269&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\ActivityForms\WXActivity618Form.cs,WXActivity.getShopActivityCanApplyProduct。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetShopActivityCanApplyProduct(ShopLoginInfo shop, int page, int pageSize = 10, string activityId = "1269")
{
string url = "https://store.weixin.qq.com/shop-faas/mmeckolmarketingnode/activity/cgi/getShopActivityCanApplyProduct?token=&lang=zh_CN";
string refere = "https://store.weixin.qq.com/shop/marketingkol/activity/detail?id=" + activityId + "&curTab=2";
string data = @"{""platformActivityId"":""" + activityId + @""",""page"":" + page + @",""pageSize"":" + pageSize + @",""queryWord"":""""}";
var result = WxHttpClient.Post(shop, url, data, refere);
return result;
}
}
}
+89
View File
@@ -0,0 +1,89 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店售后地址及运费模板接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxAddressApi
{
/// <summary>查询商品发布时可选的运费模板。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.getFreightTemplate。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetFreightTemplate(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/express/cgi/goods/getFreightTemplate?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>查询商品发布时可选的售后地址,支持搜索条件。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="searchText">地址搜索关键词,空字符串表示不指定关键词。 默认值:&quot;&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.getAddress。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetAddress(ShopLoginInfo shop, string searchText = "")
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/cgi/getAddress?token=&lang=zh_CN";
if (!string.IsNullOrEmpty(searchText))
url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/cgi/getAddress?searchStr=" + GetHtml.UrlEncodeUtf8(searchText) + "&token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>按地址 ID 查询售后地址详情。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="AddressId">售后地址 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.getAddressById。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetAddressById(ShopLoginInfo shop, string AddressId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/cgi/getAddress?offset=0&limit=20&includeBlock=1&addressId=" + AddressId + "&token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/address/expressAddressMgmt";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>新增售后寄回地址。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="provinceName">收件地址的省份名称。</param>
/// <param name="cityName">收件地址的城市名称。</param>
/// <param name="countyName">收件地址的区县名称。</param>
/// <param name="detailInfo">详细街道及门牌地址。</param>
/// <param name="userName">地址联系人姓名。</param>
/// <param name="telNumber">收件联系电话或原查询接口支持的手机号条件。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.addAddress。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string AddAddress(ShopLoginInfo shop, string provinceName, string cityName, string countyName, string detailInfo, string userName, string telNumber)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/address/addAddress?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/address/expressAddressMgmt";
string address = "{\"addressInfo\":{\"provinceName\":\"" + provinceName + "\",\"cityName\":\"" + cityName + "\",\"countyName\":\"" + countyName + "\",\"detailInfo\":\"" + detailInfo + "\",\"userName\":\"" + userName + "\",\"telNumber\":\"" + telNumber + "\",\"location\":{}},\"defaultSend\":0,\"defaultRecv\":0}";
JObject obj = new JObject();
obj["data"] = address;
string body = JsonHelper.SerializeObject(obj);
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
}
}
+53
View File
@@ -0,0 +1,53 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店带货助手选品池接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxAssistantApi
{
/// <summary>在微信带货助手选品池中查询商品;结构化参数重载执行列表筛选,商品 ID 重载执行关键词搜索。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="wxCateAuthParam">选品池列表筛选 JSON;原参数名沿用旧方法,实际并非类目资质参数。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\AdminForms\WXSaleAssistantForm.cs,WxGetAssistant.wxGetAssistant。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxGetAssistant(ShopLoginInfo shop, JObject wxCateAuthParam)
{
string url = "https://store.weixin.qq.com/shop-faas/mmeckolpoolnode/ecListSelectionSpuItems?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/talent/pool/home";
string data = JsonHelper.SerializeObject(wxCateAuthParam);
var result = WxHttpClient.PostAssistant(shop, url, data, referer);
return result;
}
/// <summary>在微信带货助手选品池中查询商品;结构化参数重载执行列表筛选,商品 ID 重载执行关键词搜索。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodId">微信商品 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\AdminForms\WXSaleAssistantForm.cs,WxGetAssistant.wxGetAssistant。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxGetAssistant(ShopLoginInfo shop, string prodId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmeckolpoolnode/ecSearchSelectionSpuItems?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/talent/pool/home?keyword=" + prodId;
string body = @"{""filter"":{""spuFilter"":{""monthlySalesRange"":null,""goodEvaluationRatioRange"":null,""shopScoreRange"":null},
""spuSort"":{""sortOrder"":0,""sortType"":0},""category"":null},""pageContext"":{""pageContext"":null,""limit"":15},
""requestContext"":{""sessionId"":""" + BaseClass.DateTimeToTimestampMilliseconds(DateTime.Now.AddSeconds(-Randomx.GetId(10, 100))) + @""",
""requestId"":""" + BaseClass.DateTimeToTimestampMilliseconds(DateTime.Now) + @""",""parentSearchId"":""53"",""displayedSpus"":null},
""keyword"":""" + prodId + @"""}";
var result = WxHttpClient.PostAssistant(shop, url, body, referer);
return result;
}
}
}
+159
View File
@@ -0,0 +1,159 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店商品类目识别、品牌及资质接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxCategoryApi
{
/// <summary>根据商品标题及本地图片识别推荐类目。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="goodsName">商品标题;方法内部执行 UTF-8 URL 编码。</param>
/// <param name="goodImgUrlsLst">用于识别类目的本地图片文件完整路径列表;原参数名含 Url,但实际读取本地文件。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.getProductClassify。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetProductClassify(ShopLoginInfo shop, string goodsName, List<string> goodImgUrlsLst)
{
string boundaryLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
string boundaryStr = "----WebKitFormBoundary";
for (int i = 0; i < 16; i++)
{
boundaryStr += boundaryLetters[Randomx.GetId(boundaryLetters.Length)];
}
string url = "https://store.weixin.qq.com/shop-faas/cgi/common/productClassify?from=B&title=" + GetHtml.UrlEncodeUtf8(goodsName) + "&token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
string body = @"--" + boundaryStr + @"
";
foreach (var imgFullPath in goodImgUrlsLst)
{
string fileName = imgFullPath.Split('\\').LastOrDefault();
body += @"Content-Disposition: form-data; name=""file""; filename=""" + fileName + @"""
Content-Type: image/jpeg
<!>" + imgFullPath + @"<!>
--" + boundaryStr;
}
body += @"--
";
var result = WxHttpClient.UploadMultipart(shop, url, body, boundaryStr, referer);
return result;
}
/// <summary>查询所选类目及品牌的上架要求。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="catIdLst">从上级到末级的类目 ID 列表,用于查询或申请类目资质。</param>
/// <param name="brandId">微信品牌 ID,直接按原协议写入请求。 默认值:&quot;2100000000&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.getCategoryOnShelf。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetCategoryOnShelf(ShopLoginInfo shop, List<long> catIdLst, string brandId = "2100000000")
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/product/getCategoryOnShelfV2?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
string body = @"{""catIdList"":[" + string.Join(",", catIdLst) + @"],""brandId"":" + brandId + "}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询类目可用品牌及品牌资质信息。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="catId">微信商品类目 ID。 默认值:&quot;547591&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.getMixBrand。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetMixBrand(ShopLoginInfo shop, string catId = "547591")
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/getMixBrand?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
string body = @"{""categoryId"":""" + catId + @"""}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>检查店铺与指定商品类目的关联及经营资格。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="catId">微信商品类目 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.batchCheckCategoryRelation。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string BatchCheckCategoryRelation(ShopLoginInfo shop, long catId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/product/batchCheckCategoryRelation?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
string body = @"{""categoryIdList"":[" + catId + "]}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>按原快捷申请流程提交类目经营资格申请。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="catId">微信商品类目 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.addFinderCategoryV2。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string AddFinderCategoryV2(ShopLoginInfo shop, long catId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/addFinderCategoryV2?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
string body = @"{""categoryInfo"":{""categories"":[{""id"":""" + catId + @"""}]},""brandIdList"":[],""leafCategoryId"":""" + catId + @""",""reuse"":0,""applyType"":1}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>申请类目资质前查询该类目的详细要求。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="catId">微信商品类目 ID。</param>
/// <param name="catIdLst">从上级到末级的类目 ID 列表,用于查询或申请类目资质。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.getSingleCategoryData。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetSingleCategoryData(ShopLoginInfo shop, long catId, List<long> catIdLst)
{
var catIds = "[\"" + string.Join("\",\"", catIdLst) + "\"]";
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/getSingleCategoryData?token=&lang=zh_CN&categoryId=" + catId;
string referer = "https://store.weixin.qq.com/shop/brandAndCat/category/apply?defaultCategoryIds=" + GetHtml.UrlEncodeUtf8(catIds) + "&source=goods&type=apply";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>提交类目资质申请资料。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="catIdLst">从上级到末级的类目 ID 列表,用于查询或申请类目资质。</param>
/// <param name="wxCateAuthParam">类目资质申请模型,包含资质图片等平台要求字段。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.wxCateAuth。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxCateAuth(ShopLoginInfo shop, List<long> catIdLst, WXCateAuthParam wxCateAuthParam)
{
var catIds = "[\"" + string.Join("\",\"", catIdLst) + "\"]";
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/addFinderCategoryV2?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/brandAndCat/category/apply?defaultCategoryIds=" + GetHtml.UrlEncodeUtf8(catIds) + "&source=goods&type=apply";
string data = JsonHelper.SerializeObject(wxCateAuthParam);
var result = WxHttpClient.Post(shop, url, data, referer);
return result;
}
}
}
+86
View File
@@ -0,0 +1,86 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店代发订单接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxConsignmentApi
{
/// <summary>查询订单代发功能的开关状态。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXOrderConsignmentForm.cs,WXOrderConsignment.getConsignmentOnOffStatus。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetConsignmentOnOffStatus(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodesuppliercosignment/associate/cgi/getOpenStatus?token=&lang=zh_CN";
string data = "{}";
string refere = "https://store.weixin.qq.com/shop/order/consignment";
var result = WxHttpClient.Post(shop, url, data, refere);
return result;
}
/// <summary>分页查询代发订单,可筛选待分配订单。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="pageNum">页码,从 1 开始。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:30。</param>
/// <param name="isWaitDevide">是否只查询等待分配的代发订单。 默认值:false。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXOrderConsignmentForm.cs,WXOrderConsignment.searchConsignmentOrder。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SearchConsignmentOrder(ShopLoginInfo shop, int pageNum, int pageSize = 30, bool isWaitDevide = false)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodesuppliercosignment/order/cgi/orderSearch?token=&lang=zh_CN";
string data = @"{""pageSize"":" + pageSize + @",""page"":" + pageNum + @",""tab"":1}";
if (isWaitDevide)
data = @"{""pageSize"":" + pageSize + @",""page"":" + pageNum + @",""orderStatus"":20,""availCosignment"":true}";
string refere = "https://store.weixin.qq.com/shop/order/consignment";
var result = WxHttpClient.Post(shop, url, data, refere);
return result;
}
/// <summary>提交代发订单分配请求。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="dataObj">完整代发操作 JSON 对象,按原接口填入订单和分配信息。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXOrderConsignmentForm.cs,WXOrderConsignment.addConsignmentOrder。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string AddConsignmentOrder(ShopLoginInfo shop, JObject dataObj)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodesuppliercosignment/order/cgi/cancelAssignOrder?token=&lang=zh_CN";
string data = JsonHelper.SerializeObject(dataObj);
string refere = "https://store.weixin.qq.com/shop/order/consignment";
var result = WxHttpClient.Post(shop, url, data, refere);
return result;
}
/// <summary>取消已分配的代发订单。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="dataObj">完整代发操作 JSON 对象,按原接口填入订单和分配信息。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXOrderConsignmentForm.cs,WXOrderConsignment.cancelConsignmentOrder。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string CancelConsignmentOrder(ShopLoginInfo shop, JObject dataObj)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodesuppliercosignment/order/cgi/cancelAssignOrder?token=&lang=zh_CN";
string data = JsonHelper.SerializeObject(dataObj);
string refere = "https://store.weixin.qq.com/shop/order/consignment";
var result = WxHttpClient.Post(shop, url, data, refere);
return result;
}
}
}
+89
View File
@@ -0,0 +1,89 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店店铺优惠券接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxCouponApi
{
/// <summary>创建优惠券,保留原优惠券模型及忽略 null 字段的序列化方式。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="couponParam">优惠券创建参数,沿用 AllBase 中的微信优惠券模型。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdCouponOrderBoomForm.cs,WxCoupon.WxSetCoupon。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxSetCoupon(ShopLoginInfo shop, WXCouponParamBase couponParam)
{
string url = "https://store.weixin.qq.com/shop-faas/market/coupon/cgi/makeQp?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/marketing/coupon/make?type=990";
JsonSerializerSettings jsonSetting = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
var prodStr = JsonConvert.SerializeObject(couponParam, jsonSetting);
string body = prodStr;
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>按优惠券名称查询优惠券。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="couponName">查询用的优惠券名称。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdCouponOrderBoomForm.cs,WxCoupon.WxSearchCoupon。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxSearchCoupon(ShopLoginInfo shop, string couponName)
{
string url = "https://store.weixin.qq.com/shop-faas/market/coupon/cgi/searchCoupon?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/marketing/coupon";
string body = "{\"pageSize\":20,\"page\":0,\"couponName\":\"" + couponName + "\",\"couponCustomizeChannel\":\"\",\"couponTypeList\":[],\"promoteTypeList\":[],\"couponStatusList\":[\"2\"]}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>结束指定优惠券的发放或活动。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="couponId">微信优惠券 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdCouponOrderBoomForm.cs,WxCoupon.WxEndCoupon。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxEndCoupon(ShopLoginInfo shop, string couponId)
{
string url = "https://store.weixin.qq.com/shop-faas/market/coupon/cgi/upCouponStatus?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/marketing/coupon";
string body = @"{""couponId"":""" + couponId + @""",""status"":4}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>删除指定优惠券。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="couponId">微信优惠券 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdCouponOrderBoomForm.cs,WxCoupon.WxDelCoupon。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxDelCoupon(ShopLoginInfo shop, string couponId)
{
string url = "https://store.weixin.qq.com/shop-faas/market/coupon/cgi/upCouponStatus?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/marketing/coupon";
string body = @"{""couponId"":""" + couponId + @""",""status"":5}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
}
}
+46
View File
@@ -0,0 +1,46 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店客服统计及消息回调接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxCustomerServiceApi
{
/// <summary>提交 AI 客服消息推送回调验证,对应 WxAiTalkForm.Lf_SaveComplete 中的微信请求。</summary>
/// <param name="shop">店铺登录信息,Cookies 为原程序保存的 Cookie 列表 JSON。</param>
/// <param name="callbackUrl">客服服务提供方返回的消息推送回调 URL。</param>
/// <param name="token">回调验证 token,原流程传入客服应用 appId。</param>
/// <param name="base64Key">客服服务提供方返回的 Base64 消息加解密密钥。</param>
/// <returns>微信原始 JSON 或传输错误文字;调用方检查 code,不自动重试。</returns>
public static string VerifyCallback(ShopLoginInfo shop, string callbackUrl, string token, string base64Key)
{
var body = new JObject { ["url"] = callbackUrl, ["token"] = token, ["base64Key"] = base64Key };
return WxHttpClient.Post(shop, WxHttpClient.ShopHost + "/shop-faas/mmecnodeservicemarket/channel/ChannelsEcVerifyCallbackInfo?token=&lang=zh_CN",
body.ToString(), WxHttpClient.ShopHost + "/shop/servicemarket/home");
}
/// <summary>查询客服实时接待统计;原人工客服与 AI 客服共用此接口。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="beginDateTick">开始时间的 Unix 毫秒时间戳;请求发送时转换为秒。</param>
/// <param name="endDateTick">结束时间的 Unix 毫秒时间戳;请求发送时转换为含三位小数的秒。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\AiTalkForms\WxAiTalkForm.cs,WxAiTalkForm.GetKfMsgStatistics。
/// 来源:TEMUKJD\WXForms\TalkForms\WxTalkForm.cs,WxTalkForm.GetKfMsgStatistics。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetKfMsgStatistics(ShopLoginInfo shop, long beginDateTick, long endDateTick)
{
string url = "https://store.weixin.qq.com/shop/kf/cgi/data/getRealTimeShopV2?" + "beginDate=" + (beginDateTick / 1000) + "&endDate=" + (endDateTick / 1000m).ToString("0.000");
string referer = "https://store.weixin.qq.com/shop/kf/data/store";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
}
}
+35
View File
@@ -0,0 +1,35 @@
using System.Collections.Generic;
namespace Work.Api.Wx
{
/// <summary>修改订单物流信息的请求。对应原 WXOrderListOptimizeForm 的同名模型。</summary>
public class UpdateDeliverInfoParam
{
/// <summary>需要修改物流信息的微信订单 ID。</summary>
public string orderId { get; set; }
/// <summary>按原接口协议提供的物流变更字典列表;字典键沿用原订单返回的标识。</summary>
public List<Dictionary<string, UpdateDeliverChangeInfo>> changeInfo { get; set; }
}
/// <summary>一个包裹的物流公司、运单及商品明细。</summary>
public class UpdateDeliverChangeInfo
{
/// <summary>微信物流公司编码;原代码以 OTHER 表示其他物流。</summary>
public string deliveryId { get; set; }
/// <summary>更新后的物流运单号。</summary>
public string waybillId { get; set; }
/// <summary>该包裹包含的商品与数量。</summary>
public List<UpdateDeliverProductInfo> productInfos { get; set; } = new List<UpdateDeliverProductInfo>();
}
/// <summary>物流包裹中的商品明细,字段名直接用于微信 JSON 协议。</summary>
public class UpdateDeliverProductInfo
{
/// <summary>微信商品 ID。</summary>
public string productId { get; set; }
/// <summary>商品规格 SKU ID。</summary>
public string skuId { get; set; }
/// <summary>本次发货商品件数;null 保留原接口的未指定语义。</summary>
public int? productCnt { get; set; }
}
}
+73
View File
@@ -0,0 +1,73 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店资金余额、保证金及订单流水接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxFundsApi
{
/// <summary>查询店铺通用资金账户余额。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WxShopStatisticsForm.cs,WxShopStatisticsForm.GetShopAmount。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetShopAmount(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradefunds/cgi/generalAccount/getGeneralAccountBalance?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/funds/home";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>查询店铺保证金支付状态。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WxShopStatisticsForm.cs,WxShopStatisticsForm.GetShopBalance。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetShopBalance(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradedeposit/home/cgi/getDepositMPayState?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/funds/home";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>分页查询订单资金流水,用于原税务管理页面。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="page">页码,从 1 开始。 默认值:1。</param>
/// <param name="orderSettleState">订单结算状态的接口筛选值,原税务查询使用 60。 默认值:60。</param>
/// <param name="orderState">资金流水的订单状态筛选值,原税务查询使用 100。 默认值:100。</param>
/// <param name="orderPayMethod">订单支付方式的接口筛选值,原税务查询使用 1。 默认值:1。</param>
/// <param name="createTimeBegin">订单创建开始时间的 Unix 秒时间戳,0 沿用原接口的起始条件。 默认值:0。</param>
/// <param name="createTimeEnd">订单创建结束时间的 Unix 秒时间戳;0 使用本机当天最后一秒。 默认值:0。</param>
/// <param name="pageSize">兼容原签名的参数;原实现固定请求每页 20 条,传入其他值不生效。 默认值:20。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXTaxManage.cs,WXTaxBLL.getListOrderFlow。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetListOrderFlow(ShopLoginInfo shop, int page = 1, int orderSettleState = 60, int orderState = 100, int orderPayMethod = 1, int createTimeBegin = 0, int createTimeEnd = 0, int pageSize = 20)
{
// shortcut: 原接口固定每页 20 条,确认平台支持自定义条数后再启用 pageSize 参数。
if (createTimeEnd == 0)
createTimeEnd = BaseClass.DateTimeToTimestampSeconds(DateTime.Now.Date.AddDays(1).AddSeconds(-1));
pageSize = 20;
var offset = Math.Max(page - 1, 0) * pageSize;
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradefunds/cgi/listOrderFlow?token=&lang=zh_CN";
string body = @"{""orderSettleState"":" + orderSettleState + @",""orderState"":" + orderState + @",""orderPayMethod"":" + orderPayMethod + @",""createTimeBegin"":""" + createTimeBegin + @""",""createTimeEnd"":""" + createTimeEnd + @""",""paginationInfo"":{""limit"":20,""offset"":" + offset + "}}";
string referer = "https://store.weixin.qq.com/shop/funds/moneyManage?section=3";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
}
}
+219
View File
@@ -0,0 +1,219 @@
using AllBase;
using AllBase.Model.Result;
using CsharpHttpHelper;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
namespace Work.Api.Wx
{
/// <summary>微信小店公共 HTTP 请求层,使用指定来源的 CsharpHttpHelper.HttpHelper。</summary>
/// <remarks>根据原 WXHttpResponseBLL 保留不同场景的 Cookie 和请求头。同步返回原始正文或错误文字;不更新 ShopLoginInfo、不重试。新业务优先调用分类 API。</remarks>
public static class WxHttpClient
{
/// <summary>微信小店后台 HTTPS 根地址。</summary>
public const string ShopHost = "https://store.weixin.qq.com";
// 原视频上传器的店铺请求发送完整 Cookie,并额外包含 logistics_magic。
internal static string SendMedia(ShopLoginInfo shop, string path, string productId, string data = null)
{
return Send(() =>
{
var item = CreateRequest(shop, ShopHost + path, ShopHost + "/shop/goods/entry?productId=" + Uri.EscapeDataString(productId),
data == null ? MethodType.Get : MethodType.Post, data);
var cookies = JsonHelper.DeserializeJsonToList<CefSharp.Cookie>(Convert.ToString(shop.Cookies)) ?? new List<CefSharp.Cookie>();
item.Cookie = string.Concat(cookies.Select(c => c.Name + "=" + c.Value + "; "));
item.Header["logistics_magic"] = "";
return item;
});
}
/// <summary>发送微信 GET 请求,沿用 WeiXinGetResponse 仅发送 biz 前缀 Cookie 的约定。</summary>
/// <param name="shop">店铺登录信息,Cookies 为 CefSharp.Cookie 列表 JSON。</param>
/// <param name="url">store.weixin.qq.com 域名下的完整 HTTPS 请求地址。</param>
/// <param name="referer">来源页面;普通接口使用原页面地址,默认空字符串。</param>
/// <param name="isGetDocument">true 模拟首页文档导航,并忽略 referer;false 模拟普通接口请求。</param>
/// <returns>原始 JSON、HTML 或错误文字;调用方判断格式和业务状态。</returns>
public static string Get(ShopLoginInfo shop, string url, string referer = "", bool isGetDocument = false)
{
return Send(() => CreateRequest(shop, url, referer, MethodType.Get, document: isGetDocument));
}
/// <summary>发送微信 JSON POST 请求,携带完整 Cookie 和 biz_magic,对应 WeiXinPostResponse。</summary>
/// <param name="shop">店铺登录信息,Cookies 为 CefSharp.Cookie 列表 JSON。</param>
/// <param name="url">store.weixin.qq.com 域名下的完整 HTTPS 请求地址。</param>
/// <param name="data">完整 JSON 请求正文;按 UTF-8 编码,发送前检查 JSON 格式。</param>
/// <param name="referer">原业务页面 Referer。</param>
/// <returns>原始响应正文或错误文字,不自动重试写操作。</returns>
public static string Post(ShopLoginInfo shop, string url, string data, string referer)
{
return Send(() => CreateRequest(shop, url, referer, MethodType.Post, data));
}
/// <summary>发送带货助手请求,对应 WeiXinAssistantPostResponse,使用 talent_magic 而非 biz_magic 请求头。</summary>
/// <param name="shop">带货助手登录信息,Cookies 必须包含对应 talent_magic 凭证。</param>
/// <param name="url">store.weixin.qq.com 域名下的完整 HTTPS 请求地址。</param>
/// <param name="data">完整 UTF-8 JSON 请求正文。</param>
/// <param name="referer">带货助手页面 Referer。</param>
/// <returns>原始响应正文或错误文字,由调用方检查业务状态。</returns>
public static string PostAssistant(ShopLoginInfo shop, string url, string data, string referer)
{
return Send(() => CreateRequest(shop, url, referer, MethodType.Post, data, assistant: true));
}
/// <summary>发送达人客服会话请求,对应 WeiXinTalentOpenKfPostResponse,补充 user_scene=1002、kf_scene=6。</summary>
/// <param name="shop">店铺登录信息,Cookies 为 CefSharp.Cookie 列表 JSON。</param>
/// <param name="url">store.weixin.qq.com 域名下的完整 HTTPS 请求地址。</param>
/// <param name="data">完整 UTF-8 JSON 请求正文。</param>
/// <param name="referer">原达人客服业务页面 Referer。</param>
/// <returns>原始响应正文或错误文字,由调用方检查业务状态。</returns>
public static string PostCustomerService(ShopLoginInfo shop, string url, string data, string referer)
{
return Send(() =>
{
var item = CreateRequest(shop, url, referer, MethodType.Post, data);
item.Header["user_scene"] = "1002";
item.Header["kf_scene"] = "6";
item.Header["logistics_magic"] = "";
return item;
});
}
/// <summary>对应 WeiXinImgPostResponse,将 Base64 解码为原始字节上传,不附带店铺 Cookie。</summary>
/// <param name="shop">店铺登录信息,openid 用于 X-Arguments 上传签名上下文。</param>
/// <param name="url">westorealpha.video.qq.com 域名下的完整 HTTPS 图片上传地址。</param>
/// <param name="base64">纯 Base64 图片字符串,不含 data URI 前缀。</param>
/// <param name="dis_k">临时上传凭证 dis_k。</param>
/// <param name="dis_t">临时上传凭证 dis_t,原值透传。</param>
/// <param name="ext">临时上传凭证 ext,原值透传。</param>
/// <param name="referer">来源页面,默认微信小店根地址。</param>
/// <returns>原始响应正文或错误文字;无效 Base64 不会发起请求。</returns>
public static string UploadImage(ShopLoginInfo shop, string url, string base64, string dis_k, long dis_t,
string ext, string referer = ShopHost + "/")
{
return Send(() =>
{
// 图片上传使用独立的视频域名和临时签名,不发送店铺 Cookie。
var item = CreateRequest(shop, url, referer, MethodType.Post, image: true);
item.Header["X-Requested-With"] = "XMLHttpRequest";
item.Header["X-Arguments"] = "dis_k=" + dis_k + "&dis_t=" + dis_t + "&ext=" + ext +
"&apptype=160&filetype=20304&openid=" + shop.openid + "&groupid=0&taskid=" + Guid.NewGuid();
item.PostDataType = PostDataType.Byte;
item.PostdataByte = Convert.FromBase64String(base64);
return item;
});
}
/// <summary>对应 WeiXinUploadResponse,构造 multipart 二进制正文并发送 biz 前缀 Cookie。</summary>
/// <param name="shop">店铺登录信息,Cookies 为 CefSharp.Cookie 列表 JSON。</param>
/// <param name="url">store.weixin.qq.com 域名下的完整 HTTPS 上传地址。</param>
/// <param name="body">原 multipart 文本模板;成对的 &lt;!&gt; 标记之间为本地文件完整路径,文本统一换行为 CRLF。</param>
/// <param name="boundary">与正文分隔符一致的 multipart boundary,不含正文额外的两个前导短横线。</param>
/// <param name="referer">原上传页面 Referer。</param>
/// <returns>原始响应正文或错误文字;文件不可读或标记不完整时不发送请求。</returns>
public static string UploadMultipart(ShopLoginInfo shop, string url, string body, string boundary, string referer)
{
return Send(() =>
{
var item = CreateRequest(shop, url, referer, MethodType.Post, bizCookiesOnly: true);
item.ContentType = "multipart/form-data; boundary=" + boundary;
item.PostDataType = PostDataType.Byte;
item.PostdataByte = BuildMultipartBody(body);
return item;
});
}
internal static byte[] BuildMultipartBody(string body)
{
if (body == null) throw new ArgumentNullException(nameof(body));
using (var stream = new MemoryStream())
{
// 保留原上传协议:<!> 包围的片段为本地文件路径,其余片段规范化为 CRLF。
var parts = body.Split(new[] { "<!>" }, StringSplitOptions.None);
if (parts.Length % 2 == 0) throw new ArgumentException("上传文件标记必须成对出现。", nameof(body));
for (int i = 0; i < parts.Length; i++)
{
string part = parts[i];
byte[] bytes = i % 2 == 1 ? File.ReadAllBytes(part) :
Encoding.UTF8.GetBytes(part.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", "\r\n"));
stream.Write(bytes, 0, bytes.Length);
}
return stream.ToArray();
}
}
internal static HttpItem CreateRequest(ShopLoginInfo shop, string url, string referer, MethodType method,
string data = null, bool assistant = false, bool document = false, bool image = false, bool bizCookiesOnly = false)
{
if (shop == null) throw new ArgumentNullException(nameof(shop));
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri) || uri.Scheme != Uri.UriSchemeHttps ||
(image ? uri.Host != "westorealpha.video.qq.com" : uri.Host != "store.weixin.qq.com"))
throw new ArgumentException("微信请求地址不在允许的 HTTPS 域名内。", nameof(url));
if (data != null) Newtonsoft.Json.Linq.JToken.Parse(data);
var cookies = JsonHelper.DeserializeJsonToList<CefSharp.Cookie>(Convert.ToString(shop.Cookies)) ?? new List<CefSharp.Cookie>();
var item = new HttpItem
{
URL = url,
Method = method,
Referer = document ? "" : referer,
Accept = document ? "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" : "application/json, text/plain, */*",
ContentType = method == MethodType.Post ? "application/json" : null,
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
Encoding = Encoding.UTF8,
PostEncoding = Encoding.UTF8,
Postdata = data,
PostDataType = PostDataType.String,
KeepAlive = true,
Expect100Continue = false,
Allowautoredirect = true,
ReadWriteTimeout = 300000,
Cookie = image ? "" : string.Concat(cookies.Where(c => !(method == MethodType.Get || bizCookiesOnly) || c.Name.StartsWith("biz", StringComparison.Ordinal)).Select(c => c.Name + "=" + c.Value + ";")),
Header = new WebHeaderCollection()
};
item.Header["sec-ch-ua"] = "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\"";
item.Header["sec-ch-ua-mobile"] = "?0";
item.Header["sec-ch-ua-platform"] = "\"Windows\"";
item.Header["Sec-Fetch-Site"] = document ? "none" : image ? "same-site" : "same-origin";
item.Header["Sec-Fetch-Mode"] = document ? "navigate" : "cors";
item.Header["Sec-Fetch-Dest"] = document ? "document" : "empty";
// HttpHelper 只解压 gzip,因此不宣告支持 br、zstd、deflate。
item.Header[HttpRequestHeader.AcceptEncoding] = "gzip";
item.Header[HttpRequestHeader.AcceptLanguage] = method == MethodType.Post && !image && !bizCookiesOnly ?
"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6" : "zh-CN,zh;q=0.9";
if (document)
{
item.Header["Upgrade-Insecure-Requests"] = "1";
item.Header["Sec-Fetch-User"] = "?1";
}
else if (!image)
{
item.Header["wecom_magic"] = "";
item.Header["supplier_magic"] = "";
item.Header["mcn_magic"] = "";
item.Header["potter-scene"] = "weixinShop";
item.Header["biz_magic"] = assistant ? "" : cookies.FirstOrDefault(c => c.Name == "biz_magic")?.Value ?? "";
item.Header["talent_magic"] = assistant ? cookies.FirstOrDefault(c => c.Name == "talent_magic")?.Value ?? "" : "";
}
if (method == MethodType.Post) item.Header["Origin"] = ShopHost;
return item;
}
private static string Send(Func<HttpItem> createRequest)
{
try
{
return HttpHelper.Request(createRequest()).Html;
}
catch (Exception ex)
{
// 兼容现有调用约定:传输失败返回错误文字,业务失败返回原 JSON。
return ex.Message;
}
}
}
}
+163
View File
@@ -0,0 +1,163 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店图片、文件分片及视频凭证接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxMediaApi
{
/// <summary>获取商品视频上传临时凭证,对应 WXVideoUploader.GetUploadTempImgAuth 的店铺请求。</summary>
/// <param name="shop">店铺登录信息,Cookies 为原程序保存的 Cookie 列表 JSON。</param>
/// <param name="productId">正在编辑的商品 ID,用于构造原视频上传页面 Referer。</param>
/// <param name="uploadScene">视频上传场景,原视频上传流程使用 100。</param>
/// <returns>含临时上传凭证的原始 JSON 或传输错误文字;调用方检查 code。</returns>
/// <remarks>此方法只获取店铺端凭证;视频域名的分片、转码流程仍由原上传器实现。</remarks>
public static string GetVideoUploadAuth(ShopLoginInfo shop, string productId, string uploadScene = "100")
{
return WxHttpClient.SendMedia(shop, "/shop-faas/mmecchannelspicture/cgi/getUploadTempImgAuth?token=&lang=zh_CN&uploadScene=" + Uri.EscapeDataString(uploadScene),
productId);
}
/// <summary>将已完成转码的视频播放地址换成商品媒体地址,对应 WXVideoUploader.GetMultiMediaDownloadUrl。</summary>
/// <param name="shop">店铺登录信息,Cookies 为原程序保存的 Cookie 列表 JSON。</param>
/// <param name="productId">正在编辑的商品 ID,用于构造原视频上传页面 Referer。</param>
/// <param name="playUrl">原视频上传流程轮询转码成功后返回的播放 URL。</param>
/// <returns>媒体下载地址的原始 JSON 或传输错误文字;调用方检查 code。</returns>
public static string GetMultiMediaDownloadUrl(ShopLoginInfo shop, string productId, string playUrl)
{
return WxHttpClient.SendMedia(shop, "/shop-faas/mmecchannelspicture/cgi/getMultiMediaDownloadUrl?token=&lang=zh_CN",
productId, new JObject { ["playUrl"] = playUrl }.ToString());
}
/// <summary>获取图片上传临时凭证,供 UploadImage 使用。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="uploadScene">上传场景的接口值,图片上传原调用使用 3。 默认值:3。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.getUploadTempImgAuth。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetUploadTempImgAuth(ShopLoginInfo shop, int uploadScene = 3)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecchannelspicture/cgi/getUploadTempImgAuth?token=&lang=zh_CN&uploadScene=" + uploadScene;
string refere = "https://store.weixin.qq.com/shop/goods/entry";
var result = WxHttpClient.Get(shop, url, refere);
return result;
}
/// <summary>使用临时凭证向微信图片上传域名提交 Base64 图片。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="imgBase64">纯 Base64 图片数据,不含 data:image 前缀。</param>
/// <param name="dis_k">GetUploadTempImgAuth 返回的临时上传签名 dis_k。</param>
/// <param name="dis_t">GetUploadTempImgAuth 返回的临时上传时间 dis_t,原值透传。</param>
/// <param name="ext">GetUploadTempImgAuth 返回的 ext 凭证,原值透传。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.adtimageupload。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string UploadImage(ShopLoginInfo shop, string imgBase64, string dis_k, long dis_t, string ext)
{
string url = "https://westorealpha.video.qq.com/adtimageupload";
string referer = "https://store.weixin.qq.com/";
string body = imgBase64;
var result = WxHttpClient.UploadImage(shop, url, body, dis_k, dis_t, ext, referer);
return result;
}
/// <summary>初始化商品编辑资料的分片文件上传。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="submitJson">初始化分片上传请求的完整 JSON。</param>
/// <param name="prodId">微信商品 ID。</param>
/// <param name="time1">原商品 lastEditDraftTime 值,按接口返回值透传到编辑页面上下文。</param>
/// <param name="time2">原商品 listingTime 值,按接口返回值透传到编辑页面上下文。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.initUploadPart。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string InitUploadPart(ShopLoginInfo shop, string submitJson, string prodId, int time1, int time2)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodefiletransfer/filecos/initUploadPart?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + prodId + "&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo=" + "{%22isEditingContinued%22:true,%22lastEditDraftTime%22:" + time1 + "," + "%22listingTime%22:" + time2 + "}";
string body = submitJson;
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>上传商品编辑文件的第一个分片,使用原 multipart 协议。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="initFileName">初始化分片上传接口返回的文件名。</param>
/// <param name="blobPath">待上传文件的本地完整路径;不是网络图片 URL。</param>
/// <param name="uploadId">初始化分片上传返回的上传任务 ID。</param>
/// <param name="prodId">微信商品 ID。</param>
/// <param name="time1">原商品 lastEditDraftTime 值,按接口返回值透传到编辑页面上下文。</param>
/// <param name="time2">原商品 listingTime 值,按接口返回值透传到编辑页面上下文。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.uploadPartBinary。
/// 保留旧行为:partSeq 固定为 1,本方法不负责多分片调度。文件必须存在且可读。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string UploadPartBinary(ShopLoginInfo shop, string initFileName, string blobPath, string uploadId, string prodId, int time1, int time2)
{
// shortcut: 沿用原实现仅上传 partSeq=1,需要多分片时再增加分片调度。
string boundaryLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
string boundaryStr = "----WebKitFormBoundary";
for (int i = 0; i < 16; i++)
{
boundaryStr += boundaryLetters[Randomx.GetId(boundaryLetters.Length)];
}
string url = "https://store.weixin.qq.com/shop-faas/mmecnodefiletransfer/filecos/uploadPartBinary?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + prodId + "&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo=" + "{%22isEditingContinued%22:true,%22lastEditDraftTime%22:" + time1 + "," + "%22listingTime%22:" + time2 + "}";
string body = @"--" + boundaryStr + @"
Content-Disposition: form-data; name=""name""
" + initFileName + @"
--" + boundaryStr + @"
Content-Disposition: form-data; name=""uploadId""
" + uploadId + @"
--" + boundaryStr + @"
Content-Disposition: form-data; name=""partSeq""
1
--" + boundaryStr + @"
Content-Disposition: form-data; name=""file""; filename=""blob""
Content-Type: application/octet-stream
<!>" + blobPath + @"<!>
--" + boundaryStr + @"--
";
var result = WxHttpClient.UploadMultipart(shop, url, body, boundaryStr, referer);
return result;
}
/// <summary>提交分片上传完成信息。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="completeJson">分片上传完成请求的完整 JSON,需包含此前上传返回的信息。</param>
/// <param name="prodId">微信商品 ID。</param>
/// <param name="time1">原商品 lastEditDraftTime 值,按接口返回值透传到编辑页面上下文。</param>
/// <param name="time2">原商品 listingTime 值,按接口返回值透传到编辑页面上下文。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.completeUploadPart。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string CompleteUploadPart(ShopLoginInfo shop, string completeJson, string prodId, int time1, int time2)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodefiletransfer/filecos/completeUploadPart?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + prodId + "&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo=" + "{%22isEditingContinued%22:true,%22lastEditDraftTime%22:" + time1 + "," + "%22listingTime%22:" + time2 + "}";
string body = completeJson;
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
}
}
+245
View File
@@ -0,0 +1,245 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店订单查询、备注、解密及发货接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxOrderApi
{
/// <summary>按订单状态分页查询订单,可指定创建时间范围。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="orderStatus">微信订单状态筛选值,原列表查询默认使用 20;以当前接口枚举为准。 默认值:20。</param>
/// <param name="pageNum">页码,从 1 开始。 默认值:1。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:30。</param>
/// <param name="timeStart">订单创建开始时间的 Unix 毫秒时间戳;与 timeEnd 同时提供才生效。 默认值:null。</param>
/// <param name="timeEnd">订单创建结束时间的 Unix 毫秒时间戳;与 timeStart 同时提供才生效。 默认值:null。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.orderListSearch。
/// 保留旧行为:同时指定开始与结束时间时,实际 pageSize 固定为 30。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string OrderListSearch(ShopLoginInfo shop, int orderStatus = 20, int pageNum = 1, int pageSize = 30, long? timeStart = null, long? timeEnd = null)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/list/cgi/orderSearch?token=&lang=zh_CN";
string body = @"{""isSearch"":false,""pageSize"":" + pageSize + @",""overTime"":0,""pengingShipOneDay"":0,""pengingShipSixHour"":0,""expediteDelivery"":0,""stockoutPunishAlert"":0,""waybillStatus"":0,""pageNum"":1" + @",""onAftersaleOrderExist"":0,""orderStatus"":" + orderStatus + @"}";
if (pageNum > 1)
body = @"{""isSearch"":false,""pageSize"":" + pageSize + @",""overTime"":0,""pengingShipOneDay"":0,""pengingShipSixHour"":0,""expediteDelivery"":0,""stockoutPunishAlert"":0,""waybillStatus"":0,""pageNum"":1" + @",""onAftersaleOrderExist"":0,""orderStatus"":" + orderStatus + @",""page"":" + pageNum + @"}";
if (timeStart != null && timeEnd != null)
body = @"{""isSearch"":true,""pageSize"":30,""orderId"":"""",""orderTime"":{""type"":0,""time"":[" + timeStart + @"," + timeEnd + @"]},
""telNumber"":"""",""title"":"""",""receiverName"":"""",""finderNickName"":"""",""merchantNotes"":"""",""merchantNotesTagColor"":0,
""waybillId"":"""",""productCode"":"""",""inspectStatus"":"""",""finderWay"":0,""searchOrderType"":0,""payMethod"":0,""orderChannel"":0,
""bulkbuyActivityId"":"""",""deliveryNegotiationFlag"":0,""transactionId"":"""",""page"":" + pageNum + @",""overTime"":0,""pengingShipOneDay"":0,
""pengingShipSixHour"":0,""expediteDelivery"":0,""stockoutPunishAlert"":0,""waybillStatus"":0,""pageNum"":1,""onAftersaleOrderExist"":0,
""orderStatus"":" + orderStatus + @",""startCreateTime"":" + timeStart + @",""endCreateTime"":" + timeEnd + @"}";
string refere = "https://store.weixin.qq.com/shop/order/list";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>查询订单;单参数重载按订单号查询,双参数重载按商品标题和收件人查询。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="orderId">微信订单 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.orderSearch。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string OrderSearch(ShopLoginInfo shop, string orderId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/list/cgi/orderSearch?token=&lang=zh_CN";
string body = @"{""isSearch"":true,""pageSize"":30,""overTime"":0,""pengingShipOneDay"":0,""pengingShipSixHour"":0,""expediteDelivery"":0,""stockoutPunishAlert"":0,
""waybillStatus"":0,""pageNum"":1,""onAftersaleOrderExist"":0,""orderStatus"":0,""orderId"":""" + orderId + @""",
""orderTime"":{""type"":0,""time"":[null,null]},""telNumber"":"""",""title"":"""",""receiverName"":"""",""finderNickName"":"""",
""merchantNotes"":"""",""merchantNotesTagColor"":0,""waybillId"":"""",""productCode"":"""",""inspectStatus"":"""",""finderWay"":0,
""searchOrderType"":0,""payMethod"":0,""orderChannel"":0,""bulkbuyActivityId"":"""",""deliveryNegotiationFlag"":0,""transactionId"":"""",
""page"":1,""startCreateTime"":null,""endCreateTime"":null}";
string refere = "https://store.weixin.qq.com/shop/order/list";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>给订单添加商家备注及颜色标签。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="orderId">微信订单 ID。</param>
/// <param name="notes">商家订单备注文本。</param>
/// <param name="tagColor">商家备注颜色的接口值,0 沿用原代码默认值。 默认值:0。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.addNotes。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string AddNotes(ShopLoginInfo shop, string orderId, string notes, int tagColor = 0)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/common/cgi/batchMerchantNotes?token=&lang=zh_CN";
string body = @"{""items"":[{""orderId"":""" + orderId + @""",""merchantNotes"":""" + notes + @""",""merchantNotesTagColor"":" + tagColor + @"}]}";
string refere = "https://store.weixin.qq.com/shop/order/list";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>申请解密订单信息,返回平台允许显示的收件信息。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="orderId">微信订单 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.decryptOrder。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string DecryptOrder(ShopLoginInfo shop, string orderId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/common/cgi/decryptOrder?token=&lang=zh_CN";
string body = @"{""id"":""" + orderId + @"""}";
string refere = "https://store.weixin.qq.com/shop/order/list";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>提交订单发货,原实现使用 OTHER 物流公司编码。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="orderId">微信订单 ID。</param>
/// <param name="waybillId">物流运单号。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.orderSendOut。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string OrderSendOut(ShopLoginInfo shop, string orderId, string waybillId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/ship/cgi/orderSendOut?token=&lang=zh_CN";
string body = @"{""orderId"":""" + orderId + @""",""deliveryProduct"":{""deliveryId"":""OTHER"",""waybillId"":""" + waybillId + @""",""isAllProduct"":true,""deliverType"":1}}";
string refere = "https://store.weixin.qq.com/shop/order/list?type=3";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>修改订单已登记的物流公司、运单号和包裹商品信息。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="param">物流变更参数,包含订单号及各包裹变更明细。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.updateDeliveryInfo。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string UpdateDeliveryInfo(ShopLoginInfo shop, UpdateDeliverInfoParam param)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/ship/cgi/updateDeliveryInfo?token=&lang=zh_CN";
string body = JsonHelper.SerializeObject(param);
string refere = "https://store.weixin.qq.com/shop/order/list?type=3";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>查询订单发货初始化数据,用于取得包裹和物流相关信息。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="orderId">微信订单 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.initDeliveryInfo。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string InitDeliveryInfo(ShopLoginInfo shop, string orderId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/ship/cgi/initShipData?token=&lang=zh_CN";
string body = @"{""id"":""" + orderId + @"""}";
string refere = "https://store.weixin.qq.com/shop/order/list";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>查询订单;单参数重载按订单号查询,双参数重载按商品标题和收件人查询。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodTitle">订单中的商品标题筛选条件。</param>
/// <param name="receiverName">收件人姓名筛选条件。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopOptimizeForm.cs,ShopOptimize.orderSearch。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string OrderSearch(ShopLoginInfo shop, string prodTitle, string receiverName)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/list/cgi/orderSearch?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/order/list";
string body = @"{""isSearch"":true,""pageSize"":30,""orderId"":"""",""orderTime"":{""type"":0,""time"":[null,null]},
""telNumber"":"""",""title"":""复古刺绣盘扣麻棉衬衫女2022夏新款中式禅意茶服宽松短款v领上衣"",""receiverName"":""浅菊夏離、"",""finderNickName"":"""",
""merchantNotes"":"""",""merchantNotesTagColor"":0,""waybillId"":"""",""productCode"":"""",""inspectStatus"":"""",""finderWay"":0,""searchOrderType"":0,
""payMethod"":0,""orderChannel"":0,""bulkbuyActivityId"":"""",""deliveryNegotiationFlag"":0,""transactionId"":"""",""page"":1,""startCreateTime"":null,
""endCreateTime"":null}";
body = @"{""isSearch"":true,""pageSize"":30,""orderId"":"""",""orderTime"":{""type"":0,""time"":[null,null]},
""telNumber"":"""",""title"":""" + prodTitle + @""",""receiverName"":""" + receiverName + @""",""finderNickName"":"""",""merchantNotes"":"""",""merchantNotesTagColor"":0,""waybillId"":"""",""productCode"":"""",""inspectStatus"":"""",""finderWay"":0,""searchOrderType"":0,""payMethod"":0,""orderChannel"":0,""bulkbuyActivityId"":"""",""deliveryNegotiationFlag"":0,""transactionId"":"""",""page"":1,""startCreateTime"":null,""endCreateTime"":null}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>按订单号字符串查询订单列表。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="orderIds">订单号查询字符串,格式沿用原订单查询接口。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopOptimizeForm.cs,ShopOptimize.orderSearchByOrderId。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SearchOrdersByIds(ShopLoginInfo shop, string orderIds)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/list/cgi/orderSearch?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/order/list";
string body = @"{""isSearch"":true,""pageSize"":30,""orderId"":""" + orderIds + @""",""orderTime"":{""type"":0,""time"":[null,null]},""telNumber"":"""",""title"":"""",""receiverName"":"""",""finderNickName"":"""",""merchantNotes"":"""",""merchantNotesTagColor"":0,""waybillId"":"""",""productCode"":"""",""inspectStatus"":"""",""finderWay"":0,""searchOrderType"":0,""payMethod"":0,""orderChannel"":0,""bulkbuyActivityId"":"""",""deliveryNegotiationFlag"":0,""transactionId"":"""",""page"":1,""startCreateTime"":null,""endCreateTime"":null}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>提交订单补发,包含物流和补发商品明细。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="orderId">微信订单 ID。</param>
/// <param name="deliveryId">微信物流公司编码。</param>
/// <param name="waybillId">物流运单号。</param>
/// <param name="productId">微信商品 ID。</param>
/// <param name="skuId">商品规格 SKU ID。</param>
/// <param name="productCnt">本次补发的商品件数。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopOptimizeForm.cs,ShopOptimize.orderCompensationDelivery。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string OrderCompensationDelivery(ShopLoginInfo shop, string orderId, string deliveryId, string waybillId, string productId, string skuId, int productCnt)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/ship/cgi/compensationDelivery?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/order/list";
string body = @"{""orderId"":""" + orderId + @""",""reason"":1,""deliveryProductInfo"":[{""deliveryId"":""" + deliveryId + @""",""waybillId"":""" + waybillId + @""",""productInfos"":[{""productId"":""" + productId + @""",""skuId"":""" + skuId + @""",""productCnt"":" + productCnt + @"}]}]}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>按订单号或手机号查询订单,支持指定订单时间范围。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="orderId">微信订单 ID。</param>
/// <param name="telNumber">收件联系电话或原查询接口支持的手机号条件。</param>
/// <param name="orderStatus">微信订单状态筛选值,原列表查询默认使用 20;以当前接口枚举为准。 默认值:20。</param>
/// <param name="page">页码,从 1 开始。 默认值:1。</param>
/// <param name="startTime">Unix 毫秒时间戳字符串;空值使用本机一个月前当天零点。 默认值:&quot;&quot;。</param>
/// <param name="endTime">Unix 毫秒时间戳字符串;空值使用本机今天零点。 默认值:&quot;&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\TalkForms\PDDBuyerOrderListForm.cs,WxOrder.OrderSeach。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SearchOrdersByContact(ShopLoginInfo shop, string orderId, string telNumber, int orderStatus = 20, int page = 1, string startTime = "", string endTime = "")
{
if (string.IsNullOrWhiteSpace(startTime))
startTime = BaseClass.DateTimeToTimestampMilliseconds(DateTime.Now.Date.AddMonths(-1)).ToString();
if (string.IsNullOrWhiteSpace(endTime))
endTime = BaseClass.DateTimeToTimestampMilliseconds(DateTime.Now.Date).ToString();
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/list/cgi/orderSearch?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/order/list";
string body = @"{""isSearch"":true,""pageSize"":100,""overTime"":0,""pengingShipOneDay"":0,""pengingShipSixHour"":0,""expediteDelivery"":0," + @"""stockoutPunishAlert"":0,""waybillStatus"":0,""pageNum"":1,""onAftersaleOrderExist"":0,""orderStatus"":" + orderStatus + @",""page"":" + page + @",""orderId"":""" + orderId + @""",""orderTime"":{""type"":0,""time"":[" + startTime + @"," + endTime + @"]}," + @"""telNumber"":""" + telNumber + @""",""title"":"""",""receiverName"":"""",""finderNickName"":"""",""merchantNotes"":""""," + @"""merchantNotesTagColor"":0,""waybillId"":"""",""productCode"":"""",""inspectStatus"":"""",""finderWay"":0,""searchOrderType"":0," + @"""payMethod"":0,""orderChannel"":0,""bulkbuyActivityId"":"""",""deliveryNegotiationFlag"":0,""transactionId"":""""," + @"""startCreateTime"":" + startTime + @",""endCreateTime"":" + endTime + @"}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
}
}
+595
View File
@@ -0,0 +1,595 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店商品查询、发布、编辑、库存及清理接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxProductApi
{
/// <summary>获取平台推荐商品及指定时间范围内的推荐表现。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="startMs">统计开始时间的 Unix 毫秒时间戳。</param>
/// <param name="endMs">统计结束时间的 Unix 毫秒时间戳。</param>
/// <param name="page">页码,从 1 开始。 默认值:1。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:10。</param>
/// <param name="dateRange">统计区间对应的平台日期范围值,原调用使用 30 天。 默认值:30。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\BLL\Wx\WxPlatformRecommendProdManage.cs,WxPlatformRecommendProdManage.getPlatformRecommend。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetPlatformRecommend(ShopLoginInfo shop, long startMs, long endMs, int page = 1, int pageSize = 10, int dateRange = 30)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradebase/cgi/shop/getShopRecommendProducts?token=&lang=zh_CN";
string data = @"{""isToday"":false,""offset"":" + Math.Max(0, page - 1) * pageSize + @",""limit"":" + pageSize + @",""sort"":[""product_view_uv"",""desc""]," + @"""time_query"":{""dateFormat"":2,""dateType"":0,""dateRange"":" + dateRange + @",""startMs"":" + startMs + @",""endMs"":" + endMs + @"}}";
string referer = "https://store.weixin.qq.com/shop/platformrecommend/recommendationFeed";
var result = WxHttpClient.Post(shop, url, data, referer);
return result;
}
/// <summary>按销售状态查询商品列表,使用原平台推荐页面的排序方式。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="pageNum">页码,从 1 开始。 默认值:1。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:50。</param>
/// <param name="status">商品销售状态:-1 全部、5 在售、11 下架,沿用原代码。 默认值:5。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\BLL\Wx\WxPlatformRecommendProdManage.cs,WxPlatformRecommendProdManage.searchProductWithSaleStatus。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SearchProductWithSaleStatus(ShopLoginInfo shop, int pageNum = 1, int pageSize = 50, int status = 5)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?token=&lang=zh_CN&pageSize=" + pageSize + "&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&fromProductManager=1&pageNum=" + pageNum + "&status[]=" + status + "&sortType=6";
string refere = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_ON&currentPage=" + pageNum;
var result = WxHttpClient.Get(shop, url, refere);
return result;
}
/// <summary>批量查询商品指标,用于平台推荐商品的数据分析。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="spuIdLst">微信商品 SPU ID 列表。</param>
/// <param name="pageNum">页码,从 1 开始。 默认值:1。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:50。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\BLL\Wx\WxPlatformRecommendProdManage.cs,WxPlatformRecommendProdManage.getProductMetricList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetProductMetricList(ShopLoginInfo shop, List<string> spuIdLst, int pageNum = 1, int pageSize = 50)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductlist/cgi/goods/getProductMetricList?token=&lang=zh_CN";
string refere = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_ON&currentPage=" + pageNum;
string body = @"{""spuIds"":[""10000941685997"",""10000941606843"",""10000941606678"",""10000941814176"",""10000941730758"",""10000941794530"",""10000941656198"",""10000941838792"",""10000941813664"",""10000941507483"",""10000941644842"",""10000941511634"",""10000941566070"",""10000941773596"",""10000941605208"",""10000941768333"",""10000941442087"",""10000941595429"",""10000941600162"",""10000941382412"",""10000941506207"",""10000941599882"",""10000941743120"",""10000941708791"",""10000941480748"",""10000941505847"",""10000941377556"",""10000941327242"",""10000941519895"",""10000941574393"",""10000941708024"",""10000941543916"",""10000941445436"",""10000941287155"",""10000941297349"",""10000941543530"",""10000941603084"",""10000941360832"",""10000941484113"",""10000941137242"",""10000941468968"",""10000941271777"",""10000941563120"",""10000941528202"",""10000941226651"",""10000941136287"",""10000940942388"",""10000941389756"",""10000941261318"",""10000940962314""],""limit"":300,""offset"":0,""sortMetricCode"":""shopxspu_growth_pay_product_cnt_30d_2"",""sortRule"":""desc"",""sceneType"":""0""}";
var data = new Dictionary<string, object>();
data["spuIds"] = spuIdLst;
data["limit"] = pageSize * 6;
data["offset"] = 0;
data["sortMetricCode"] = "shopxspu_growth_pay_product_cnt_30d_2";
data["sortRule"] = "desc";
data["sceneType"] = "0";
body = JsonHelper.SerializeObject(data);
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>修改商品 SKU 售价;结构化参数重载可提交完整价格变更列表。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="spuId">微信商品 SPU ID。</param>
/// <param name="skuId">商品规格 SKU ID。</param>
/// <param name="newPrice">新的 SKU 售价,单位为分,直接作为 salePrice 发送。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.EditPrice。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string EditPrice(ShopLoginInfo shop, string spuId, string skuId, int newPrice)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductlist/cgi/goods/listingUpdatePrice?token=&lang=zh_CN";
string body = @"{""skuList"":[{""spuId"":" + spuId + @",""skuId"":""" + skuId + @""",""salePrice"":" + newPrice + @"}],""uploadSource"":6}";
string refere = "https://store.weixin.qq.com/shop/goods/list";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>修改商品 SKU 售价;结构化参数重载可提交完整价格变更列表。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="priceData">包含 skuList 等字段的完整改价 JSON 对象;salePrice 单位为分。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.EditPrice。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string EditPrice(ShopLoginInfo shop, JObject priceData)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductlist/cgi/goods/listingUpdatePrice?token=&lang=zh_CN";
string body = JsonHelper.SerializeObject(priceData);
string refere = "https://store.weixin.qq.com/shop/goods/list";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>按商品 ID 批量查询 SKU 库存明细。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="spuIds">逗号分隔的商品 ID 数值字符串,直接放入 productIdList 数组。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.getSkuBySpu。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetSkuBySpu(ShopLoginInfo shop, string spuIds)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductlist/cgi/goods/getStockBySpu?token=&lang=zh_CN";
string body = @"{""productIdList"":[" + spuIds + @"]}";
string refere = "https://store.weixin.qq.com/shop/goods/list";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>按增量增加指定 SKU 库存。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="spuId">微信商品 SPU ID。</param>
/// <param name="skuId">商品规格 SKU ID。</param>
/// <param name="num">增减库存件数的整数字符串,原代码直接写入 JSON 数值位置。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.batchUpdateStockAdd。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string BatchUpdateStockAdd(ShopLoginInfo shop, string spuId, string skuId, string num)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductlist/cgi/goods/batchUpdateStock?token=&lang=zh_CN";
string body = @"{""skuList"":[{""spuId"":""" + spuId + @""",""skuId"":""" + skuId + @""",""diffType"":1,""num"":" + num + "}]}";
string refere = "https://store.weixin.qq.com/shop/goods/list";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>按减量减少指定 SKU 库存。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="spuId">微信商品 SPU ID。</param>
/// <param name="skuId">商品规格 SKU ID。</param>
/// <param name="num">增减库存件数的整数字符串,原代码直接写入 JSON 数值位置。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.batchUpdateStockReduce。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string BatchUpdateStockReduce(ShopLoginInfo shop, string spuId, string skuId, string num)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductlist/cgi/goods/batchUpdateStock?token=&lang=zh_CN";
string body = @"{""skuList"":[{""spuId"":""" + spuId + @""",""skuId"":""" + skuId + @""",""diffType"":2,""num"":" + num + "}]}";
string refere = "https://store.weixin.qq.com/shop/goods/list";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>按商家商品编码查询在售商品,可追加第二个编码。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="extCode">商家商品编码,用于 spuCode 查询。</param>
/// <param name="extCode2">可选的第二个商家商品编码,非空时与第一个编码用逗号连接。 默认值:&quot;&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.searchProduct。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SearchProductByCode(ShopLoginInfo shop, string extCode, string extCode2 = "")
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?" + "token=&lang=zh_CN&pageSize=20&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&pageNum=1&status[]=5&spuCode=" + extCode;
if (!string.IsNullOrEmpty(extCode2))
url += "," + extCode2;
string refere = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_ON";
var result = WxHttpClient.Get(shop, url, refere);
return result;
}
/// <summary>按微信商品 SPU ID 查询商品。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="spuId">微信商品 SPU ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.searchProductWithSpuId。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SearchProductWithSpuId(ShopLoginInfo shop, string spuId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?" + "token=&lang=zh_CN&pageSize=20&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&pageNum=1&status[]=-1&spuId=" + spuId;
string refere = "https://store.weixin.qq.com/shop/goods/list";
var result = WxHttpClient.Get(shop, url, refere);
return result;
}
/// <summary>使用已经 URL 编码的标题查询商品。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="urlEncodeTitle">已经执行 UTF-8 URL 编码的商品标题,本方法不会再次编码。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.searchProductWithTitle。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SearchProductWithTitle(ShopLoginInfo shop, string urlEncodeTitle)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?" + "token=&lang=zh_CN&pageSize=20&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&pageNum=1&status[]=-1&title=" + urlEncodeTitle;
string refere = "https://store.weixin.qq.com/shop/goods/list";
var result = WxHttpClient.Get(shop, url, refere);
return result;
}
/// <summary>根据商品标题、图片和类目生成短标题。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="getShortTitleParam">短标题生成参数,包含原商品标题、图片及类目。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.genProductShortTitle。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GenProductShortTitle(ShopLoginInfo shop, WXGetShortTitleParam getShortTitleParam)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/common/cgi/goods/genProductShortTitle?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
string body = JsonHelper.SerializeObject(getShortTitleParam);
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>保存商品发布草稿;序列化时忽略 null 字段。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodParam">商品发布或编辑参数,沿用 AllBase 中的 WXUploadProductParam。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.uploadProductDraft。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string UploadProductDraft(ShopLoginInfo shop, WXUploadProductParam prodParam)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/common/cgi/goods/uploadProductDraft?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
JsonSerializerSettings jsonSetting = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
prodParam.type = 1;
var prodStr = JsonConvert.SerializeObject(prodParam, jsonSetting);
JObject jObj = new JObject();
jObj.Add("data", prodStr);
string body = JsonHelper.SerializeObject(jObj);
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>提交商品发布或更新请求;序列化时忽略 null 字段。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodParam">商品发布或编辑参数,沿用 AllBase 中的 WXUploadProductParam。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.upProductV2。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string UpProductV2(ShopLoginInfo shop, WXUploadProductParam prodParam)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/upProductV2?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
JsonSerializerSettings jsonSetting = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
var prodStr = JsonConvert.SerializeObject(prodParam, jsonSetting);
JObject jObj = new JObject();
jObj.Add("data", prodStr);
string body = JsonHelper.SerializeObject(jObj);
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询商品草稿上传状态。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="productId">微信商品 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.checkProductUpload。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string CheckProductUpload(ShopLoginInfo shop, string productId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/checkUploadProductDraftStatus?token=&lang=zh_CN&productKey=%7B%22productId%22:" + productId + "%7D&preview=false";
string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + productId + "&isUpdateAuditFree=0&source=list_edit&continueEditInfo=" + "{%22isEditingContinued%22:false,%22lastEditDraftTime%22:0,%22listingTime%22:0}";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>在编辑状态商品列表中按商品 ID 查询上传结果。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="productId">微信商品 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.SearchProductUpload。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SearchProductUpload(ShopLoginInfo shop, string productId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?token=&lang=zh_CN&pageSize=20&productStatus[]=-1" + "&productSource=[1,16,32]&searchSource=1&useNew=true&fromProductManager=1&pageNum=1&status[]=2&spuId=" + productId;
string referer = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_EDIT";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>提交原始商品 JSON 发布或更新请求。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodStr">完整商品发布或编辑 JSON 字符串。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.upProductJObjectV2。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string UpProductJObjectV2(ShopLoginInfo shop, string prodStr)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/upProductV2?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry";
JObject jObj = new JObject();
jObj.Add("data", prodStr);
string body = JsonHelper.SerializeObject(jObj);
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>获取商品编辑详情,用于在原商品数据基础上修改。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="productId">微信商品 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.getEditProductV2。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetEditProductV2(ShopLoginInfo shop, string productId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/getEditProductV2?token=&lang=zh_CN&productKey=%7B%22productId%22:" + productId + "%7D&needRealStock=true&preview=false&release=false";
string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + productId + "&isUpdateAuditFree=0&source=list_edit&continueEditInfo={%22isEditingContinued%22:false,%22lastEditDraftTime%22:0,%22listingTime%22:0}";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>提交免审商品编辑;支持商品模型或原始 JSON 请求体。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodParam">商品发布或编辑参数,沿用 AllBase 中的 WXUploadProductParam。</param>
/// <param name="prodId">微信商品 ID。</param>
/// <param name="time1">原商品 lastEditDraftTime 值,按接口返回值透传到编辑页面上下文。</param>
/// <param name="time2">原商品 listingTime 值,按接口返回值透传到编辑页面上下文。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.listingAuditFree。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string ListingAuditFree(ShopLoginInfo shop, WXUploadProductParam prodParam, string prodId, int time1, int time2)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/listingAuditFree?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + prodId + "&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo=" + "{%22isEditingContinued%22:true,%22lastEditDraftTime%22:" + time1 + "," + "%22listingTime%22:" + time2 + "}";
JsonSerializerSettings jsonSetting = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
var prodStr = JsonConvert.SerializeObject(prodParam, jsonSetting);
JObject jObj = new JObject();
jObj.Add("data", prodStr);
string body = JsonHelper.SerializeObject(jObj);
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>提交免审商品编辑;支持商品模型或原始 JSON 请求体。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodStr">完整商品发布或编辑 JSON 字符串。</param>
/// <param name="prodId">微信商品 ID。</param>
/// <param name="time1">原商品 lastEditDraftTime 值,按接口返回值透传到编辑页面上下文。</param>
/// <param name="time2">原商品 listingTime 值,按接口返回值透传到编辑页面上下文。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.listingAuditFree。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string ListingAuditFree(ShopLoginInfo shop, string prodStr, string prodId, int time1, int time2)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/listingAuditFree?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + prodId + "&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo=" + "{%22isEditingContinued%22:true,%22lastEditDraftTime%22:" + time1 + "," + "%22listingTime%22:" + time2 + "}";
JsonSerializerSettings jsonSetting = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
JObject jObj = new JObject();
jObj.Add("data", prodStr);
string body = JsonHelper.SerializeObject(jObj);
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>获取商品信息的 AI 推荐内容。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="recommendParam">商品信息推荐参数,包含商品 ID 等原接口字段。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.generalProductInfoRecommend。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GeneralProductInfoRecommend(ShopLoginInfo shop, WXUploadProductInfoRecommendParam recommendParam)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/aiRecommendCompat/cgi/goods/generalProductInfoRecommend?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + recommendParam.productId + "&isUpdateAuditFree=0&source=list_edit&continueEditInfo={%22isEditingContinued%22:false,%22lastEditDraftTime%22:0,%22listingTime%22:0}";
JsonSerializerSettings jsonSetting = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
string body = JsonConvert.SerializeObject(recommendParam, jsonSetting);
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>按状态、商品 ID 列表及排序查询商品,用于商品清理页面。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="pageNum">页码,从 1 开始。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:50。</param>
/// <param name="prodIds">逗号分隔的商品 ID 字符串;批量操作直接放入 JSON 数组,不含方括号。 默认值:null。</param>
/// <param name="status">商品销售状态:-1 全部、5 在售、11 下架,沿用原代码。 默认值:5。</param>
/// <param name="sortType">商品排序的接口值;null 使用平台默认排序。 默认值:null。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdClearNoVisit260606Form.cs,WXClearNoVisit260606.searchProduct。
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdClearNoVisitForm.cs,WXClearNoVisit.searchProduct。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SearchProduct(ShopLoginInfo shop, int pageNum, int pageSize = 50, string prodIds = null, int status = 5, int? sortType = null)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?token=&lang=zh_CN&" + "pageSize=" + pageSize + "&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&pageNum=" + pageNum + "&status[]=" + status;
if (prodIds != null)
url += "&spuId=" + prodIds;
if (sortType != null)
url += "&sortType=" + sortType;
string refere = "https://store.weixin.qq.com/shop/goods/list";
var result = WxHttpClient.Get(shop, url, refere);
return result;
}
/// <summary>批量下架商品。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodIds">逗号分隔的商品 ID 字符串;批量操作直接放入 JSON 数组,不含方括号。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdClearNoVisit260606Form.cs,WXClearNoVisit260606.DownProd。
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdClearNoVisitForm.cs,WXClearNoVisit.DownProd。
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdPreSaleForm.cs,WXProdNoCheckEditHelper.DownProd。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string DownProd(ShopLoginInfo shop, string prodIds)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductlist/cgi/goods/BatchUnListing?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/list";
string body = @"{""ids"":[" + prodIds + @"],""uploadSource"":6}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>批量删除商品至回收站。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodIds">逗号分隔的商品 ID 字符串;批量操作直接放入 JSON 数组,不含方括号。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdClearNoVisit260606Form.cs,WXClearNoVisit260606.DelProd。
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdClearNoVisitForm.cs,WXClearNoVisit.DelProd。
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdPreSaleForm.cs,WXProdNoCheckEditHelper.DelProd。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string DelProd(ShopLoginInfo shop, string prodIds)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductlist/cgi/goods/batchDel?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/list";
string body = @"{""ids"":[" + prodIds + @"],""uploadSource"":6}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>从回收站彻底删除商品;调用前由业务方确认目标商品。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodIds">逗号分隔的商品 ID 字符串;批量操作直接放入 JSON 数组,不含方括号。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdClearNoVisit260606Form.cs,WXClearNoVisit260606.RealDelProd。
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdClearNoVisitForm.cs,WXClearNoVisit.RealDelProd。
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdPreSaleForm.cs,WXProdNoCheckEditHelper.RealDelProd。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string RealDelProd(ShopLoginInfo shop, string prodIds)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductlist/cgi/goods/batchRealDel?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_RECYCLE_BIN";
string body = @"{""ids"":[" + prodIds + @"],""uploadSource"":6}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>按预售类型、销售状态及排序查询商品。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="pageNum">页码,从 1 开始。</param>
/// <param name="presaleType">预售类型的接口筛选值;null 不增加预售类型筛选。 默认值:null。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:50。</param>
/// <param name="sortType">商品排序的接口值;null 使用平台默认排序。 默认值:null。</param>
/// <param name="status">商品销售状态:-1 全部、5 在售、11 下架,沿用原代码。 默认值:5。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdPreSaleForm.cs,WXProdNoCheckEditHelper.searchProduct。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SearchPresaleProduct(ShopLoginInfo shop, int pageNum, int? presaleType = null, int pageSize = 50, int? sortType = null, int status = 5)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?token=&lang=zh_CN&" + "pageSize=" + pageSize + "&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&pageNum=" + pageNum + "&status[]=" + status;
if (presaleType != null)
url += "&presaleType[]=" + presaleType;
if (sortType != null)
url += "&sortType=" + sortType;
string refere = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_ON";
var result = WxHttpClient.Get(shop, url, refere);
return result;
}
/// <summary>使用游标分页扫描商品预览信息。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="page">页码,从 1 开始。</param>
/// <param name="nextKey">上一页返回的游标,首页传空字符串。 默认值:&quot;&quot;。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:50。</param>
/// <param name="saleStatus">销售状态筛选值,原商品列表默认 5 表示在售。 默认值:5。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdPreSaleForm.cs,WXProdNoCheckEditHelper.scanProductPreview。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string ScanProductPreview(ShopLoginInfo shop, int page, string nextKey = "", int pageSize = 50, int saleStatus = 5)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/scanProductPreview?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_ON";
if (page > 1)
referer = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_ON&currentPage=" + page;
JObject bodyObj = new JObject();
bodyObj["pageSize"] = pageSize;
bodyObj["productStatus"] = new JArray()
{
-1
};
bodyObj["productSource"] = "[1,16,32]";
bodyObj["searchSource"] = 1;
bodyObj["useNew"] = true;
bodyObj["pageNum"] = page;
bodyObj["status"] = new JArray()
{
saleStatus
};
if (!string.IsNullOrEmpty(nextKey))
{
bodyObj["nextKey"] = nextKey;
}
string body = JsonHelper.SerializeObject(bodyObj);
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>获取商品推广素材或链接信息。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodId">微信商品 ID。</param>
/// <param name="pageId">页码,从 1 开始;部分接口仅用于页面 Referer。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdPreSaleForm.cs,WXProdNoCheckEditHelper.GetPromotionLink。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetPromotionLink(ShopLoginInfo shop, string prodId, int pageId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodematerial/product?token=&lang=zh_CN&productId=" + prodId;
string referer = "https://store.weixin.qq.com/shop/goods/list?currentPage=" + pageId;
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
}
}
+131
View File
@@ -0,0 +1,131 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店商品联盟推广接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxPromotionApi
{
/// <summary>在编辑商品时设置联盟及团长推广开关和佣金。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="itemSwitch">普通联盟推广开关的接口原始值。</param>
/// <param name="itemRatio">普通联盟推广佣金比例的接口原始整数值,不在本方法内换算。</param>
/// <param name="headSupplierItemSwitch">团长推广开关的接口原始值。</param>
/// <param name="HeadSupplierItemRatio">团长推广佣金比例的接口原始整数值,不在本方法内换算。</param>
/// <param name="prodId">微信商品 ID。</param>
/// <param name="updType">推广更新类型的接口原始值。 默认值:2。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.addLeagueItemForUpdatingProduct。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string AddLeagueItemForUpdatingProduct(ShopLoginInfo shop, int itemSwitch, int itemRatio, int headSupplierItemSwitch, int HeadSupplierItemRatio, long prodId, int updType = 2)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/common/cgi/goods/addLeagueItemForUpdatingProduct?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/home";
string body = @"{""itemSwitch"":" + itemSwitch + @",""itemRatio"":" + itemRatio + @",""headSupplierPublicItemSwitch"":" + headSupplierItemSwitch + @",""headSupplierPublicItemServiceRatio"":" + HeadSupplierItemRatio + @",""productId"":" + prodId + @",""scene"":2,""updType"":" + updType + @"}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询商品是否满足推广条件。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodIdLst">微信商品 ID 列表。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdCouponOrderBoomForm.cs,WxCoupon.WxGetCanPromotion。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxGetCanPromotion(ShopLoginInfo shop, List<string> prodIdLst)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeleague/plan/getItemList?token=&lang=zh_CN";
foreach (var prodId in prodIdLst)
{
url += "&spuIdList[]=" + prodId;
}
url += "&offset=0&list_type=1";
string referer = "https://store.weixin.qq.com/shop/shopleague/home/normal-add";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>批量为商品添加推广计划并设置佣金比例。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodIdLst">微信商品 ID 列表。</param>
/// <param name="ratio">推广佣金比例的接口原始整数值,不在本方法内换算。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdCouponOrderBoomForm.cs,WxCoupon.WxAddPromotion。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxAddPromotion(ShopLoginInfo shop, List<string> prodIdLst, int ratio)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeleague/plan/batchAddItem?token=&lang=zh_CN";
string body = @"{""list"":[";
foreach (var prodId in prodIdLst)
body += @"{""spuId"":""" + prodId + @""",""ratio"":" + ratio + @",""finderCoupon"":0},";
body = body.TrimEnd(',');
body += @"]}";
string referer = "https://store.weixin.qq.com/shop/shopleague/home/normal-add";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>按商品 ID 查询推广计划。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodId">微信商品 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdCouponOrderBoomForm.cs,WxCoupon.WxSearchPromotion。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxSearchPromotion(ShopLoginInfo shop, string prodId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeleague/plan/getItemListBySearch?" + "token=&lang=zh_CN&offset=0&size=10&product_title=" + prodId + "&status=1&list_type=2&needWarning=true&needStockNum=true";
string referer = "https://store.weixin.qq.com/shop/shopleague/home";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>结束指定商品的推广计划。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodId">微信商品 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdCouponOrderBoomForm.cs,WxCoupon.WxEndPromotion。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxEndPromotion(ShopLoginInfo shop, string prodId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeleague/plan/updateItem?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/shopleague/home";
string body = @"{""spu_id"":""" + prodId + @""",""operate_type"":2}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>删除指定商品的推广计划。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="prodId">微信商品 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXProdCouponOrderBoomForm.cs,WxCoupon.WxDelPromotion。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxDelPromotion(ShopLoginInfo shop, string prodId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeleague/plan/updateItem?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/shopleague/home";
string body = @"{""spu_id"":""" + prodId + @""",""operate_type"":3}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
}
}
+106
View File
@@ -0,0 +1,106 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店店铺登录、服务、状态及违规接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxShopApi
{
/// <summary>查询店铺违规商品信息。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\PDDForms\ProductForms\WXProdViolationManage.cs,WXProdViolationManage.getShopiolationProd。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetShopViolationProducts(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeviolationsec/violation/cgi/get?token=&lang=zh_CN&violationType=finder&shopId=";
string referer = "https://store.weixin.qq.com/shop/violation/home";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>查询店铺当前已订购的服务列表。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.GetApiServiceList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetApiServiceList(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodeservicemarket/service/GetMyServiceList?offset=0&limit=20&status=2&token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/servicemarket/myServices?status=2";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>获取并更新微信小店后台在线状态。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.GetAndUpdateWebStatus。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetAndUpdateWebStatus(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradehome/home/getAndUpdateWebStatus?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/home";
string body = @"{""timeQuery"":{""startMs"":" + BaseClass.DateTimeToTimestampMilliseconds(DateTime.Now.Date.AddDays(-1)) + @",""endMs"":" + BaseClass.DateTimeToTimestampMilliseconds(DateTime.Now.Date.AddSeconds(-1)) + @"}}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>读取店铺后台首页 HTML,用于原店铺登录信息提取流程。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>后台首页原始 HTML;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopListForm.cs,WXShopListForm.GetShopInfo。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetShopInfo(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop/home";
string refere = "";
var result = WxHttpClient.Get(shop, url, refere, true);
return result;
}
/// <summary>请求店铺通知配置,用于判断当前 Cookie 是否仍可访问后台。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="refere">请求的 Referer 页面地址。 默认值:&quot;https://store.weixin.qq.com/shop/home&quot;。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopListForm.cs,WXShopListForm.CheckShopLogin。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string CheckShopLogin(ShopLoginInfo shop, string refere = "https://store.weixin.qq.com/shop/home")
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodebase/reachDiolog/getBizNotifyConfig?token=&lang=zh_CN";
string body = @"{""path"":""https://store.weixin.qq.com/shop/home""}";
return WxHttpClient.Post(shop, url, body, refere);
}
/// <summary>查询当前登录账号可切换的店铺列表。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopMultiLoginForm.cs,WXShopSwitch.getShopSwitchList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetShopSwitchList(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodelogin/session/getShopSwitchList?token=&lang=zh_CN";
string refere = "https://store.weixin.qq.com/shop/home";
var result = WxHttpClient.Get(shop, url, refere);
return result;
}
}
}
+203
View File
@@ -0,0 +1,203 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店销售、评分及物流统计接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxStatisticsApi
{
/// <summary>查询影响商品质量评分的退款订单明细。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="pageId">页码,从 1 开始;部分接口仅用于页面 Referer。</param>
/// <param name="beginTick">统计开始时间的 Unix 秒时间戳。</param>
/// <param name="endTick">统计结束时间的 Unix 秒时间戳。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopOptimizeForm.cs,ShopOptimize.GetProductRefundOrder。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetProductRefundOrder(ShopLoginInfo shop, int pageId, int beginTick, int endTick)
{
string url = "https://store.weixin.qq.com/shop-faas/statistic/dsr/product/refund/order?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/setting/ratedetail?type=product&key=productQualityRatio_30d&detail=product";
string body = @"{""page"":" + pageId + @",""pageSize"":20,""beginTs"":" + beginTick + @",""endTs"":" + endTick + @"}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询指定时间范围内的商品评价。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="pageId">页码,从 1 开始;部分接口仅用于页面 Referer。</param>
/// <param name="beginTick">统计开始时间的 Unix 秒时间戳。</param>
/// <param name="endTick">统计结束时间的 Unix 秒时间戳。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopOptimizeForm.cs,ShopOptimize.GetProductEvaluation。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetProductEvaluation(ShopLoginInfo shop, int pageId, int beginTick, int endTick)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeevaluation/cgi/search?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/evaluate/home";
string body = @"{""orderId"":"""",""productId"":"""",""productEvaluationId"":"""",""buyerEvaluationTimeStart"":" + beginTick + @",""buyerEvaluationTimeEnd"":" + endTick + @",""status"":2,""page"":" + pageId + @",""visibleType"":0}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询店铺评分项目,供业务方判断使用 24 小时或 48 小时揽收指标。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopOptimizeForm.cs,ShopOptimize.Get24H48HFlag。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string Get24H48HFlag(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/statistic/cgi/search?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/setting/rate2";
string body = "{\"days\":14,\"scoreTypeList\":[63,1000]}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询影响揽收及时率的订单明细。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="pageId">页码,从 1 开始;部分接口仅用于页面 Referer。</param>
/// <param name="beginTick">统计开始时间的 Unix 秒时间戳。</param>
/// <param name="endTick">统计结束时间的 Unix 秒时间戳。</param>
/// <param name="is24">是否使用 24 小时揽收相关页面上下文;false 使用 48 小时上下文。 默认值:false。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopOptimizeForm.cs,ShopOptimize.GetProductOrderWayBill。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetProductOrderWayBill(ShopLoginInfo shop, int pageId, int beginTick, int endTick, bool is24 = false)
{
string url = "https://store.weixin.qq.com/shop-faas/statistic/dsr/logistics/pickup/insale?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/setting/ratedetail?type=logistics&key=collectIn_48hOrdRatio_30d&valid=collectIn_48hOrdRatio_30d|waybillArriveOntimeRatio_30d|waybillNegtiveOrdRatio_30d&detail=insale";
if (is24)
referer = "https://store.weixin.qq.com/shop/setting/ratedetail?type=logistics&key=collectIn_24hOrdRatio_30d&valid=collectIn_24hOrdRatio_30d|waybillArriveOntimeRatio_30d|waybillNegtiveOrdRatio_30d&detail=insale";
string body = @"{""page"":" + pageId + @",""pageSize"":20,""beginTs"":" + beginTick + @",""endTs"":" + endTick + @"}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询物流轨迹及时率订单明细,沿用原统计查询协议。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="pageId">页码,从 1 开始;部分接口仅用于页面 Referer。</param>
/// <param name="beginTick">预期的开始时间(Unix 毫秒);原实现未使用此值,见 remarks。</param>
/// <param name="endTick">结束时间(Unix 毫秒);原实现同时用于 startMs 和 endMs。</param>
/// <param name="is24">是否使用 24 小时揽收相关页面上下文;false 使用 48 小时上下文。 默认值:false。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopOptimizeForm.cs,ShopOptimize.GetOrderLinerCgi。
/// 保留旧行为:startMs 与 endMs 均取 endTick;需要修正时间范围时应单独确认业务影响。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetOrderLinerCgi(ShopLoginInfo shop, int pageId, long beginTick, long endTick, bool is24 = false)
{
// shortcut: 保留旧代码 startMs 取 endTick 的行为,业务确认时间范围修正后再改为 beginTick。
string url = "https://store.weixin.qq.com/shop-faas/mmecnodelinercgi/cgi/liner/query?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/setting/ratedetail?type=logistics&key=waybillArriveOntimeRatio_30d&valid=collectIn_48hOrdRatio_30d|waybillArriveOntimeRatio_30d|waybillNegtiveOrdRatio_30d";
if (is24)
referer = "https://store.weixin.qq.com/shop/setting/ratedetail?type=logistics&key=waybillArriveOntimeRatio_30d&valid=collectIn_24hOrdRatio_30d|waybillArriveOntimeRatio_30d|waybillNegtiveOrdRatio_30d";
string body = @"{""time_query"":{""dateFormat"":2,""dateType"":0,""dateRange"":30,""startMs"":" + endTick + @",""endMs"":" + endTick + @"},""limit"":10,""offset"":" + (Math.Max(0, pageId - 1) * 10) + @",""id"":""ratedetail-wuliu-route-order-table"",""biz"":""store"",""is_std"":""0"",""sort"":[""std_route_rate"",""desc""]}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询物流负向反馈订单明细。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="page">页码,从 1 开始。</param>
/// <param name="beginTs">统计开始时间的 Unix 秒时间戳。</param>
/// <param name="endTs">统计结束时间的 Unix 秒时间戳。</param>
/// <param name="is24">是否使用 24 小时揽收相关页面上下文;false 使用 48 小时上下文。 默认值:false。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WXShopOptimizeForm.cs,ShopOptimize.GetFeedbackOrder。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetFeedbackOrder(ShopLoginInfo shop, int page, int beginTs, int endTs, bool is24 = false)
{
string url = "https://store.weixin.qq.com/shop-faas/statistic/dsr/logistics/feedback/order?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/setting/ratedetail?type=logistics&key=waybillNegtiveOrdRatio_30d&valid=collectIn_48hOrdRatio_30d|waybillArriveOntimeRatio_30d|waybillNegtiveOrdRatio_30d&detail=company";
if (is24)
referer = "https://store.weixin.qq.com/shop/setting/ratedetail?type=logistics&key=waybillNegtiveOrdRatio_30d&valid=collectIn_24hOrdRatio_30d|waybillArriveOntimeRatio_30d|waybillNegtiveOrdRatio_30d&detail=company";
string body = @"{""page"":" + page + @",""pageSize"":20,""beginTs"":" + beginTs + @",""endTs"":" + endTs + @"}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询店铺首页待办数量,包括待发货、售后和物流异常等。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WxShopStatisticsForm.cs,WxShopStatisticsForm.GetShopMainInfoList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetShopMainInfoList(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradehome/home/main?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/home";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>查询指定时间范围内的离线销售统计。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="startTime">统计开始时间的 Unix 毫秒时间戳。</param>
/// <param name="endTime">统计结束时间的 Unix 毫秒时间戳。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WxShopStatisticsForm.cs,WxShopStatisticsForm.GetShopSaleInfoList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetShopSaleInfoList(ShopLoginInfo shop, long startTime, long endTime)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodelinercgi/cgi/liner_query/3/home-overview-shop-offline?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/home";
string data = @"{""time_query"":{""dateFormat"":2,""dateType"":0,""dateRange"":7,""startMs"":" + startTime + @",""endMs"":" + endTime + "}}";
var result = WxHttpClient.Post(shop, url, data, referer);
return result;
}
/// <summary>查询指定时间范围内的实时销售统计。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="startTime">统计开始时间的 Unix 毫秒时间戳。</param>
/// <param name="endTime">统计结束时间的 Unix 毫秒时间戳。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WxShopStatisticsForm.cs,WxShopStatisticsForm.GetShopSaleInfoRealTimeList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetShopSaleInfoRealTimeList(ShopLoginInfo shop, long startTime, long endTime)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodelinercgi/cgi/liner_query/3/home-overview-shop-realtime?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/home";
string data = @"{""time_query"":{""dateFormat"":1,""dateType"":0,""dateRange"":1,""startMs"":" + startTime + @",""endMs"":" + endTime + "}}";
var result = WxHttpClient.Post(shop, url, data, referer);
return result;
}
/// <summary>查询店铺首页评分等次要统计信息。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ShopForms\WxShopStatisticsForm.cs,WxShopStatisticsForm.GetShopScore。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetShopScore(ShopLoginInfo shop)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradehome/home/minor?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/home";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
}
}
+191
View File
@@ -0,0 +1,191 @@
using AllBase;
using NaiBa.Util.Extension;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店达人广场、邀约及带货数据接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxTalentApi
{
/// <summary>按完整筛选 JSON 查询达人广场列表。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="bodyJson">符合原接口结构的完整筛选请求 JSON。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXFinderSquareForm.cs,WXFinderSquareBLL.getSquareTalentList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetSquareTalentList(ShopLoginInfo shop, string bodyJson)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeleague/finderSquare/cgi/getSquareTalentList?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/findersquare/find";
string body = bodyJson;
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询指定达人橱窗中的商品列表。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="page">页码,从 1 开始。</param>
/// <param name="finderUsername">达人视频号在平台中的 finderUsername 标识。</param>
/// <param name="talentAppid">达人关联的 talentAppid 标识。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXFinderSquareForm.cs,WXFinderSquareBLL.WxFinderSquareGetProdList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string WxFinderSquareGetProdList(ShopLoginInfo shop, int page, string finderUsername, string talentAppid)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeleague/finderSquare/cgi/getItemList?token=&lang=zh_CN&offset=" + (page - 1) * 10 + "&pageSize=10&productTitle=";
string referer = "https://store.weixin.qq.com/shop/findersquare/initiate-invite?finderUsername=" + finderUsername + "&talentAppid=" + talentAppid + "&from=5";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>批量查询商品,并按销量排序。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="spuIdLst">微信商品 SPU ID 列表。</param>
/// <param name="page">页码,从 1 开始。 默认值:1。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXFinderSquareForm.cs,WXFinderSquareBLL.getSaleSortProduct。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetSaleSortProduct(ShopLoginInfo shop, List<string> spuIdLst, int page = 1)
{
var spuIdStr = "+" + string.Join("+", spuIdLst);
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct" + "?token=&lang=zh_CN&pageSize=50&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&pageNum=" + page + "&status[]=5&spuId=" + spuIdStr + "&sortType=6";
string referer = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_ON";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>批量查询商品,并按上架时间排序。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="spuIdLst">微信商品 SPU ID 列表。</param>
/// <param name="page">页码,从 1 开始。 默认值:1。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXFinderSquareForm.cs,WXFinderSquareBLL.getListingTimeSortProduct。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetListingTimeSortProduct(ShopLoginInfo shop, List<string> spuIdLst, int page = 1)
{
var spuIdStr = "+" + string.Join("+", spuIdLst);
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct" + "?token=&lang=zh_CN&pageSize=50&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&pageNum=" + page + "&status[]=5&spuId=" + spuIdStr + "&sortType=18";
string referer = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_ON";
var result = WxHttpClient.Get(shop, url, referer);
return result;
}
/// <summary>向指定达人提交商品推广邀请及商家联系方式。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="productIdLst">微信商品 ID 列表。</param>
/// <param name="finderUsername">达人视频号在平台中的 finderUsername 标识。</param>
/// <param name="talentAppid">达人关联的 talentAppid 标识。</param>
/// <param name="contactName">推广邀请中展示的商家联系人姓名。</param>
/// <param name="contactWxId">商家联系人的微信号。</param>
/// <param name="contactPhoneNumber">商家联系人手机号。</param>
/// <param name="invitationIntroduction">发送给达人的推广邀请说明。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXFinderSquareForm.cs,WXFinderSquareBLL.createPromotionInvitation。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string CreatePromotionInvitation(ShopLoginInfo shop, List<string> productIdLst, string finderUsername, string talentAppid, string contactName, string contactWxId, string contactPhoneNumber, string invitationIntroduction)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeleague/finderSquare/cgi/createPromotionInvitation?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/findersquare/initiate-invite?finderUsername=" + "&talentAppid=" + "&from=5";
string body = @"{""finderUsername"":""" + finderUsername + @""",""talentAppid"":""" + talentAppid + @""",""itemList"":{""itemInfo"":[";
foreach (var spuId in productIdLst)
{
body += @"{""spuId"":""" + spuId + @"""},";
}
body = body.TrimEnd(',');
body += @"]},""contactInfo"":{""contactName"":""" + contactName + @""",""contactWxId"":""" + contactWxId + @""",""contactPhoneNumber"":""" + contactPhoneNumber + @""",""invitationIntroduction"":""" + invitationIntroduction + @""",""inviteScene"":""5""}}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询达人在指定时间范围内的直播或短视频内容列表。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="finderUsername">达人视频号在平台中的 finderUsername 标识。</param>
/// <param name="mpAppid">达人关联的 mpAppid 标识。</param>
/// <param name="talentAppid">达人关联的 talentAppid 标识。</param>
/// <param name="startMs">统计开始时间的 Unix 毫秒时间戳。</param>
/// <param name="endMs">统计结束时间的 Unix 毫秒时间戳。</param>
/// <param name="liveOrFeed">内容类型:1 直播、2 短视频,来自原页面调用。 默认值:1。</param>
/// <param name="page">页码,从 1 开始。 默认值:1。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:10。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXFinderSquareForm.cs,WXFinderSquareBLL.GetDaRenLiveFeedList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetDaRenLiveFeedList(ShopLoginInfo shop, string finderUsername, string mpAppid, string talentAppid, long startMs, long endMs, int liveOrFeed = 1, int page = 1, int pageSize = 10)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeleague/finderSquare/cgi/GetSameIndustryDetailLiveFeedList?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/findersquare/finder-detail?from=5&fromTab=all&finderUsername=" + finderUsername;
if (!mpAppid.IsNullOrEmpty())
referer += "&mpAppid=" + mpAppid;
referer += "&talentAppid=" + talentAppid;
string body = @"{""appid"":""" + talentAppid + @""",""liveOrFeed"":" + liveOrFeed + @",""page"":{""limit"":" + pageSize + @",""offset"":" + (page - 1) * 10 + @"},""startMs"":" + startMs + @",""endMs"":" + endMs + @",""sortControl"":null}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>查询达人指定直播或短视频内容中的商品列表。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="finderUsername">达人视频号在平台中的 finderUsername 标识。</param>
/// <param name="mpAppid">达人关联的 mpAppid 标识。</param>
/// <param name="talentAppid">达人关联的 talentAppid 标识。</param>
/// <param name="objectId">目标直播或短视频内容的 objectId。</param>
/// <param name="page">页码,从 1 开始。 默认值:1。</param>
/// <param name="pageSize">每页条数,默认值沿用原调用。 默认值:10。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXFinderSquareForm.cs,WXFinderSquareBLL.GetDaRenLiveProductList。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string GetDaRenLiveProductList(ShopLoginInfo shop, string finderUsername, string mpAppid, string talentAppid, string objectId, int page = 1, int pageSize = 10)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeleague/finderSquare/cgi/getLiveProductList?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/findersquare/finder-detail?from=5&fromTab=all&finderUsername=" + finderUsername;
if (!mpAppid.IsNullOrEmpty())
referer += "&mpAppid=" + mpAppid;
referer += "&talentAppid=" + talentAppid;
string body = @"{""appid"":""" + talentAppid + @""",""objectId"":""" + objectId + @""",""limit"":" + pageSize + @",""offset"":" + (page - 1) * 10 + @"}";
var result = WxHttpClient.Post(shop, url, body, referer);
return result;
}
/// <summary>创建与指定达人的客服会话。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="finderUsername">达人视频号在平台中的 finderUsername 标识。</param>
/// <param name="mpAppid">达人关联的 mpAppid 标识。</param>
/// <param name="talentAppid">达人关联的 talentAppid 标识。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\ProductForms\WXFinderSquareForm.cs,WXFinderSquareBLL.userCreateChatRoom。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string UserCreateChatRoom(ShopLoginInfo shop, string finderUsername, string mpAppid, string talentAppid)
{
string url = "https://store.weixin.qq.com/shop/commkf/user_room?action=user_create_room&token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/findersquare/finder-detail?from=1&fromTab=all&finderUsername=" + finderUsername;
if (!mpAppid.IsNullOrEmpty())
referer += "&mpAppid=" + mpAppid;
referer += "&talentAppid=" + talentAppid;
string body = @"{""open_account"":""" + talentAppid + @"""}";
var result = WxHttpClient.PostCustomerService(shop, url, body, referer);
return result;
}
}
}
+84
View File
@@ -0,0 +1,84 @@
using AllBase;
using AllBase.Model.Result;
using AllBase.Model.Param.WXParam;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Work.Api.Wx
{
/// <summary>微信小店在线电子面单接口;独立于原窗体,使用 HttpHelper 发送请求。</summary>
/// <remarks>传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。</remarks>
public static class WxWaybillApi
{
/// <summary>在线电子面单预下单,校验寄收件资料并获取下单准备信息。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="preWaybillOnlineparam">电子面单预下单参数,沿用 AllBase 中的请求模型。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.preCreateOrderWaybillOnline。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string PreCreateOrderWaybillOnline(ShopLoginInfo shop, WXPreCreateOrderWaybillOnlineParam preWaybillOnlineparam)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodewaybill/alltoall/platPreCreateOrder?token=&lang=zh_CN";
string body = JsonHelper.SerializeObject(preWaybillOnlineparam);
string refere = "https://store.weixin.qq.com/shop/waybill/allToAll";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>创建在线电子面单订单,实际向平台提交面单申请。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="waybillOnlineparam">电子面单创建参数,沿用 AllBase 中的请求模型。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.createOrderWaybillOnline。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string CreateOrderWaybillOnline(ShopLoginInfo shop, WXCreateOrderWaybillOnlineParam waybillOnlineparam)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodewaybill/alltoall/platCreateOrder?token=&lang=zh_CN";
string body = JsonHelper.SerializeObject(waybillOnlineparam);
string refere = "https://store.weixin.qq.com/shop/waybill/allToAll";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>按微信订单号查询已创建的在线电子面单。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="orderId">微信订单 ID。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.searchOnlineWaybill。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string SearchOnlineWaybill(ShopLoginInfo shop, string orderId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodewaybill/alltoall/searchBill?token=&lang=zh_CN";
string body = @"{""createMode"":1,""orderId"":""" + orderId + @""",""cosignmentOrderId"":"""",""goodsTitle"":"""",""receiverPhone"":"""",""receiverName"":"""",""billStatus"":null,""orderStatus"":null,""offset"":0,""limit"":20,""waybillId"":"""",""payMethodList"":[],""platDisplayOrderStatusList"":[],""cosignmentOrderTime"":[],""cosignmentAssignTime"":[],""storeName"":"""",""orderNote"":"""",""deliveryOrderStatusList"":[10,20,40]}";
string refere = "https://store.weixin.qq.com/shop/waybill/allToAll";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
/// <summary>取消指定在线电子面单订单。</summary>
/// <param name="shop">店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。</param>
/// <param name="ewaybillOrderId">平台返回的电子面单订单 ID。</param>
/// <param name="waybillId">物流运单号。</param>
/// <returns>微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。</returns>
/// <remarks>
/// 来源:TEMUKJD\WXForms\OrderForms\WXOrderListForm.cs,WXOrderList.cancelOnlineWaybill。
/// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。
/// </remarks>
public static string CancelOnlineWaybill(ShopLoginInfo shop, string ewaybillOrderId, string waybillId)
{
string url = "https://store.weixin.qq.com/shop-faas/mmecnodewaybill/alltoall/platCancelOrder?token=&lang=zh_CN";
string body = @"{""requestContent"":[{""ewaybillOrderId"":""" + ewaybillOrderId + @""",""waybillId"":""" + waybillId + @""",""source"":1,""merchCancelReason"":""临时缺货,库存不足""}]}";
string refere = "https://store.weixin.qq.com/shop/waybill/allToAll";
var result = WxHttpClient.Post(shop, url, body, refere);
return result;
}
}
}
+327
View File
@@ -2,11 +2,13 @@
using AllBase.Helper;
using AllBase.Model.Result;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Work.Api.Wx;
namespace Work.Services
{
@@ -46,6 +48,295 @@ namespace Work.Services
return ret.Data;
}
/// <summary>
/// 在后台解析微信处罚 JSON、匹配店铺商品编码并上报,异常在内部记录。
/// </summary>
public static void ReportViolationsFromJson(string json, ShopLoginInfo shop)
{
_ = Task.Run(async () =>
{
try
{
await ReportViolationsFromJsonCore(json, shop).ConfigureAwait(false);
}
catch (Exception ex)
{
try
{
LogSave.AddFile("解析并上报违规商品失败:" + ex.Message);
}
catch
{
// 日志失败也不能影响调用方。
}
}
});
}
private static async Task<List<ReportGoodsViolationResult>> ReportViolationsFromJsonCore(string json, ShopLoginInfo shop)
{
if (string.IsNullOrWhiteSpace(json))
{
throw new ArgumentException("处罚 JSON 文本不能为空。", nameof(json));
}
JObject root;
try
{
root = JObject.Parse(json);
}
catch (JsonException ex)
{
throw new ArgumentException("处罚 JSON 格式不正确。", nameof(json), ex);
}
var record = root["record"] as JObject;
if (root["code"]?.ToString() != "0" || record?["code"]?.ToString() != "0")
{
throw new ArgumentException("处罚数据的 code 或 record.code 不为 0,或缺少 record。", nameof(json));
}
if (!(record["items"] is JArray records))
{
throw new ArgumentException("处罚数据缺少 record.items 数组。", nameof(json));
}
if (records.Count == 0)
return new List<ReportGoodsViolationResult>();
var items = new List<ReportGoodsViolationItem>();
foreach (var token in records)
{
if (!(token is JObject punishment))
{
throw new ArgumentException("record.items 中的处罚记录必须是对象。", nameof(json));
}
var objects = punishment["punishObject"];
if (objects == null || objects.Type == JTokenType.Null)
{
continue;
}
if (!(objects is JArray products))
{
throw new ArgumentException("punishObject 必须是数组。", nameof(json));
}
foreach (var product in products)
{
if (!(product is JObject target))
{
throw new ArgumentException("punishObject 中的处罚对象必须是对象。", nameof(json));
}
var id = target["productId"];
// 订单等非商品处罚对象不包含 productId。
if (id == null)
{
continue;
}
if ((id.Type != JTokenType.String && id.Type != JTokenType.Integer)
|| !long.TryParse(id.ToString(), out var goodsId) || goodsId <= 0)
{
throw new ArgumentException("商品 productId 必须是有效的正整数编号。", nameof(json));
}
var reason = punishment["punishReason"];
if (reason?.Type != JTokenType.String || string.IsNullOrWhiteSpace((string)reason))
{
throw new ArgumentException($"商品 {goodsId} 缺少有效的 punishReason。", nameof(json));
}
items.Add(new ReportGoodsViolationItem { GoodsId = goodsId, Reasons = ((string)reason).Trim() });
}
}
if (items.Count == 0)
{
return new List<ReportGoodsViolationResult>();
}
var productCodes = GetWxProductCodes(shop, items.Select(item => item.GoodsId));
var mappedItems = new List<ReportGoodsViolationItem>();
foreach (var item in items)
{
if (!productCodes.TryGetValue(item.GoodsId, out var code) || string.IsNullOrWhiteSpace(code))
{
LogSave.AddFile($"跳过违规商品 {item.GoodsId}:未找到对应的 spuCode。");
continue;
}
if (!TryGetGoodsId(code, out var goodsId))
{
LogSave.AddFile($"跳过违规商品 {item.GoodsId}:spuCode 无法转换为有效商品编号。");
continue;
}
mappedItems.Add(new ReportGoodsViolationItem { GoodsId = goodsId, Reasons = item.Reasons });
}
var reports = mappedItems.GroupBy(item => item.GoodsId).Select(group => new ReportGoodsViolationItem
{
GoodsId = group.Key,
Reasons = string.Join(";", group.Select(item => item.Reasons).Distinct())
}).ToList();
return reports.Count == 0
? new List<ReportGoodsViolationResult>() : await ReportViolations(reports);
}
private static bool TryGetGoodsId(string code, out long goodsId)
{
code = code?.Trim() ?? string.Empty;
if (code.StartsWith("P1-", StringComparison.Ordinal))
{
code = code.Substring(3);
}
else if (code.StartsWith("EC1", StringComparison.Ordinal) && code.EndsWith("A", StringComparison.Ordinal))
{
code = code.Substring(3, code.Length - 4);
}
return long.TryParse(code, out goodsId) && goodsId > 0;
}
/// <summary>
/// 后台检查当前店铺所有在售商品,云端确认违规后立即下架;异常仅记录日志。
/// </summary>
public static void CheckAndOffShelfViolations(ShopLoginInfo shop)
{
_ = Task.Run(async () =>
{
try
{
await CheckAndOffShelfViolationsCore(shop).ConfigureAwait(false);
}
catch (Exception ex)
{
try
{
LogSave.AddFile($"店铺 {shop?.ShopId} 在售商品违规检查失败:{ex.Message}");
}
catch { }
}
});
}
private static async Task CheckAndOffShelfViolationsCore(ShopLoginInfo shop)
{
// 先读取完整列表,避免下架改变分页位置而漏查后面的商品。
var products = GetWxProductCodes(shop, status: 5);
var mappings = new Dictionary<long, long>();
foreach (var product in products)
{
if (TryGetGoodsId(product.Value, out var goodsId))
{
mappings.Add(product.Key, goodsId);
}
else
{
LogSave.AddFile($"店铺 {shop.ShopId} 跳过商品 {product.Key}:spuCode 无法转换为有效商品编号。");
}
}
var goodsIds = mappings.Values.Distinct().ToList();
for (var offset = 0; offset < goodsIds.Count; offset += 50)
{
var batch = goodsIds.Skip(offset).Take(50).ToList();
var statuses = GetViolationStatus(batch);
var violations = new HashSet<long>(statuses.Where(item => item != null && item.IsViolation && batch.Contains(item.GoodsId))
.Select(item => item.GoodsId));
var productIds = mappings.Where(item => violations.Contains(item.Value)).Select(item => item.Key).ToList();
// 同一云商品可能对应多个微信商品,每次下架最多 50 个。
for (var index = 0; index < productIds.Count; index += 50)
{
var ids = string.Join(",", productIds.Skip(index).Take(50));
var response = JObject.Parse(WxProductApi.DownProd(shop, ids));
if (response["code"]?.ToString() != "0")
{
throw new Exception($"微信商品 {ids} 下架失败:{response}");
}
LogSave.AddFile($"店铺 {shop.ShopId} 云端检测违规,已下架微信商品:{ids}");
}
}
}
private static Dictionary<long, string> GetWxProductCodes(ShopLoginInfo shop, IEnumerable<long> productIds = null, int status = -1)
{
if (shop == null)
{
throw new ArgumentNullException(nameof(shop));
}
var codes = new Dictionary<long, string>();
var prodIds = productIds == null ? null : string.Join(",", productIds.Distinct());
long received = 0;
for (var page = 1; ; page++)
{
var response = JObject.Parse(WxProductApi.SearchProduct(shop, page, pageSize: 50, prodIds: prodIds, status: status));
if (response["ret"]?.ToString() != "0" || response["success"]?.Type != JTokenType.Boolean
|| !(bool)response["success"] || !(response["productList"] is JArray products)
|| !long.TryParse(response["totalNum"]?.ToString(), out var total) || total < 0)
{
throw new Exception($"获取微信商品列表第 {page} 页失败。");
}
var previousCount = codes.Count;
foreach (var product in products)
{
if (!(product is JObject item) || !long.TryParse(item["productId"]?.ToString(), out var id) || id <= 0)
{
throw new Exception("微信商品列表包含无效的 productId。");
}
codes[id] = item["spuCode"]?.Type == JTokenType.String ? (string)item["spuCode"] : null;
}
received += products.Count;
if (received >= total)
{
return codes;
}
if (codes.Count == previousCount)
{
throw new Exception("微信商品列表分页未返回新商品,无法获取全部搜索结果。");
}
}
}
/// <summary>
/// 批量上报违规商品。
/// </summary>
public static async Task<List<ReportGoodsViolationResult>> ReportViolations(List<ReportGoodsViolationItem> items)
{
if (items == null)
{
throw new ArgumentNullException(nameof(items));
}
if (items.Any(item => item == null))
{
throw new ArgumentException("违规商品列表不能包含空项。", nameof(items));
}
var html = await GetHtml.PostJsonAsync(ServerUrl + "/api/CloudGoods/ReportViolations", items, timeOut: 5);
var ret = JsonConvert.DeserializeObject<Result<List<ReportGoodsViolationResult>>>(html);
if (ret == null)
{
throw new Exception("批量上报违规商品返回为空。");
}
if (ret.Code != 200)
{
throw new Exception(ret.Msg);
}
return ret.Data ?? throw new Exception("批量上报违规商品返回数据为空。");
}
/// <summary>
/// 批量查询商品违规状态。
/// </summary>
public static List<GoodsViolationStatus> GetViolationStatus(List<long> goodsIds)
{
if (goodsIds == null)
{
throw new ArgumentNullException(nameof(goodsIds));
}
var html = GetHtml.PostJson(ServerUrl + "/api/CloudGoods/GetViolationStatus", goodsIds, timeOut: 5);
var ret = JsonConvert.DeserializeObject<Result<List<GoodsViolationStatus>>>(html);
if (ret == null)
{
throw new Exception("批量查询商品违规状态返回为空。");
}
if (ret.Code != 200)
{
throw new Exception(ret.Msg);
}
return ret.Data ?? throw new Exception("批量查询商品违规状态返回数据为空。");
}
#region user
/// <summary>
/// 搜索收藏
@@ -117,6 +408,42 @@ namespace Work.Services
return string.IsNullOrEmpty(BaseClass.ParentUserName) ? BaseClass.UserName : BaseClass.ParentUserName;
}
}
/// <summary>
/// 违规商品上报项。
/// </summary>
public class ReportGoodsViolationItem
{
[JsonProperty("goodsId")]
public long GoodsId { get; set; }
[JsonProperty("reasons")]
public string Reasons { get; set; } = string.Empty;
}
/// <summary>
/// 单个商品的违规上报结果。
/// </summary>
public class ReportGoodsViolationResult
{
[JsonProperty("goodsId")]
public long GoodsId { get; set; }
[JsonProperty("isOffShelf")]
public bool IsOffShelf { get; set; }
}
/// <summary>
/// 商品违规状态。
/// </summary>
public class GoodsViolationStatus
{
[JsonProperty("goodsId")]
public long GoodsId { get; set; }
[JsonProperty("isViolation")]
public bool IsViolation { get; set; }
}
/// <summary>
/// 商品搜索请求
/// </summary>
+11 -9
View File
@@ -12,15 +12,9 @@ using System.Threading.Tasks;
namespace Work.Services;
public class ImageCache
{
public string Md5 { get; set; }
public int Platform { get; set; }
[JsonProperty("platform_url")]
public string PlatformUrl { get; set; }
public bool IsCache { get; set; }
}
/// <summary>
/// 图片缓存服务
/// </summary>
public class ImageCacheService
{
private static string ServerUrl = "http://103.90.155.78:9001";
@@ -136,3 +130,11 @@ public class ImageCacheService
}
}
public class ImageCache
{
public string Md5 { get; set; }
public int Platform { get; set; }
[JsonProperty("platform_url")]
public string PlatformUrl { get; set; }
public bool IsCache { get; set; }
}