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 { /// 微信小店图片、文件分片及视频凭证接口;独立于原窗体,使用 HttpHelper 发送请求。 /// 传入原 ShopLoginInfo 登录信息;方法同步执行,界面调用请置于后台任务。返回原始正文,不自动登录、重试或解释业务状态。 public static class WxMediaApi { /// 获取商品视频上传临时凭证,对应 WXVideoUploader.GetUploadTempImgAuth 的店铺请求。 /// 店铺登录信息,Cookies 为原程序保存的 Cookie 列表 JSON。 /// 正在编辑的商品 ID,用于构造原视频上传页面 Referer。 /// 视频上传场景,原视频上传流程使用 100。 /// 含临时上传凭证的原始 JSON 或传输错误文字;调用方检查 code。 /// 此方法只获取店铺端凭证;视频域名的分片、转码流程仍由原上传器实现。 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); } /// 将已完成转码的视频播放地址换成商品媒体地址,对应 WXVideoUploader.GetMultiMediaDownloadUrl。 /// 店铺登录信息,Cookies 为原程序保存的 Cookie 列表 JSON。 /// 正在编辑的商品 ID,用于构造原视频上传页面 Referer。 /// 原视频上传流程轮询转码成功后返回的播放 URL。 /// 媒体下载地址的原始 JSON 或传输错误文字;调用方检查 code。 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()); } /// 获取图片上传临时凭证,供 UploadImage 使用。 /// 店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。 /// 上传场景的接口值,图片上传原调用使用 3。 默认值:3。 /// 微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。 /// /// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.getUploadTempImgAuth。 /// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。 /// 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; } /// 使用临时凭证向微信图片上传域名提交 Base64 图片。 /// 店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。 /// 纯 Base64 图片数据,不含 data:image 前缀。 /// GetUploadTempImgAuth 返回的临时上传签名 dis_k。 /// GetUploadTempImgAuth 返回的临时上传时间 dis_t,原值透传。 /// GetUploadTempImgAuth 返回的 ext 凭证,原值透传。 /// 微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。 /// /// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.adtimageupload。 /// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。 /// 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; } /// 初始化商品编辑资料的分片文件上传。 /// 店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。 /// 初始化分片上传请求的完整 JSON。 /// 微信商品 ID。 /// 原商品 lastEditDraftTime 值,按接口返回值透传到编辑页面上下文。 /// 原商品 listingTime 值,按接口返回值透传到编辑页面上下文。 /// 微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。 /// /// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.initUploadPart。 /// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。 /// 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; } /// 上传商品编辑文件的第一个分片,使用原 multipart 协议。 /// 店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。 /// 初始化分片上传接口返回的文件名。 /// 待上传文件的本地完整路径;不是网络图片 URL。 /// 初始化分片上传返回的上传任务 ID。 /// 微信商品 ID。 /// 原商品 lastEditDraftTime 值,按接口返回值透传到编辑页面上下文。 /// 原商品 listingTime 值,按接口返回值透传到编辑页面上下文。 /// 微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。 /// /// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.uploadPartBinary。 /// 保留旧行为:partSeq 固定为 1,本方法不负责多分片调度。文件必须存在且可读。 /// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。 /// 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; } /// 提交分片上传完成信息。 /// 店铺登录信息;Cookies 为原程序保存的 CefSharp.Cookie 列表 JSON,图片上传还需 openid。 /// 分片上传完成请求的完整 JSON,需包含此前上传返回的信息。 /// 微信商品 ID。 /// 原商品 lastEditDraftTime 值,按接口返回值透传到编辑页面上下文。 /// 原商品 listingTime 值,按接口返回值透传到编辑页面上下文。 /// 微信接口原始 JSON 正文;传输或登录参数配置失败可能返回错误文字。调用方须验证响应格式和业务状态,不能仅以非空判断成功。 /// /// 来源:TEMUKJD\WXForms\ProductForms\WXDBProdUploadForm.cs,WXUpload.completeUploadPart。 /// 原方法中直接拼接的 ID、JSON 数值片段应按上述格式传入;不会自动转义或转换单位。参数模型构造或序列化失败会向调用方抛出异常。 /// 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; } } }