164 lines
12 KiB
C#
164 lines
12 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|