Merge branch 'master' of github.com:KJD2025/KJD

This commit is contained in:
wule committed 2026-10-15 13:34:45 +08:00
commit 737670adec
17 files changed
+3826 -1064

No files matched your search

+351 -115
View File
@@ -11,23 +11,27 @@ using System.Linq;
namespace TemuKJD.BLL.ImportConverters
{
/// <summary>
/// 微信转拼多多数据源 V4版本
/// 针对微信商品详情API(/channels/ec/product/get)返回的完整数据结构
/// 微信转拼多多数据源 V4版本(兼容增强版)
/// 针对微信商品详情API(/channels/ec/product/get)返回的 detail.product 结构
///
/// 数据结构特点:
/// - 顶层为 { detail: { product: { product_key, info, product_skus, ... } } }
/// - info 节点包含商品基本信息、主图、详情图、参数、SKU列表等
/// - product_skus 节点包含完整的SKU信息(含库存、价格、规格)
/// - product_sale_attrs 节点包含销售属性(颜色、尺码)
/// - extra_service 节点包含售后服务信息
/// - qualification_list 节点包含资质信息
/// 兼容的数据样例:
/// - 10000031453165(女装针织衫,含视频、资质、完整size_chart)
/// - 10000182390569(不锈钢调味球,无视频、无资质列表、简化size_chart)
///
/// 兼容策略:
/// 1. 所有可选字段使用安全访问,缺失时回退
/// 2. 属性解析优先 param_v2,回退 categorys
/// 3. 规格解析优先 value_v2,回退 value
/// 4. SKU价格优先 sale_price,回退 sku_list.sku_info.price
/// 5. SKU库存优先 product_skus,回退 spu_total_stock 均分
/// </summary>
internal class ConverterWXToPddV4 : GoodsConverterBase
{
private JObject _jsonRoot;
private JObject _productNode; // detail.product
private JObject _infoNode; // detail.product.info
private JArray _skuList; // detail.product.info.product_skus
private JArray _skuList; // detail.product.info.sku_list.sku_info(价格兜底)
private JArray _productSkus; // detail.product.product_skus(完整SKU)
private JArray _saleAttrs; // detail.product.info.product_sale_attrs
public override string ConverterName => "微信转拼多多数据源 V4";
@@ -41,36 +45,41 @@ namespace TemuKJD.BLL.ImportConverters
_jsonRoot = JsonConvert.DeserializeObject<JObject>(RawData);
if (_jsonRoot == null) return false;
// 1. 检查是否为详情API格式(detail.product 结构)
// 1. 检查 detail.product 结构
var detail = _jsonRoot.SelectToken("$.detail") as JObject;
if (detail == null) return false;
var product = detail.SelectToken("$.product") as JObject;
if (product == null) return false;
// 2. 检查 product_key 是否存在
// 2. 检查 product_key.product_id
var productKey = product.SelectToken("$.product_key") as JObject;
if (productKey == null) return false;
var productId = productKey.SelectToken("$.product_id")?.ToString();
if (string.IsNullOrEmpty(productId)) return false;
// 3. 检查 info 节点是否存在
// 3. 检查 info 节点
var info = product.SelectToken("$.info") as JObject;
if (info == null) return false;
// 4. 检查是否有标题
// 4. 检查标题
var title = info.SelectToken("$.title")?.ToString();
if (string.IsNullOrEmpty(title)) return false;
// 5. 检查是否有SKU列表
var skus = product.SelectToken("$.product_skus") as JArray;
if (skus == null || skus.Count == 0) return false;
// 5. 检查SKU(兼容两种:product_skus 优先,sku_list.sku_info 兜底)
var productSkus = product.SelectToken("$.product_skus") as JArray;
var skuList = info.SelectToken("$.sku_list.sku_info") as JArray;
if ((productSkus == null || productSkus.Count == 0) &&
(skuList == null || skuList.Count == 0))
return false;
// 缓存节点
_productNode = product;
_infoNode = info;
_skuList = skus;
_productSkus = productSkus;
_skuList = skuList;
_saleAttrs = info.SelectToken("$.product_sale_attrs") as JArray;
return true;
@@ -88,14 +97,12 @@ namespace TemuKJD.BLL.ImportConverters
Platform = Platform,
GoodsId = ParseGoodsId()
};
product.ListingTime = GetListingTime();
// ========== 1. 商品基本信息 ==========
product.Title = GetStringValue(_infoNode, "title");
product.Description = GetStringValue(_infoNode, "short_title");
if (string.IsNullOrEmpty(product.Description))
{
product.Description = GetStringValue(_infoNode, "ai_gen_short_title");
}
// ========== 2. 品牌信息 ==========
product.BrandId = GetLongValue(_infoNode, "brand_id");
@@ -130,20 +137,21 @@ namespace TemuKJD.BLL.ImportConverters
#region 核心字段解析
/// <summary>
/// 解析商品ID
/// 解析商品ID(兼容 out_product_id 存在与否)
/// </summary>
private long ParseGoodsId()
{
// 优先 product_id(所有情况都存在)
var productId = _productNode.SelectToken("$.product_key.product_id")?.ToString();
if (long.TryParse(productId, out var result))
return result;
// 回退到文件路径
// 回退文件路径
return Path.GetFileNameWithoutExtension(FilePath).ParseToLong();
}
/// <summary>
/// 获取类目ID(取最细分类目)
/// 获取类目ID(兼容 category 数组,取最细分类目)
/// </summary>
private int GetCategoryId()
{
@@ -151,7 +159,6 @@ namespace TemuKJD.BLL.ImportConverters
if (category == null || category.Count == 0)
return 0;
// 取最后一个类目(最细分类目)
var lastCat = category.Last as JObject;
return lastCat?["cat_id"]?.Value<int>() ?? 0;
}
@@ -183,7 +190,7 @@ namespace TemuKJD.BLL.ImportConverters
{
var result = new List<string>();
// 优先使用 head_img 数组
// 优先 head_img
var headImg = _infoNode["head_img"] as JArray;
if (headImg != null && headImg.Count > 0)
{
@@ -196,7 +203,7 @@ namespace TemuKJD.BLL.ImportConverters
return result;
}
// 回退到 head_img_infos
// 回退 head_img_infos
var headImgInfos = _infoNode["head_img_infos"] as JArray;
if (headImgInfos != null)
{
@@ -236,7 +243,10 @@ namespace TemuKJD.BLL.ImportConverters
}
/// <summary>
/// 获取商品属性列表(从 param 节点解析)
/// 获取商品属性列表(从 info.param 解析)
/// 兼容两种结构:
/// - 10000031453165:categorys[0].name = key, categorys[1].name = value
/// - 10000182390569:categorys[0].name = key, categorys[1].name = value(相同)
/// </summary>
private List<Property> GetProperties()
{
@@ -256,7 +266,6 @@ namespace TemuKJD.BLL.ImportConverters
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
{
// 去重
if (!result.Any(p => p.Key == key))
{
result.Add(new Property
@@ -272,7 +281,7 @@ namespace TemuKJD.BLL.ImportConverters
}
/// <summary>
/// 获取视频URL列表
/// 获取视频URL列表(兼容无视频的情况)
/// </summary>
private List<string> GetVideoUrls()
{
@@ -290,18 +299,6 @@ namespace TemuKJD.BLL.ImportConverters
return result;
}
private DateTime? GetListingTime()
{
string time = _infoNode["listing_time"].ToString();
if (time != null)
{
if (int.TryParse(time, out int v))
{
return NaiBa.Util.Helper.DateTimeHelper.IntStampToDateTime(v);
}
}
return null;
}
#endregion
@@ -309,87 +306,324 @@ namespace TemuKJD.BLL.ImportConverters
/// <summary>
/// 获取SKU和规格信息
/// 兼容两种数据:
/// - product_skus:包含 sku_key.sku_id、sale_param、sale_price、stock_info
/// - sku_list.sku_info:包含 sku_id、price、estimate_price(无规格、无库存)
/// </summary>
private Tuple<List<SkuItem>, List<SpecItem>> GetSkusAndSpecs()
private Tuple<List<SkuItem> , List<SpecItem>> GetSkusAndSpecs()
{
var skuList = new List<SkuItem>();
var specList = new List<SpecItem>();
if (_skuList == null || _skuList.Count == 0)
return new Tuple<List<SkuItem>, List<SpecItem>>(skuList, specList);
// 构建 sku_list.sku_info 的价格字典(作为兜底)
var priceFallbackDict = BuildPriceFallbackDict();
// 收集所有规格
var specDict = new Dictionary<string, HashSet<string>>();
// 构建 product_sale_attrs 的规格字典(作为兜底)
var attrFallbackDict = BuildAttrFallbackDict();
// 优先处理 product_skus(完整信息)
if (_productSkus != null && _productSkus.Count > 0)
{
foreach (var sku in _productSkus)
{
var skuObj = sku as JObject;
if (skuObj == null) continue;
var skuItem = ParseProductSku(skuObj, priceFallbackDict, attrFallbackDict);
if (skuItem != null)
skuList.Add(skuItem);
}
}
// 回退到 sku_list.sku_info(仅价格)
else if (_skuList != null && _skuList.Count > 0)
{
foreach (var sku in _skuList)
{
var skuObj = sku as JObject;
if (skuObj == null) continue;
var skuItem = ParseSkuInfoOnly(skuObj, attrFallbackDict);
if (skuItem != null)
skuList.Add(skuItem);
}
}
// 构建规格列表(优先 product_sale_attrs)
BuildSpecList(specList, skuList);
return new Tuple<List<SkuItem>, List<SpecItem>>(skuList, specList);
}
/// <summary>
/// 构建 sku_list.sku_info 的价格兜底字典
/// </summary>
private Dictionary<string, decimal> BuildPriceFallbackDict()
{
var dict = new Dictionary<string, decimal>();
if (_skuList == null) return dict;
foreach (var sku in _skuList)
{
var skuObj = sku as JObject;
if (skuObj == null) continue;
// 获取 SKU 基本信息
var skuKey = skuObj["sku_key"] as JObject;
var skuInfo = skuObj["product_sku_info"] as JObject;
if (skuKey == null || skuInfo == null) continue;
var skuId = skuObj["sku_id"]?.Value<string>();
if (string.IsNullOrEmpty(skuId)) continue;
var skuId = skuKey["sku_id"]?.Value<string>() ?? string.Empty;
var outSkuId = skuKey["out_sku_id"]?.Value<string>() ?? string.Empty;
// 优先 estimate_price(优惠后),回退 price
var estimatePrice = skuObj["estimate_price"]?.Value<decimal>() ?? 0;
var price = skuObj["price"]?.Value<decimal>() ?? 0;
var actualPrice = estimatePrice > 0 ? estimatePrice : price;
// 解析销售属性
var saleParams = skuInfo["sale_param"] as JArray;
var specValues = new List<string>();
dict[skuId] = actualPrice;
}
if (saleParams != null)
return dict;
}
/// <summary>
/// 构建 product_sale_attrs 的规格兜底字典(skuId -> spec文本)
/// 兼容两种结构:
/// - 10000031453165:items[].value_v2, items[].sku_ids[]
/// - 10000182390569:items[].value, items[].sku_ids[]
/// </summary>
private Dictionary<string, string> BuildAttrFallbackDict()
{
var dict = new Dictionary<string, string>();
if (_saleAttrs == null) return dict;
foreach (var attr in _saleAttrs)
{
var key = attr["key"]?.Value<string>() ?? string.Empty;
var items = attr["items"] as JArray;
if (items == null) continue;
foreach (var item in items)
{
foreach (var param in saleParams)
{
var paramV2 = param["param_v2"] as JObject;
if (paramV2 == null) continue;
// 兼容 value_v2 和 value
var value = item["value_v2"]?.Value<string>();
if (string.IsNullOrEmpty(value))
value = item["value"]?.Value<string>();
if (string.IsNullOrEmpty(value)) continue;
var skuIds = item["sku_ids"] as JArray;
if (skuIds == null) continue;
var specText = $"{key}:{value}";
foreach (var skuId in skuIds)
{
var id = skuId?.Value<string>();
if (!string.IsNullOrEmpty(id))
dict[id] = specText;
}
}
}
return dict;
}
/// <summary>
/// 解析 product_skus 中的单个SKU
/// </summary>
private SkuItem ParseProductSku(
JObject skuObj,
Dictionary<string, decimal> priceFallbackDict,
Dictionary<string, string> attrFallbackDict)
{
var skuKey = skuObj["sku_key"] as JObject;
var skuInfo = skuObj["product_sku_info"] as JObject;
if (skuKey == null || skuInfo == null) return null;
var skuId = skuKey["sku_id"]?.Value<string>() ?? string.Empty;
var outSkuId = skuKey["out_sku_id"]?.Value<string>() ?? string.Empty;
if (string.IsNullOrEmpty(skuId)) return null;
// 解析规格
var specText = ParseSkuSpec(skuInfo, skuId, attrFallbackDict);
// 解析价格
var salePrice = skuInfo["sale_price"]?.Value<decimal>() ?? 0;
if (salePrice <= 0 && priceFallbackDict.TryGetValue(skuId, out var fallbackPrice))
salePrice = fallbackPrice;
// 解析库存
var stockNum = ParseStockNum(skuInfo);
// 缩略图
var thumbImg = skuInfo["thumb_img"]?.Value<string>() ?? string.Empty;
return new SkuItem
{
SkuId = !string.IsNullOrEmpty(outSkuId) ? outSkuId : skuId,
Spec = specText,
Price = salePrice / 100, // 分转元
OriginalPrice = salePrice.ToString(),
Stock = stockNum,
SpecImage = thumbImg
};
}
/// <summary>
/// 解析 sku_list.sku_info 中的单个SKU(仅价格)
/// </summary>
private SkuItem ParseSkuInfoOnly(
JObject skuObj,
Dictionary<string, string> attrFallbackDict)
{
var skuId = skuObj["sku_id"]?.Value<string>() ?? string.Empty;
if (string.IsNullOrEmpty(skuId)) return null;
// 规格从 attrFallbackDict 获取
var specText = attrFallbackDict.TryGetValue(skuId, out var spec) ? spec : string.Empty;
// 价格
var estimatePrice = skuObj["estimate_price"]?.Value<decimal>() ?? 0;
var price = skuObj["price"]?.Value<decimal>() ?? 0;
var actualPrice = estimatePrice > 0 ? estimatePrice : price;
return new SkuItem
{
SkuId = skuId,
Spec = specText,
Price = actualPrice / 100,
OriginalPrice = actualPrice.ToString(),
Stock = 0,
SpecImage = string.Empty
};
}
/// <summary>
/// 解析SKU规格
/// 兼容两种结构:
/// - 10000031453165:sale_param[].param_v2.attr_name / attr_value_name
/// - 10000182390569:sale_param[].categorys[0].name / categorys[1].name
/// </summary>
private string ParseSkuSpec(
JObject skuInfo,
string skuId,
Dictionary<string, string> attrFallbackDict)
{
var specValues = new List<string>();
var saleParams = skuInfo["sale_param"] as JArray;
if (saleParams != null)
{
foreach (var param in saleParams)
{
// 优先 param_v2
var paramV2 = param["param_v2"] as JObject;
if (paramV2 != null)
{
var attrName = paramV2["attr_name"]?.Value<string>() ?? string.Empty;
var attrValue = paramV2["attr_value_name"]?.Value<string>() ?? string.Empty;
if (!string.IsNullOrEmpty(attrName) && !string.IsNullOrEmpty(attrValue))
{
specValues.Add($"{attrName}:{attrValue}");
continue;
}
}
// 收集规格
if (!specDict.ContainsKey(attrName))
specDict[attrName] = new HashSet<string>();
specDict[attrName].Add(attrValue);
// 回退 categorys
var categorys = param["categorys"] as JArray;
if (categorys != null && categorys.Count >= 2)
{
var attrName = categorys[0]?["name"]?.Value<string>() ?? string.Empty;
var attrValue = categorys[1]?["name"]?.Value<string>() ?? string.Empty;
if (!string.IsNullOrEmpty(attrName) && !string.IsNullOrEmpty(attrValue))
{
specValues.Add($"{attrName}:{attrValue}");
}
}
}
// 价格(单位:分)
var salePrice = skuInfo["sale_price"]?.Value<decimal>() ?? 0;
// 库存
var stockInfo = skuInfo["stock_info"] as JObject;
var stockNum = 0;
if (stockInfo != null)
{
var stockStr = stockInfo["stock_num"]?.Value<string>();
if (!string.IsNullOrEmpty(stockStr))
{
int.TryParse(stockStr, out stockNum);
}
}
// 缩略图
var thumbImg = skuInfo["thumb_img"]?.Value<string>() ?? string.Empty;
skuList.Add(new SkuItem
{
SkuId = !string.IsNullOrEmpty(outSkuId) ? outSkuId : skuId,
Spec = string.Join(";", specValues),
Price = salePrice / 100, // 分转元
OriginalPrice = salePrice.ToString(),
Stock = stockNum,
SpecImage = thumbImg
});
}
// 构建规格列表
// 如果无法从 sale_param 解析,从 attrFallbackDict 兜底
if (specValues.Count == 0 && attrFallbackDict.TryGetValue(skuId, out var fallbackSpec))
{
specValues.Add(fallbackSpec);
}
return string.Join(";", specValues);
}
/// <summary>
/// 解析库存(兼容字符串/数字格式)
/// </summary>
private int ParseStockNum(JObject skuInfo)
{
var stockInfo = skuInfo["stock_info"] as JObject;
if (stockInfo == null) return 0;
var stockToken = stockInfo["stock_num"];
if (stockToken == null) return 0;
if (stockToken.Type == JTokenType.String)
{
return int.TryParse(stockToken.Value<string>(), out var result) ? result : 0;
}
return stockToken.Value<int>();
}
/// <summary>
/// 构建规格列表
/// 优先从 product_sale_attrs 构建,回退从SKU的spec文本解析
/// </summary>
private void BuildSpecList(List<SpecItem> specList, List<SkuItem> skus)
{
var specDict = new Dictionary<string, HashSet<string>>();
// 优先从 product_sale_attrs 构建
if (_saleAttrs != null && _saleAttrs.Count > 0)
{
foreach (var attr in _saleAttrs)
{
var key = attr["key"]?.Value<string>() ?? string.Empty;
var items = attr["items"] as JArray;
if (items == null) continue;
foreach (var item in items)
{
// 兼容 value_v2 和 value
var value = item["value_v2"]?.Value<string>();
if (string.IsNullOrEmpty(value))
value = item["value"]?.Value<string>();
if (string.IsNullOrEmpty(value)) continue;
if (!specDict.ContainsKey(key))
specDict[key] = new HashSet<string>();
specDict[key].Add(value);
}
}
}
// 如果 product_sale_attrs 不存在,从SKU的spec文本解析
if (specDict.Count == 0 && skus.Count > 0)
{
foreach (var sku in skus)
{
if (string.IsNullOrEmpty(sku.Spec)) continue;
foreach (var part in sku.Spec.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
{
var kv = part.Split(':');
if (kv.Length == 2)
{
var key = kv[0].Trim();
var value = kv[1].Trim();
if (!specDict.ContainsKey(key))
specDict[key] = new HashSet<string>();
specDict[key].Add(value);
}
}
}
}
// 构建 SpecItem 列表
foreach (var spec in specDict)
{
foreach (var value in spec.Value)
@@ -403,8 +637,6 @@ namespace TemuKJD.BLL.ImportConverters
});
}
}
return new Tuple<List<SkuItem>, List<SpecItem>>(skuList, specList);
}
/// <summary>
@@ -412,33 +644,37 @@ namespace TemuKJD.BLL.ImportConverters
/// </summary>
private decimal GetMinPrice()
{
if (_skuList == null || _skuList.Count == 0)
return 0;
var minPrice = decimal.MaxValue;
foreach (var sku in _skuList)
// 优先从 product_skus 获取
if (_productSkus != null && _productSkus.Count > 0)
{
var skuObj = sku as JObject;
if (skuObj == null) continue;
var minPrice = decimal.MaxValue;
foreach (var sku in _productSkus)
{
var skuObj = sku as JObject;
if (skuObj == null) continue;
var skuInfo = skuObj["product_sku_info"] as JObject;
if (skuInfo == null) continue;
var skuInfo = skuObj["product_sku_info"] as JObject;
if (skuInfo == null) continue;
var price = skuInfo["sale_price"]?.Value<decimal>() ?? 0;
if (price > 0 && price < minPrice)
minPrice = price;
var price = skuInfo["sale_price"]?.Value<decimal>() ?? 0;
if (price > 0 && price < minPrice)
minPrice = price;
}
if (minPrice > 0 && minPrice != decimal.MaxValue)
return minPrice / 100;
}
// 回退到 sku_list.min_price
if (minPrice == decimal.MaxValue)
// 回退 sku_list.min_price
var skuListInfo = _infoNode["sku_list"] as JObject;
if (skuListInfo != null)
{
var skuListInfo = _infoNode["sku_list"] as JObject;
var minPriceToken = skuListInfo?["min_price"]?.Value<decimal>() ?? 0;
return minPriceToken / 100;
var minPriceToken = skuListInfo["min_price"]?.Value<decimal>() ?? 0;
if (minPriceToken > 0)
return minPriceToken / 100;
}
return minPrice > 0 ? minPrice / 100 : 0;
return 0;
}
#endregion
+3
View File
@@ -68,6 +68,9 @@
<ProjectReference Include="..\Work\Work.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="PDDForms\ProductSelectForms\CloudGoodsFavoriteForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="PDDForms\ProductSelectForms\CloudGoodsForm.cs">
<SubType>Form</SubType>
</Compile>
@@ -0,0 +1,636 @@
namespace TemuKJD.PDDForms.ProductSelectForms
{
partial class CloudGoodsFavoriteForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle10 = new System.Windows.Forms.DataGridViewCellStyle();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.panel1 = new System.Windows.Forms.Panel();
this.btn_removefavorite = new DevComponents.DotNetBar.PanelEx();
this.bt_importUploadList = new DevComponents.DotNetBar.PanelEx();
this.label5r = new System.Windows.Forms.Label();
this.cb_Platform = new System.Windows.Forms.ComboBox();
this.cmbCatSelect2 = new System.Windows.Forms.ComboBox();
this.cmbCatSelect1 = new System.Windows.Forms.ComboBox();
this.cmbCatSelect4 = new System.Windows.Forms.ComboBox();
this.cmbCatSelect3 = new System.Windows.Forms.ComboBox();
this.label4 = new System.Windows.Forms.Label();
this.num_maxprice = new System.Windows.Forms.NumericUpDown();
this.num_minprice = new System.Windows.Forms.NumericUpDown();
this.label7 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.num_maxsold = new System.Windows.Forms.NumericUpDown();
this.num_minsold = new System.Windows.Forms.NumericUpDown();
this.txt_title = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.btnSearch = new DevComponents.DotNetBar.PanelEx();
this.pnlEmpty = new DevComponents.DotNetBar.PanelEx();
this.label2 = new System.Windows.Forms.Label();
this.splitContainer2 = new System.Windows.Forms.SplitContainer();
this.pbLoading = new System.Windows.Forms.PictureBox();
this.dgvData = new TemuKJD.UserComponent.DataGridViewEx();
this.colSelect = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.c_Platform = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column1 = new System.Windows.Forms.DataGridViewImageColumn();
this.c_goodsid = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column4 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.ucSplitPage1 = new TemuKJD.UserControls.UcSplitPage();
this.statusBar = new TemuKJD.UserControls.StatusBarUserControl();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.num_maxprice)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.num_minprice)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.num_maxsold)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.num_minsold)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit();
this.splitContainer2.Panel1.SuspendLayout();
this.splitContainer2.Panel2.SuspendLayout();
this.splitContainer2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pbLoading)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.dgvData)).BeginInit();
this.SuspendLayout();
//
// splitContainer1
//
this.splitContainer1.BackColor = System.Drawing.Color.White;
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.panel1);
this.splitContainer1.Panel1.Controls.Add(this.label5r);
this.splitContainer1.Panel1.Controls.Add(this.cb_Platform);
this.splitContainer1.Panel1.Controls.Add(this.cmbCatSelect2);
this.splitContainer1.Panel1.Controls.Add(this.cmbCatSelect1);
this.splitContainer1.Panel1.Controls.Add(this.cmbCatSelect4);
this.splitContainer1.Panel1.Controls.Add(this.cmbCatSelect3);
this.splitContainer1.Panel1.Controls.Add(this.label4);
this.splitContainer1.Panel1.Controls.Add(this.num_maxprice);
this.splitContainer1.Panel1.Controls.Add(this.num_minprice);
this.splitContainer1.Panel1.Controls.Add(this.label7);
this.splitContainer1.Panel1.Controls.Add(this.label3);
this.splitContainer1.Panel1.Controls.Add(this.num_maxsold);
this.splitContainer1.Panel1.Controls.Add(this.num_minsold);
this.splitContainer1.Panel1.Controls.Add(this.txt_title);
this.splitContainer1.Panel1.Controls.Add(this.label1);
this.splitContainer1.Panel1.Controls.Add(this.label6);
this.splitContainer1.Panel1.Controls.Add(this.btnSearch);
this.splitContainer1.Panel1.Controls.Add(this.pnlEmpty);
this.splitContainer1.Panel1.Controls.Add(this.label2);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.splitContainer2);
this.splitContainer1.Panel2.Margin = new System.Windows.Forms.Padding(4);
this.splitContainer1.Size = new System.Drawing.Size(1643, 530);
this.splitContainer1.TabIndex = 35;
//
// panel1
//
this.panel1.Controls.Add(this.btn_removefavorite);
this.panel1.Controls.Add(this.bt_importUploadList);
this.panel1.Dock = System.Windows.Forms.DockStyle.Right;
this.panel1.Location = new System.Drawing.Point(1507, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(136, 50);
this.panel1.TabIndex = 914;
//
// btn_removefavorite
//
this.btn_removefavorite.ColorSchemeStyle = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled;
this.btn_removefavorite.Cursor = System.Windows.Forms.Cursors.Hand;
this.btn_removefavorite.DisabledBackColor = System.Drawing.Color.Empty;
this.btn_removefavorite.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.btn_removefavorite.Location = new System.Drawing.Point(67, 14);
this.btn_removefavorite.Name = "btn_removefavorite";
this.btn_removefavorite.Size = new System.Drawing.Size(58, 23);
this.btn_removefavorite.Style.Alignment = System.Drawing.StringAlignment.Center;
this.btn_removefavorite.Style.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255)))));
this.btn_removefavorite.Style.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255)))));
this.btn_removefavorite.Style.BorderColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBorder;
this.btn_removefavorite.Style.BorderDashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
this.btn_removefavorite.Style.BorderSide = DevComponents.DotNetBar.eBorderSide.None;
this.btn_removefavorite.Style.ForeColor.Color = System.Drawing.Color.White;
this.btn_removefavorite.Style.GradientAngle = 90;
this.btn_removefavorite.StyleMouseOver.Alignment = System.Drawing.StringAlignment.Center;
this.btn_removefavorite.StyleMouseOver.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(102)))), ((int)(((byte)(255)))));
this.btn_removefavorite.StyleMouseOver.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(102)))), ((int)(((byte)(255)))));
this.btn_removefavorite.TabIndex = 447;
this.btn_removefavorite.Text = "取消收藏";
this.btn_removefavorite.Click += new System.EventHandler(this.btn_removefavorite_Click);
//
// bt_importUploadList
//
this.bt_importUploadList.ColorSchemeStyle = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled;
this.bt_importUploadList.Cursor = System.Windows.Forms.Cursors.Hand;
this.bt_importUploadList.DisabledBackColor = System.Drawing.Color.Empty;
this.bt_importUploadList.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.bt_importUploadList.Location = new System.Drawing.Point(3, 14);
this.bt_importUploadList.Name = "bt_importUploadList";
this.bt_importUploadList.Size = new System.Drawing.Size(58, 23);
this.bt_importUploadList.Style.Alignment = System.Drawing.StringAlignment.Center;
this.bt_importUploadList.Style.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255)))));
this.bt_importUploadList.Style.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255)))));
this.bt_importUploadList.Style.BorderColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBorder;
this.bt_importUploadList.Style.BorderDashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
this.bt_importUploadList.Style.BorderSide = DevComponents.DotNetBar.eBorderSide.None;
this.bt_importUploadList.Style.ForeColor.Color = System.Drawing.Color.White;
this.bt_importUploadList.Style.GradientAngle = 90;
this.bt_importUploadList.StyleMouseOver.Alignment = System.Drawing.StringAlignment.Center;
this.bt_importUploadList.StyleMouseOver.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(102)))), ((int)(((byte)(255)))));
this.bt_importUploadList.StyleMouseOver.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(102)))), ((int)(((byte)(255)))));
this.bt_importUploadList.TabIndex = 443;
this.bt_importUploadList.Text = "上传选中";
this.bt_importUploadList.Click += new System.EventHandler(this.bt_importUploadList_Click);
//
// label5r
//
this.label5r.AutoSize = true;
this.label5r.Location = new System.Drawing.Point(1048, 16);
this.label5r.Name = "label5r";
this.label5r.Size = new System.Drawing.Size(44, 17);
this.label5r.TabIndex = 907;
this.label5r.Text = "来源:";
//
// cb_Platform
//
this.cb_Platform.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cb_Platform.DropDownWidth = 150;
this.cb_Platform.FormattingEnabled = true;
this.cb_Platform.Items.AddRange(new object[] {
"全部",
"多多",
"微信"});
this.cb_Platform.Location = new System.Drawing.Point(1098, 13);
this.cb_Platform.Name = "cb_Platform";
this.cb_Platform.Size = new System.Drawing.Size(97, 25);
this.cb_Platform.TabIndex = 906;
//
// cmbCatSelect2
//
this.cmbCatSelect2.DropDownWidth = 150;
this.cmbCatSelect2.FormattingEnabled = true;
this.cmbCatSelect2.Location = new System.Drawing.Point(745, 12);
this.cmbCatSelect2.Name = "cmbCatSelect2";
this.cmbCatSelect2.Size = new System.Drawing.Size(97, 25);
this.cmbCatSelect2.TabIndex = 897;
//
// cmbCatSelect1
//
this.cmbCatSelect1.DropDownWidth = 150;
this.cmbCatSelect1.FormattingEnabled = true;
this.cmbCatSelect1.Location = new System.Drawing.Point(648, 12);
this.cmbCatSelect1.Name = "cmbCatSelect1";
this.cmbCatSelect1.Size = new System.Drawing.Size(97, 25);
this.cmbCatSelect1.TabIndex = 896;
//
// cmbCatSelect4
//
this.cmbCatSelect4.DropDownWidth = 150;
this.cmbCatSelect4.FormattingEnabled = true;
this.cmbCatSelect4.Location = new System.Drawing.Point(939, 12);
this.cmbCatSelect4.Name = "cmbCatSelect4";
this.cmbCatSelect4.Size = new System.Drawing.Size(97, 25);
this.cmbCatSelect4.TabIndex = 899;
//
// cmbCatSelect3
//
this.cmbCatSelect3.DropDownWidth = 150;
this.cmbCatSelect3.FormattingEnabled = true;
this.cmbCatSelect3.Location = new System.Drawing.Point(842, 12);
this.cmbCatSelect3.Name = "cmbCatSelect3";
this.cmbCatSelect3.Size = new System.Drawing.Size(97, 25);
this.cmbCatSelect3.TabIndex = 898;
//
// label4
//
this.label4.AutoSize = true;
this.label4.ForeColor = System.Drawing.Color.Gray;
this.label4.Location = new System.Drawing.Point(518, 17);
this.label4.Margin = new System.Windows.Forms.Padding(0);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(13, 17);
this.label4.TabIndex = 488;
this.label4.Text = "-";
//
// num_maxprice
//
this.num_maxprice.Location = new System.Drawing.Point(534, 14);
this.num_maxprice.Maximum = new decimal(new int[] {
99999,
0,
0,
0});
this.num_maxprice.Name = "num_maxprice";
this.num_maxprice.Size = new System.Drawing.Size(70, 23);
this.num_maxprice.TabIndex = 487;
//
// num_minprice
//
this.num_minprice.Location = new System.Drawing.Point(447, 14);
this.num_minprice.Maximum = new decimal(new int[] {
99999,
0,
0,
0});
this.num_minprice.Name = "num_minprice";
this.num_minprice.Size = new System.Drawing.Size(70, 23);
this.num_minprice.TabIndex = 486;
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(388, 17);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(64, 17);
this.label7.TabIndex = 485;
this.label7.Text = "价格(元):";
//
// label3
//
this.label3.AutoSize = true;
this.label3.ForeColor = System.Drawing.Color.Gray;
this.label3.Location = new System.Drawing.Point(294, 17);
this.label3.Margin = new System.Windows.Forms.Padding(0);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(13, 17);
this.label3.TabIndex = 484;
this.label3.Text = "-";
//
// num_maxsold
//
this.num_maxsold.Location = new System.Drawing.Point(310, 14);
this.num_maxsold.Maximum = new decimal(new int[] {
9999999,
0,
0,
0});
this.num_maxsold.Name = "num_maxsold";
this.num_maxsold.Size = new System.Drawing.Size(70, 23);
this.num_maxsold.TabIndex = 483;
//
// num_minsold
//
this.num_minsold.Location = new System.Drawing.Point(223, 14);
this.num_minsold.Maximum = new decimal(new int[] {
9999999,
0,
0,
0});
this.num_minsold.Name = "num_minsold";
this.num_minsold.Size = new System.Drawing.Size(70, 23);
this.num_minsold.TabIndex = 482;
//
// txt_title
//
this.txt_title.Location = new System.Drawing.Point(60, 14);
this.txt_title.Name = "txt_title";
this.txt_title.Size = new System.Drawing.Size(118, 23);
this.txt_title.TabIndex = 468;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(8, 17);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(56, 17);
this.label1.TabIndex = 469;
this.label1.Text = "关键词:";
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(610, 17);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(44, 17);
this.label6.TabIndex = 440;
this.label6.Text = "类目:";
//
// btnSearch
//
this.btnSearch.ColorSchemeStyle = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled;
this.btnSearch.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnSearch.DisabledBackColor = System.Drawing.Color.Empty;
this.btnSearch.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.btnSearch.Location = new System.Drawing.Point(1208, 14);
this.btnSearch.Name = "btnSearch";
this.btnSearch.Size = new System.Drawing.Size(58, 23);
this.btnSearch.Style.Alignment = System.Drawing.StringAlignment.Center;
this.btnSearch.Style.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255)))));
this.btnSearch.Style.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255)))));
this.btnSearch.Style.BorderColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBorder;
this.btnSearch.Style.BorderDashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
this.btnSearch.Style.BorderSide = DevComponents.DotNetBar.eBorderSide.None;
this.btnSearch.Style.ForeColor.Color = System.Drawing.Color.White;
this.btnSearch.Style.GradientAngle = 90;
this.btnSearch.StyleMouseOver.Alignment = System.Drawing.StringAlignment.Center;
this.btnSearch.StyleMouseOver.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(102)))), ((int)(((byte)(255)))));
this.btnSearch.StyleMouseOver.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(102)))), ((int)(((byte)(255)))));
this.btnSearch.TabIndex = 435;
this.btnSearch.Text = "查询";
this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
//
// pnlEmpty
//
this.pnlEmpty.CanvasColor = System.Drawing.SystemColors.Control;
this.pnlEmpty.ColorSchemeStyle = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled;
this.pnlEmpty.DisabledBackColor = System.Drawing.Color.Empty;
this.pnlEmpty.Location = new System.Drawing.Point(1272, 14);
this.pnlEmpty.Name = "pnlEmpty";
this.pnlEmpty.Size = new System.Drawing.Size(58, 23);
this.pnlEmpty.Style.Alignment = System.Drawing.StringAlignment.Center;
this.pnlEmpty.Style.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(185)))), ((int)(((byte)(215)))), ((int)(((byte)(255)))));
this.pnlEmpty.Style.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(185)))), ((int)(((byte)(215)))), ((int)(((byte)(255)))));
this.pnlEmpty.Style.Border = DevComponents.DotNetBar.eBorderType.SingleLine;
this.pnlEmpty.Style.BorderColor.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255)))));
this.pnlEmpty.Style.ForeColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelText;
this.pnlEmpty.Style.GradientAngle = 90;
this.pnlEmpty.StyleMouseDown.Alignment = System.Drawing.StringAlignment.Center;
this.pnlEmpty.StyleMouseOver.Alignment = System.Drawing.StringAlignment.Center;
this.pnlEmpty.StyleMouseOver.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255)))));
this.pnlEmpty.StyleMouseOver.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255)))));
this.pnlEmpty.StyleMouseOver.ForeColor.Color = System.Drawing.Color.White;
this.pnlEmpty.TabIndex = 413;
this.pnlEmpty.Text = "清空条件";
this.pnlEmpty.Click += new System.EventHandler(this.pnlEmpty_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(184, 17);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(44, 17);
this.label2.TabIndex = 373;
this.label2.Text = "销量:";
//
// splitContainer2
//
this.splitContainer2.BackColor = System.Drawing.Color.White;
this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer2.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
this.splitContainer2.Location = new System.Drawing.Point(0, 0);
this.splitContainer2.Name = "splitContainer2";
this.splitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer2.Panel1
//
this.splitContainer2.Panel1.BackColor = System.Drawing.Color.White;
this.splitContainer2.Panel1.Controls.Add(this.pbLoading);
this.splitContainer2.Panel1.Controls.Add(this.dgvData);
this.splitContainer2.Panel1.Padding = new System.Windows.Forms.Padding(4, 0, 4, 0);
//
// splitContainer2.Panel2
//
this.splitContainer2.Panel2.Controls.Add(this.ucSplitPage1);
this.splitContainer2.Panel2.Controls.Add(this.statusBar);
this.splitContainer2.Size = new System.Drawing.Size(1643, 476);
this.splitContainer2.SplitterDistance = 447;
this.splitContainer2.TabIndex = 0;
//
// pbLoading
//
this.pbLoading.Anchor = System.Windows.Forms.AnchorStyles.None;
this.pbLoading.Image = global::TemuKJD.Properties.Resources.loading_blue;
this.pbLoading.Location = new System.Drawing.Point(796, 198);
this.pbLoading.Name = "pbLoading";
this.pbLoading.Size = new System.Drawing.Size(50, 50);
this.pbLoading.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pbLoading.TabIndex = 6;
this.pbLoading.TabStop = false;
//
// dgvData
//
this.dgvData.AllowUserToAddRows = false;
this.dgvData.AllowUserToDeleteRows = false;
dataGridViewCellStyle9.BackColor = System.Drawing.Color.WhiteSmoke;
this.dgvData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle9;
this.dgvData.AutoRowNumber = true;
this.dgvData.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
this.dgvData.BackgroundColor = System.Drawing.Color.White;
this.dgvData.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255)))));
dataGridViewCellStyle10.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle10.BackColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle10.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
dataGridViewCellStyle10.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle10.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle10.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle10.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dgvData.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle10;
this.dgvData.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dgvData.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.colSelect,
this.c_Platform,
this.Column1,
this.c_goodsid,
this.Column2,
this.Column3,
this.Column4});
this.dgvData.Dock = System.Windows.Forms.DockStyle.Fill;
this.dgvData.Location = new System.Drawing.Point(4, 0);
this.dgvData.MultiSelectCheckBox = true;
this.dgvData.Name = "dgvData";
this.dgvData.ReadOnly = true;
this.dgvData.RowTemplate.Height = 60;
this.dgvData.ShowCellErrors = false;
this.dgvData.Size = new System.Drawing.Size(1635, 447);
this.dgvData.TabIndex = 5;
//
// colSelect
//
this.colSelect.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
this.colSelect.FillWeight = 26F;
this.colSelect.HeaderText = "选";
this.colSelect.Name = "colSelect";
this.colSelect.ReadOnly = true;
this.colSelect.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.colSelect.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
this.colSelect.Width = 30;
//
// c_Platform
//
this.c_Platform.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
this.c_Platform.HeaderText = "来源";
this.c_Platform.Name = "c_Platform";
this.c_Platform.ReadOnly = true;
this.c_Platform.Width = 80;
//
// Column1
//
this.Column1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
this.Column1.FillWeight = 44.62474F;
this.Column1.HeaderText = "主图";
this.Column1.ImageLayout = System.Windows.Forms.DataGridViewImageCellLayout.Zoom;
this.Column1.MinimumWidth = 60;
this.Column1.Name = "Column1";
this.Column1.ReadOnly = true;
this.Column1.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.Column1.Width = 200;
//
// c_goodsid
//
this.c_goodsid.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
this.c_goodsid.FillWeight = 60.68966F;
this.c_goodsid.HeaderText = "商品ID";
this.c_goodsid.Name = "c_goodsid";
this.c_goodsid.ReadOnly = true;
this.c_goodsid.Width = 180;
//
// Column2
//
this.Column2.FillWeight = 111.5619F;
this.Column2.HeaderText = "标题";
this.Column2.Name = "Column2";
this.Column2.ReadOnly = true;
//
// Column3
//
this.Column3.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
this.Column3.FillWeight = 111.5619F;
this.Column3.HeaderText = "价格";
this.Column3.Name = "Column3";
this.Column3.ReadOnly = true;
this.Column3.Width = 120;
//
// Column4
//
this.Column4.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
this.Column4.FillWeight = 111.5619F;
this.Column4.HeaderText = "销量";
this.Column4.Name = "Column4";
this.Column4.ReadOnly = true;
this.Column4.Width = 120;
//
// ucSplitPage1
//
this.ucSplitPage1.CurrentPage = 1;
this.ucSplitPage1.Dock = System.Windows.Forms.DockStyle.Right;
this.ucSplitPage1.IsShowPageSize = true;
this.ucSplitPage1.IsShowTotalCount = true;
this.ucSplitPage1.Location = new System.Drawing.Point(1181, 0);
this.ucSplitPage1.Margin = new System.Windows.Forms.Padding(0);
this.ucSplitPage1.MaxPageSizeValue = 2000;
this.ucSplitPage1.Name = "ucSplitPage1";
this.ucSplitPage1.PageSize = 50;
this.ucSplitPage1.Size = new System.Drawing.Size(462, 25);
this.ucSplitPage1.TabIndex = 4;
this.ucSplitPage1.TotalCount = ((long)(0));
this.ucSplitPage1.TotalPage = 1;
//
// statusBar
//
this.statusBar.BackColor = System.Drawing.Color.White;
this.statusBar.Dock = System.Windows.Forms.DockStyle.Fill;
this.statusBar.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.statusBar.Location = new System.Drawing.Point(0, 0);
this.statusBar.Margin = new System.Windows.Forms.Padding(0);
this.statusBar.Name = "statusBar";
this.statusBar.Size = new System.Drawing.Size(1643, 25);
this.statusBar.TabIndex = 1;
this.statusBar.Visible = false;
//
// CloudGoodsFavoriteForm
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(1643, 530);
this.Controls.Add(this.splitContainer1);
this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.KeyPreview = true;
this.Name = "CloudGoodsFavoriteForm";
this.Text = "AdminCardCodeForm";
this.Load += new System.EventHandler(this.AdminCardCodeForm_Load);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel1.PerformLayout();
this.splitContainer1.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.panel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.num_maxprice)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.num_minprice)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.num_maxsold)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.num_minsold)).EndInit();
this.splitContainer2.Panel1.ResumeLayout(false);
this.splitContainer2.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
this.splitContainer2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pbLoading)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.dgvData)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.SplitContainer splitContainer1;
private DevComponents.DotNetBar.PanelEx pnlEmpty;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.SplitContainer splitContainer2;
private System.Windows.Forms.PictureBox pbLoading;
private UserComponent.DataGridViewEx dgvData;
private UserControls.UcSplitPage ucSplitPage1;
private UserControls.StatusBarUserControl statusBar;
private DevComponents.DotNetBar.PanelEx btnSearch;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.TextBox txt_title;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.NumericUpDown num_maxsold;
private System.Windows.Forms.NumericUpDown num_minsold;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.NumericUpDown num_maxprice;
private System.Windows.Forms.NumericUpDown num_minprice;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.ComboBox cmbCatSelect2;
private System.Windows.Forms.ComboBox cmbCatSelect1;
private System.Windows.Forms.ComboBox cmbCatSelect4;
private System.Windows.Forms.ComboBox cmbCatSelect3;
private System.Windows.Forms.Label label5r;
private System.Windows.Forms.ComboBox cb_Platform;
private System.Windows.Forms.DataGridViewCheckBoxColumn colSelect;
private System.Windows.Forms.DataGridViewTextBoxColumn c_Platform;
private System.Windows.Forms.DataGridViewImageColumn Column1;
private System.Windows.Forms.DataGridViewTextBoxColumn c_goodsid;
private System.Windows.Forms.DataGridViewTextBoxColumn Column2;
private System.Windows.Forms.DataGridViewTextBoxColumn Column3;
private System.Windows.Forms.DataGridViewTextBoxColumn Column4;
private System.Windows.Forms.Panel panel1;
private DevComponents.DotNetBar.PanelEx btn_removefavorite;
private DevComponents.DotNetBar.PanelEx bt_importUploadList;
}
}
@@ -0,0 +1,483 @@
using AllBase;
using AllBase.Helper;
using AllBase.Model.Result;
using AllBase.Model.Result.PDDResult;
using AllBase.Model.Result.WXResult;
using NaiBa.Util.Extension;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using TemuKJD.BaseForms;
using TemuKJD.Extension;
using TemuKJD.ToolForms;
using TemuKJD.UserControls;
using TemuKJD.WXForms.ProductForms;
using Work;
using Work.GoodDetail;
using Work.Services;
namespace TemuKJD.PDDForms.ProductSelectForms
{
public partial class CloudGoodsFavoriteForm : BaseForm
{
private GoodsSearchRequest search = new GoodsSearchRequest();
private List<ComboBox> catBoxList = new List<ComboBox>();
private BindingList<CloudGoods> dataList = new BindingList<CloudGoods>();
CheckBox chkSelectAll = null;
public CloudGoodsFavoriteForm()
{
InitializeComponent();
}
private void AdminCardCodeForm_Load(object sender, EventArgs e)
{
pbLoading.Visible = false;
ucSplitPage1.PageChange += UcSplitPage1_PageChange;
InitCategory();
InitBindingDataGridView();
num_minsold.Value = 0;
num_maxsold.Value = 9999999;
num_minprice.Value = 0;
num_maxprice.Value = 999;
cb_Platform.SelectedIndex = 0;
ucSplitPage1.TotalCount = 0;
if (EnvironmentHelper.IsDevelopment)
{
txt_title.Text = "连衣裙";
}
}
private void InitBindingDataGridView()
{
this.dgvData.AutoGenerateColumns = false;
this.Column1.Width = 70;
// Column1 是图片列,DataGridViewImageColumn 无法把 ThumbUrl 的 URL 字符串直接渲染成图片,
// 因此不绑定 DataPropertyName,改为数据加载后由 ShowDgvImg() 异步下载图片填入该列。
this.colSelect.DataPropertyName = nameof(CloudGoods.IsSelected);
this.colSelect.ReadOnly = false;
this.Column2.DataPropertyName = nameof(CloudGoods.Title);
this.Column3.DataPropertyName = nameof(CloudGoods.Price);
this.Column4.DataPropertyName = nameof(CloudGoods.SoldQuantity);
this.c_goodsid.DataPropertyName = nameof(CloudGoods.GoodsId);
this.c_Platform.DataPropertyName = nameof(CloudGoods.Platform);
// 2. 设置列样式
// 时间列格式化
//this.Column6.DefaultCellStyle.Format = "yyyy-MM-dd HH:mm:ss";
//this.Column8.DefaultCellStyle.Format = "yyyy-MM-dd HH:mm:ss";
this.dgvData.DataSource = dataList;
// 滚动到可视区时按需加载缩略图
this.dgvData.Scroll += (s, e) => ShowDgvImg();
this.dgvData.CellContentClick += DgvData_CellContentClick;
dgvData.CellFormatting += DgvData_CellFormatting;
chkSelectAll = dgvData.Columns["colSelect"].AddHeaderCheckBox(HorizontalAlignment.Center, 0, 0, null, null, false);
dgvData.Columns["colSelect"].HeaderText = "";
//chkSelectAll.Width = chkSelectAll.Height = 13;
chkSelectAll.CheckedChanged += chkSelectAll_CheckedChanged;
//chkSelectAll.Checked = true;
}
private void DgvData_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == this.c_Platform.Index && e.Value != null && e.Value != DBNull.Value)
{
if (int.TryParse(e.Value.ToString(), out int v))
{
e.Value = v == 1 ? ("多多") : v == 2 ? ("微信") : ("未知");
e.FormattingApplied = true;
}
}
}
private void chkSelectAll_CheckedChanged(object sender, EventArgs e)
{
foreach (var item in dataList)
{
item.IsSelected = (sender as CheckBox).Checked;
}
//this.dgvData.Refresh();
}
private void DgvData_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (dgvData.Columns[e.ColumnIndex] == colSelect)
{
var data = dgvData.Rows[e.RowIndex].DataBoundItem as CloudGoods;
data.IsSelected = !data.IsSelected;
}
if (dgvData.Columns[e.ColumnIndex] == Column1)
{
var data = dgvData.Rows[e.RowIndex].DataBoundItem as CloudGoods;
if (dgvData.Rows[e.RowIndex].Cells[e.ColumnIndex].Value is Image img)
{
ShowImgForm imgFrom = new ShowImgForm(img, data.ThumbUrl);
imgFrom.ShowDialog();
}
}
}
/// <summary>
/// 异步下载 CloudGoods.ThumbUrl 图片并填充到 Column1 图片列(只加载可视区行,避免一次下载整页)
/// </summary>
private void ShowDgvImg()
{
// 先在 UI 线程上快照“行 + 图片地址”,避免在后台线程遍历绑定的 DataGridView
List<KeyValuePair<DataGridViewRow, string>> waitList = new List<KeyValuePair<DataGridViewRow, string>>();
foreach (DataGridViewRow row in this.dgvData.Rows)
{
try
{
if (row.Index < 0)
continue;
// 不在可视区:先放占位图,滚动到可视区时再真正加载
if (row.Index > 0 && row.Cells["Column1"].Displayed == false)
{
if (row.Cells["Column1"].Value != DataGridViewExtension.defaultBitmap)
row.Cells["Column1"].Value = DataGridViewExtension.defaultBitmap;
continue;
}
// 已加载过就不再重复下载
if (row.Cells["Column1"].Value != null && row.Cells["Column1"].Value != DataGridViewExtension.defaultBitmap)
continue;
string imgUrl = (row.DataBoundItem as CloudGoods)?.ThumbUrl;
if (!string.IsNullOrWhiteSpace(imgUrl))
waitList.Add(new KeyValuePair<DataGridViewRow, string>(row, imgUrl));
else
row.Cells["Column1"].Value = TemuKJD.Properties.Resources.errpic;
}
catch
{
}
}
if (waitList.Count == 0)
return;
Task.Run(() =>
{
foreach (var item in waitList)
{
try
{
DataGridViewRow row = item.Key;
string getImgError = "";
Image image = GetHtml.GetUrlImg(item.Value, out getImgError);
if (image == null)
image = TemuKJD.Properties.Resources.errpic;
Invoke(new Action(() =>
{
try
{
if (row.Index >= 0)
row.Cells["Column1"].Value = image;
}
catch { }
}));
}
catch
{
}
}
});
}
private void InitCategory()
{
catBoxList.Add(cmbCatSelect1);
catBoxList.Add(cmbCatSelect2);
catBoxList.Add(cmbCatSelect3);
catBoxList.Add(cmbCatSelect4);
for (int i = 0; i < catBoxList.Count; i++)
{
catBoxList[i].DropDownStyle = ComboBoxStyle.DropDownList;
catBoxList[i].Tag = i;
catBoxList[i].SelectedIndexChanged += CmbCatSelect_SelectedIndexChanged;
catBoxList[i].DisplayMember = "cat_name";
catBoxList[i].ValueMember = "cat_id";
}
cmbCatSelect1.Items.Add(new PddCatInfo
{
cat_name = "全部",
cat_id = 0
});
foreach (PddCatInfo cat in GlobalConfig.PddCatList.Where(c => c.level == 1).ToList())
{
cmbCatSelect1.Items.Add(cat);
}
catBoxList[0].SelectedIndex = 0;
}
private void CmbCatSelect_SelectedIndexChanged(object sender, EventArgs e)
{
if (sender is ComboBox ccb)
{
ccb.SelectedIndexChanged -= CmbCatSelect_SelectedIndexChanged;
try
{
int currentLevel = (int)ccb.Tag;
// 先清空并禁用所有下级 ComboBox
for (int i = currentLevel + 1; i < catBoxList.Count; i++)
{
catBoxList[i].Items.Clear();
catBoxList[i].SelectedIndex = -1;
}
var parentCategory = ccb.SelectedItem as PddCatInfo;
// 启用并填充当前级别及上级(如果需要)
for (int i = currentLevel + 1; i < catBoxList.Count; i++)
{
// 清空所有下级
catBoxList[i].Items.Clear();
catBoxList[i].SelectedIndex = -1;
catBoxList[i].Text = "";
catBoxList[i].SelectedItem = null;
if (i == currentLevel + 1)
{
catBoxList[i].Enabled = true;
// 根据当前选中的值过滤下一级数据
if (parentCategory != null)
{
var childItems = GlobalConfig.PddCatList
.Where(c => c.level == i + 1 && c.parent_cat_id == parentCategory.cat_id)
.ToList();
foreach (var cat in childItems)
{
catBoxList[i].Items.Add(cat);
}
}
}
else
{
// 更下级的全部禁用并清空
catBoxList[i].Enabled = false;
}
}
if (currentLevel == 0)
{
catBoxList[1].Enabled = parentCategory.cat_id != 0;
}
}
finally
{
// 重新绑定事件
ccb.SelectedIndexChanged += CmbCatSelect_SelectedIndexChanged;
}
}
}
private void UcSplitPage1_PageChange(object obj)
{
btnSearch_Click(obj, null);
}
private async void btnSearch_Click(object sender, EventArgs e)
{
try
{
this.pbLoading.Visible = true;
btnSearch.Enabled = false;
UserFavoritesGoodsSearchRequest search = new UserFavoritesGoodsSearchRequest();
search.Platform = cb_Platform.SelectedIndex == 1 ? PlatformType.PDD : cb_Platform.SelectedIndex == 2 ? PlatformType.WX : PlatformType.None;
search.Title = txt_title.Text;
search.MinSoldQuantity = (int)num_minsold.Value;
search.MaxSoldQuantity = (int)num_maxsold.Value;
search.MinPrice = (long)num_minprice.Value * 100;
search.MaxPrice = (long)num_maxprice.Value * 100;
if (cmbCatSelect1.SelectedItem is PddCatInfo cat1)
{
search.CatId1 = (int)(cat1.cat_id);
search.CatId1 = search.CatId1 == 0 ? null : search.CatId1;
}
if (cmbCatSelect2.SelectedItem is PddCatInfo cat2)
search.CatId2 = (int)(cat2.cat_id);
if (cmbCatSelect3.SelectedItem is PddCatInfo cat3)
search.CatId3 = (int)(cat3.cat_id);
if (cmbCatSelect4.SelectedItem is PddCatInfo cat4)
search.CatId4 = (int)(cat4.cat_id);
search.PageIndex = ucSplitPage1.CurrentPage;
search.PageSize = ucSplitPage1.PageSize;
await GetGoods(search);
}
catch (Exception ex)
{
BaseMsgForm.ShowError($"查询失败:{ex.Message}");
}
finally
{
this.pbLoading.Visible = false;
btnSearch.Enabled = true;
}
}
private void pnlEmpty_Click(object sender, EventArgs e)
{
txt_title.Text = "";
num_minsold.Value = 0;
num_maxsold.Value = 99999;
num_minprice.Value = 0;
num_maxprice.Value = 999;
cmbCatSelect1.SelectedIndex = 0;
cb_Platform.SelectedIndex = 0;
ucSplitPage1.PageChange -= UcSplitPage1_PageChange;
ucSplitPage1.CurrentPage = 1;
ucSplitPage1.PageChange += UcSplitPage1_PageChange;
}
public async Task GetGoods(UserFavoritesGoodsSearchRequest request)
{
dataList.Clear();
PageData<CloudGoods> ret = await CloudGoodsService.SearchFavorites(request);
Invoke(new Action(() =>
{
ret.List.ForEach(a => dataList.Add(a));
ucSplitPage1.TotalPage = Math.Max(1, ret.TotalPages);
ucSplitPage1.TotalCount = ret.Total;
this.pbLoading.Visible = false;
// 异步加载商品缩略图(Column1 绑定 ThumbUrl)
ShowDgvImg();
}));
}
/// <summary>
/// 导入数据到待上传
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bt_importUploadList_Click(object sender, EventArgs e)
{
int succ = 0;
int err = 0;
foreach (var item in dataList)
{
try
{
if (item.IsSelected == false) continue;
string catName = "";
if (item.CatId4.HasValue)
{
catName = GlobalConfig.PddCatList.FirstOrDefault(a => a.cat_id == item.CatId4)?.cat_name ?? "";
}
else if (item.CatId3.HasValue)
{
catName = GlobalConfig.PddCatList.FirstOrDefault(a => a.cat_id == item.CatId3)?.cat_name ?? "";
}
else if (item.CatId2.HasValue)
{
catName = GlobalConfig.PddCatList.FirstOrDefault(a => a.cat_id == item.CatId2)?.cat_name ?? "";
}
WXDBProdUploadForm.lstTemuDBProductSelect.Add(new TemuDBProductSelect
{
//out_product_Id = item.GoodsId.ToString(),
spu_id = item.GoodsId.ToString(),
main_img = item.ThumbUrl,
product_name = item.Title,
cat_name = catName,
product_get_type_text = item.Platform == 1 ? ("多多") : item.Platform == 2 ? ("微信") : ("未知"),
db_type = "云端数据",
});
succ++;
}
catch
{
err++;
}
}
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_db_prod_upload_list", WXDBProdUploadForm.lstTemuDBProductSelect);
BaseMsgForm.ShowInfo($"导入完成!{succ} 成功 {err} 失败");
}
/// <summary>
/// 取消收藏
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void btn_removefavorite_Click(object sender, EventArgs e)
{
int succ = 0;
int err = 0;
try
{
this.pbLoading.Visible = true;
btn_removefavorite.Enabled = false;
var goodsIds = dataList.Where(a => a.IsSelected).Select(a => a.GoodsId).ToList();
if(goodsIds.Count==0)
{
BaseMsgForm.ShowInfo($"请勾选商品");
return;
}
var ret = await CloudGoodsService.RemoveFavorites(goodsIds);
succ = ret;
if (ret != goodsIds.Count)
{
err = goodsIds.Count - ret;
}
BaseMsgForm.ShowInfo($"取消收藏完成!{succ} 成功 {err} 失败");
}
catch (Exception ex)
{
BaseMsgForm.ShowError($"取消收藏失败:{ex.Message}");
}
finally
{
this.pbLoading.Visible = false;
btn_removefavorite.Enabled = true;
}
}
}
}
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="colSelect.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="c_Platform.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="c_goodsid.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column2.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column3.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column4.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>
File diff suppressed because it is too large. Load diff
@@ -50,9 +50,9 @@ namespace TemuKJD.PDDForms.ProductSelectForms
InitCategory();
InitBindingDataGridView();
num_minsold.Value = 0;
num_maxsold.Value = 999;
num_maxsold.Value = 9999999;
num_minprice.Value = 0;
num_maxprice.Value = 999;
@@ -424,7 +424,7 @@ namespace TemuKJD.PDDForms.ProductSelectForms
product_name = item.Title,
cat_name = catName,
product_get_type_text = item.Platform == 1 ? ("多多") : item.Platform == 2 ? ("微信") : ("未知"),
db_type = "云端数据",
db_type = "云端数据",
});
succ++;
}
@@ -436,6 +436,45 @@ namespace TemuKJD.PDDForms.ProductSelectForms
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_db_prod_upload_list", WXDBProdUploadForm.lstTemuDBProductSelect);
BaseMsgForm.ShowInfo($"导入完成!{succ} 成功 {err} 失败");
}
/// <summary>
/// 选中收藏
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void btn_favorite_Click(object sender, EventArgs e)
{
int succ = 0;
int err = 0;
try
{
this.pbLoading.Visible = true;
btn_favorite.Enabled = false;
var goodsIds = dataList.Where(a => a.IsSelected).Select(a => a.GoodsId).ToList();
if (goodsIds.Count == 0)
{
BaseMsgForm.ShowInfo($"请勾选商品");
return;
}
var ret = await CloudGoodsService.Favorite(goodsIds);
succ = ret;
if (ret != goodsIds.Count)
{
err = goodsIds.Count - ret;
}
BaseMsgForm.ShowInfo($"收藏完成!{succ} 成功 {err} 失败");
}
catch (Exception ex)
{
BaseMsgForm.ShowError($"收藏失败:{ex.Message}");
}
finally
{
this.pbLoading.Visible = false;
btn_favorite.Enabled = true;
}
}
}
+42 -38
View File
@@ -31,18 +31,19 @@
System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("选品上传");
System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("云端数据");
System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("我的商品库");
System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("商品预售/下架");
System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode("云仓退货地址");
System.Windows.Forms.TreeNode treeNode6 = new System.Windows.Forms.TreeNode("清理无流量");
System.Windows.Forms.TreeNode treeNode7 = new System.Windows.Forms.TreeNode("爆单神器");
System.Windows.Forms.TreeNode treeNode8 = new System.Windows.Forms.TreeNode("活动报名");
System.Windows.Forms.TreeNode treeNode9 = new System.Windows.Forms.TreeNode("达人广场");
System.Windows.Forms.TreeNode treeNode10 = new System.Windows.Forms.TreeNode("商品同步");
System.Windows.Forms.TreeNode treeNode11 = new System.Windows.Forms.TreeNode("订单管理");
System.Windows.Forms.TreeNode treeNode12 = new System.Windows.Forms.TreeNode("订单代发管理");
System.Windows.Forms.TreeNode treeNode13 = new System.Windows.Forms.TreeNode("多多商品采集");
System.Windows.Forms.TreeNode treeNode14 = new System.Windows.Forms.TreeNode("1688商品采集");
System.Windows.Forms.TreeNode treeNode15 = new System.Windows.Forms.TreeNode("商品管理", new System.Windows.Forms.TreeNode[] {
System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("云端收藏");
System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode("商品预售/下架");
System.Windows.Forms.TreeNode treeNode6 = new System.Windows.Forms.TreeNode("云仓退货地址");
System.Windows.Forms.TreeNode treeNode7 = new System.Windows.Forms.TreeNode("清理无流量");
System.Windows.Forms.TreeNode treeNode8 = new System.Windows.Forms.TreeNode("爆单神器");
System.Windows.Forms.TreeNode treeNode9 = new System.Windows.Forms.TreeNode("活动报名");
System.Windows.Forms.TreeNode treeNode10 = new System.Windows.Forms.TreeNode("达人广场");
System.Windows.Forms.TreeNode treeNode11 = new System.Windows.Forms.TreeNode("商品同步");
System.Windows.Forms.TreeNode treeNode12 = new System.Windows.Forms.TreeNode("订单管理");
System.Windows.Forms.TreeNode treeNode13 = new System.Windows.Forms.TreeNode("订单代发管理");
System.Windows.Forms.TreeNode treeNode14 = new System.Windows.Forms.TreeNode("多多商品采集");
System.Windows.Forms.TreeNode treeNode15 = new System.Windows.Forms.TreeNode("1688商品采集");
System.Windows.Forms.TreeNode treeNode16 = new System.Windows.Forms.TreeNode("商品管理", new System.Windows.Forms.TreeNode[] {
treeNode1,
treeNode2,
treeNode3,
@@ -56,7 +57,8 @@
treeNode11,
treeNode12,
treeNode13,
treeNode14});
treeNode14,
treeNode15});
this.panel1 = new System.Windows.Forms.Panel();
this.panel3 = new System.Windows.Forms.Panel();
this.panel2 = new System.Windows.Forms.Panel();
@@ -153,32 +155,34 @@
treeNode2.Text = "云端数据";
treeNode3.Name = "我的商品库";
treeNode3.Text = "我的商品库";
treeNode4.Name = "商品预售/下架";
treeNode4.Text = "商品预售/下架";
treeNode5.Name = "云仓退货地址";
treeNode5.Text = "云仓退货地址";
treeNode6.Name = "清理无流量";
treeNode6.Text = "清理无流量";
treeNode7.Name = "爆单神器";
treeNode7.Text = "爆单神器";
treeNode8.Name = "活动报名";
treeNode8.Text = "活动报名";
treeNode9.Name = "达人广场";
treeNode9.Text = "达人广场";
treeNode10.Name = "商品同步";
treeNode10.Text = "商品同步";
treeNode11.Name = "订单管理";
treeNode11.Text = "订单管理";
treeNode12.Name = "订单代发管理";
treeNode12.Text = "订单代发管理";
treeNode13.Name = "多多商品采集";
treeNode13.Text = "多多商品采集";
treeNode14.Name = "1688商品采集";
treeNode14.Text = "1688商品采集";
treeNode15.Name = "商品管理";
treeNode15.Text = "商品管理";
treeNode4.Name = "云端收藏";
treeNode4.Text = "云端收藏";
treeNode5.Name = "商品预售/下架";
treeNode5.Text = "商品预售/下架";
treeNode6.Name = "云仓退货地址";
treeNode6.Text = "云仓退货地址";
treeNode7.Name = "清理无流量";
treeNode7.Text = "清理无流量";
treeNode8.Name = "爆单神器";
treeNode8.Text = "爆单神器";
treeNode9.Name = "活动报名";
treeNode9.Text = "活动报名";
treeNode10.Name = "达人广场";
treeNode10.Text = "达人广场";
treeNode11.Name = "商品同步";
treeNode11.Text = "商品同步";
treeNode12.Name = "订单管理";
treeNode12.Text = "订单管理";
treeNode13.Name = "订单代发管理";
treeNode13.Text = "订单代发管理";
treeNode14.Name = "多多商品采集";
treeNode14.Text = "多多商品采集";
treeNode15.Name = "1688商品采集";
treeNode15.Text = "1688商品采集";
treeNode16.Name = "商品管理";
treeNode16.Text = "商品管理";
this.tv.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
treeNode15});
treeNode16});
this.tv.OverForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(235)))), ((int)(((byte)(235)))));
this.tv.Size = new System.Drawing.Size(140, 521);
this.tv.TabIndex = 1;
@@ -34,6 +34,7 @@ namespace TemuKJD.WXForms.ProductForms
public Lazy<Get1688ProductForm> get1688ProdForm = new Lazy<Get1688ProductForm>();
public Lazy<WXProdNoCheckEditAddressForm> prodNoCheckEditForm = new Lazy<WXProdNoCheckEditAddressForm>();
public Lazy<CloudGoodsForm> cloudgoodsForm = new Lazy<CloudGoodsForm>();
public Lazy<CloudGoodsFavoriteForm> cloudgoodsFavoriteForm = new Lazy<CloudGoodsFavoriteForm>();
public WXProductForm()
{
InitializeComponent();
@@ -104,6 +105,9 @@ namespace TemuKJD.WXForms.ProductForms
case "我的商品库":
SetForm(userCollectAuthProdListForm.Value);
break;
case "云端收藏":
SetForm(cloudgoodsFavoriteForm.Value);
break;
case "商品预售/下架":
SetForm(wxProdPreSaleForm.Value);
break;
+577 -270
View File
@@ -1,8 +1,10 @@
using System;
using COSXML.Network;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.IO.Compression;
using System.Linq;
@@ -12,307 +14,612 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static Update.ChangelogTheme;
namespace Update
{
public partial class MainForm : Form
{
public string Title { get { return Text; } set { Text = value; } }
private Point mouseOffset; // 记录鼠标指针的坐标
private bool isMouseDown; // 记录鼠标左键是否按下
public partial class MainForm : Form
{
public string Title { get { return Text; } set { Text = value; } }
private Point mouseOffset; // 记录鼠标指针的坐标
private bool isMouseDown; // 记录鼠标左键是否按下
public MainForm()
{
InitializeComponent();
public MainForm()
{
InitializeComponent();
this.TopMost = true;
}
this.TopMost = true;
lb_title.Text = "更新日志";
private void MessageForm_Paint(object sender, PaintEventArgs e)
{
SetFormRoundRectRgn(this, 7);
SetFormRoundRectRgn(panel2, 7);
SetFormRoundRectRgn(this.btnOk, 7);
SetFormRoundRectRgn(this.btnCancel, 7);
}
var changelogItems = GetChangeInfos();
if (changelogItems != null)
{
private void btnOk_Click(object sender, EventArgs e)
{
if (lblMessage.Text == "升级完成,点击确定重启程序")
{
string extPath = System.Environment.CurrentDirectory + "\\" + Program.softName.Replace(".exe", "") + ".exe";
System.Diagnostics.Process.Start(extPath);
Application.Exit();
return;
}
string fromVersion = (Program.oldVersion / 100m).ToString();
string toVersion = (Program.newVersion / 100m).ToString();
ShowChangelog(fromVersion, toVersion, changelogItems);
}
btnOk.Enabled = false;
//// 演示数据:v1.0.0 升级到 v1.3.0,展示 1.1.0 ~ 1.3.0(新的在上)
//ShowChangelog("1.0.0", "1.3.0", new[]
//{
// new ChangelogItem { Version = "1.3.0", PublishedAt = "2026-10-10", Notes = "新增深色模式,支持跟随系统\n新增快捷键面板(Ctrl + /)\n启动速度提升 40%" },
// new ChangelogItem { Version = "1.2.0", PublishedAt = "2026-09-05", Notes = "支持导出数据为 Excel 格式\n优化列表滚动性能\n修复偶发的保存失败问题" },
// new ChangelogItem { Version = "1.1.0", PublishedAt = "2026-08-01", Notes = "新增自动更新功能\n修复高分屏下界面模糊的问题" },
//});
}
private List<ChangelogItem> GetChangeInfos()
{
try
{
string paidanUrl = $"https://update-wx-order.e57.cn";
string shanghuoUrl = $"https://update.e57.cn";
using (WebClient c = new WebClient())
{
c.Encoding = Encoding.UTF8;
string url = $"/api/releases/since?version={(Program.oldVersion / 100m)}&channel=stable";
if (Program.softName == "29WxFindOrder")
{
url = paidanUrl + url;
}
else if (Program.softName == "29供应链.exe")
url = shanghuoUrl + url;
string json = c.DownloadString(url);
var root = MiniJson.Json.Deserialize(json) as Dictionary<string, object>;
if (root["ok"].ToString() == "True")
{
var data = (Dictionary<string, object>)root["data"];
var versionsRaw = (List<object>)data["versions"];
CloseMainProgram();
var list = new List<ChangelogItem>();
foreach (Dictionary<string, object> item in versionsRaw)
{
var ci = new ChangelogItem
{
Version = item["version"]?.ToString(),
Notes = item["notes"]?.ToString(),
};
if (!System.IO.Directory.Exists("upBak"))
System.IO.Directory.CreateDirectory("upBak");
var upBakPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "upBak";
if (!System.IO.Directory.Exists("upTemp"))
System.IO.Directory.CreateDirectory("upTemp");
var upTempPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "upTemp";
if (DateTime.TryParse(item["publishedAt"]?.ToString(), out DateTime v))
{
ci.ChangeTime = v;
}
list.Add(ci);
}
list.Sort((a, b) => b.ChangeTime.CompareTo(a.ChangeTime));
return list;
}
}
return null;
}
catch (Exception ex)
{
return new List<ChangelogItem>
{
new ChangelogItem
{
Notes="更新日志获取错误\n"+ex.Message
}
};
}
}
// 清空文件夹准备下载
foreach (string filePath in Directory.GetFiles(upTempPath))
{
File.Delete(filePath); // 删除文件
}
foreach (string dirPath in Directory.GetDirectories(upTempPath))
{
Directory.Delete(dirPath, true); // 删除子文件夹及其内容
}
/// <summary>
/// 渲染更新日志:头部展示版本区间,中间按版本分组列出更新条目
/// </summary>
private void ShowChangelog(string fromVersion, string toVersion, IEnumerable<ChangelogItem> entries)
{
int length = entries.Count();
lblHeroTitle.Text = "v" + fromVersion + " → v" + toVersion;
lblHeroMeta.Text = length > 1 ? "共包含 " + length + " 个版本的更新内容" : "本次更新内容";
this.lblMessage.Text = "升级中请稍候...";
progressBar1.Visible = true;
progressBar1.Maximum = 100;//fileNameArr.Count();
progressBar1.Value = 0;
Task.Run(async() =>
{
string tempFile = upTempPath + "\\" + Program.updateUrl.Substring(Program.updateUrl.LastIndexOf("/") + 1);
//bool result = Program.DownloadFile(Program.updateUrl, tempFile);
panelChangelog.SuspendLayout();
panelChangelog.Controls.Clear();
//while (true)
//{
// Invoke(new Action(() =>
// {
// progressBar1.Value = Program.progress;
// }));
// if (Program.progress == 100)
// break;
//}
var blocks = entries.Select((entry, i) => new ChangelogBlock(entry, i == 0, panelChangelog.Width)).ToList();
int contentHeight = blocks.Sum(b => b.Height);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
using (var downloadClient = new WebClient())
{
downloadClient.Proxy = null;
// 内容超出可视区时预留垂直滚动条宽度,避免出现横向滚动条
int width = panelChangelog.ClientSize.Width;
if (contentHeight > panelChangelog.ClientSize.Height)
width -= SystemInformation.VerticalScrollBarWidth;
downloadClient.DownloadProgressChanged += (s, args) =>
{
Invoke(new Action(() => { progressBar1.Value = args.ProgressPercentage; }));
};
int y = 6;
foreach (var block in blocks)
{
block.Width = width;
block.Location = new Point(0, y);
y += block.Height;
panelChangelog.Controls.Add(block);
}
panelChangelog.ResumeLayout(true);
}
await downloadClient.DownloadFileTaskAsync(new Uri(Program.updateUrl), tempFile);
}
private void heroPanel_Paint(object sender, PaintEventArgs e)
{
var panel = (Panel)sender;
if (panel.Width <= 0 || panel.Height <= 0)
return;
if (1 == 1)
//if (result)
{
ZipFile.ExtractToDirectory(tempFile, upTempPath);
File.Delete(tempFile);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
using (var brush = new LinearGradientBrush(panel.ClientRectangle, AccentBg, Color.White, 40F))
e.Graphics.FillRectangle(brush, panel.ClientRectangle);
string mainPath = System.Environment.CurrentDirectory;
// 备份旧文件
foreach (string filePath in Directory.GetFiles(upTempPath))
{
try
{
string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
File.Copy(mainPath + "\\" + fileName, upBakPath + "\\" + fileName, true);
Thread.Sleep(10);
}
catch
{
}
}
foreach (string dirPath in Directory.GetDirectories(upTempPath))
{
try
{
string fileName = dirPath.Substring(dirPath.LastIndexOf("\\") + 1);
CopyDirectory(mainPath + "\\" + fileName, upBakPath + "\\" + fileName);
Thread.Sleep(10);
}
catch
{
}
}
using (var pen = new Pen(LineColor))
{
e.Graphics.DrawLine(pen, 0, 0, panel.Width, 0);
e.Graphics.DrawLine(pen, 0, panel.Height - 1, panel.Width, panel.Height - 1);
}
}
string error = "";
// 替换旧文件
foreach (string filePath in Directory.GetFiles(upTempPath))
{
if (!string.IsNullOrEmpty(error))
{
error = "发生错误:\r\n" + error + "\r\n请关闭升级窗口重试!";
break;
}
try
{
string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
File.Copy(upTempPath + "\\" + fileName, mainPath + "\\" + fileName, true);
Thread.Sleep(10);
}
catch (Exception ex)
{
error = "发生错误:\r\n" + ex.Message + "\r\n请关闭升级窗口重试!";
Invoke(new Action(() =>
{
lblMessage.Text = error;
}));
}
}
foreach (string dirPath in Directory.GetDirectories(upTempPath))
{
if (!string.IsNullOrEmpty(error))
break;
try
{
string fileName = dirPath.Substring(dirPath.LastIndexOf("\\") + 1);
CopyDirectory(upTempPath + "\\" + fileName, mainPath + "\\" + fileName);
Thread.Sleep(10);
}
catch (Exception ex)
{
error = "发生错误:\r\n" + ex.Message + "\r\n请关闭升级窗口重试!";
Invoke(new Action(() =>
{
lblMessage.Text = error;
}));
}
}
Thread.Sleep(50);
Invoke(new Action(() =>
{
if (string.IsNullOrEmpty(error))
{
progressBar1.Value = 100;
lblMessage.Text = "升级完成,点击确定重启程序";
btnOk.Enabled = true;
}
}));
}
else
{
Invoke(new Action(() =>
{
progressBar1.Value = 100;
this.lblMessage.Text = "升级失败,未获取到升级文件";
btnOk.Enabled = true;
}));
}
});
}
private void btnOk_Click(object sender, EventArgs e)
{
if (lblMessage.Text == "升级完成,点击确定重启程序")
{
string extPath = System.Environment.CurrentDirectory + "\\" + Program.softName.Replace(".exe", "") + ".exe";
System.Diagnostics.Process.Start(extPath);
Application.Exit();
return;
}
/// <summary>
/// 拷贝文档目录
/// </summary>
/// <param name="srcPath"></param>
/// <param name="destPath"></param>
public static void CopyDirectory(string srcPath, string destPath)
{
try
{
DirectoryInfo dir = new DirectoryInfo(srcPath);
FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //获取目录下(不包含子目录)的文件和子目录
foreach (FileSystemInfo i in fileinfo)
{
if (i is DirectoryInfo) //判断是否文件夹
{
if (!Directory.Exists(destPath + "\\" + i.Name))
{
Directory.CreateDirectory(destPath + "\\" + i.Name); //目标目录下不存在此文件夹即创建子文件夹
}
CopyDirectory(i.FullName, destPath + "\\" + i.Name); //递归调用复制子文件夹
}
else
{
File.Copy(i.FullName, destPath + "\\" + i.Name, true); //不是文件夹即复制文件,true表示可以覆盖同名文件
}
}
}
catch (Exception e)
{
throw;
}
}
btnOk.Enabled = false;
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
CloseMainProgram();
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseOffset = new Point(-e.X, -e.Y);
isMouseDown = true;
}
}
if (!System.IO.Directory.Exists("upBak"))
System.IO.Directory.CreateDirectory("upBak");
var upBakPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "upBak";
if (!System.IO.Directory.Exists("upTemp"))
System.IO.Directory.CreateDirectory("upTemp");
var upTempPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "upTemp";
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
isMouseDown = false;
}
// 清空文件夹准备下载
foreach (string filePath in Directory.GetFiles(upTempPath))
{
File.Delete(filePath); // 删除文件
}
foreach (string dirPath in Directory.GetDirectories(upTempPath))
{
Directory.Delete(dirPath, true); // 删除子文件夹及其内容
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (isMouseDown)
{
// 获取鼠标的位置
Point mousePos = MousePosition;
mousePos.Offset(mouseOffset.X, mouseOffset.Y);
Location = mousePos;
}
}
this.lblMessage.Text = "升级中请稍候...";
progressBar1.Visible = true;
progressBar1.Maximum = 100;//fileNameArr.Count();
progressBar1.Value = 0;
Task.Run(async () =>
{
string tempFile = upTempPath + "\\" + Program.updateUrl.Substring(Program.updateUrl.LastIndexOf("/") + 1);
//bool result = Program.DownloadFile(Program.updateUrl, tempFile);
public static void SetFormRoundRectRgn(Control c, int rgnRadius)
{
int hRgn = 0;
hRgn = Win32.CreateRoundRectRgn(0, 0, c.Width + 1, c.Height + 1, rgnRadius, rgnRadius);
Win32.SetWindowRgn(c.Handle, hRgn, true);
Win32.DeleteObject(hRgn);
}
//while (true)
//{
// Invoke(new Action(() =>
// {
// progressBar1.Value = Program.progress;
// }));
// if (Program.progress == 100)
// break;
//}
private void btnClose_Click(object sender, EventArgs e)
{
Application.Exit();
}
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
using (var downloadClient = new WebClient())
{
downloadClient.Proxy = null;
private void CloseMainProgram()
{
string in_sAppName = Program.softName; //(一个word文档程序)
in_sAppName = in_sAppName.Replace(".exe", "");
downloadClient.DownloadProgressChanged += (s, args) =>
{
Invoke(new Action(() => { progressBar1.Value = args.ProgressPercentage; }));
try
{
System.Diagnostics.Process[] psiNewcas = System.Diagnostics.Process.GetProcessesByName(in_sAppName);
//System.Diagnostics.Process.GetProcessesByName("");
};
//var pro = System.Diagnostics.Process.GetProcesses();
//foreach(var p in pro)
//{
// Console.WriteLine(p.ProcessName);
//}
await downloadClient.DownloadFileTaskAsync(new Uri(Program.updateUrl), tempFile);
}
foreach (System.Diagnostics.Process p in psiNewcas)
{
p.Kill();
//p.WaitForExit();
//p.Close();
//Console.WriteLine(in_sAppName + "已经停止了");
}
}
catch
{
Console.WriteLine(in_sAppName + "停止失败");
}
}
}
if (1 == 1)
//if (result)
{
ZipFile.ExtractToDirectory(tempFile, upTempPath);
File.Delete(tempFile);
public enum FormLevel
{
SMALL,
MEDIUM,
LARGE = 500
}
string mainPath = System.Environment.CurrentDirectory;
// 备份旧文件
foreach (string filePath in Directory.GetFiles(upTempPath))
{
try
{
string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
File.Copy(mainPath + "\\" + fileName, upBakPath + "\\" + fileName, true);
Thread.Sleep(10);
}
catch
{
}
}
foreach (string dirPath in Directory.GetDirectories(upTempPath))
{
try
{
string fileName = dirPath.Substring(dirPath.LastIndexOf("\\") + 1);
CopyDirectory(mainPath + "\\" + fileName, upBakPath + "\\" + fileName);
Thread.Sleep(10);
}
catch
{
}
}
string error = "";
// 替换旧文件
foreach (string filePath in Directory.GetFiles(upTempPath))
{
if (!string.IsNullOrEmpty(error))
{
error = "发生错误:\r\n" + error + "\r\n请关闭升级窗口重试!";
break;
}
try
{
string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
File.Copy(upTempPath + "\\" + fileName, mainPath + "\\" + fileName, true);
Thread.Sleep(10);
}
catch (Exception ex)
{
error = "发生错误:\r\n" + ex.Message + "\r\n请关闭升级窗口重试!";
Invoke(new Action(() =>
{
lblMessage.Text = error;
}));
}
}
foreach (string dirPath in Directory.GetDirectories(upTempPath))
{
if (!string.IsNullOrEmpty(error))
break;
try
{
string fileName = dirPath.Substring(dirPath.LastIndexOf("\\") + 1);
CopyDirectory(upTempPath + "\\" + fileName, mainPath + "\\" + fileName);
Thread.Sleep(10);
}
catch (Exception ex)
{
error = "发生错误:\r\n" + ex.Message + "\r\n请关闭升级窗口重试!";
Invoke(new Action(() =>
{
lblMessage.Text = error;
}));
}
}
Thread.Sleep(50);
Invoke(new Action(() =>
{
if (string.IsNullOrEmpty(error))
{
progressBar1.Value = 100;
lblMessage.Text = "升级完成,点击确定重启程序";
btnOk.Enabled = true;
}
}));
}
else
{
Invoke(new Action(() =>
{
progressBar1.Value = 100;
this.lblMessage.Text = "升级失败,未获取到升级文件";
btnOk.Enabled = true;
}));
}
});
}
/// <summary>
/// 拷贝文档目录
/// </summary>
/// <param name="srcPath"></param>
/// <param name="destPath"></param>
public static void CopyDirectory(string srcPath, string destPath)
{
try
{
DirectoryInfo dir = new DirectoryInfo(srcPath);
FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //获取目录下(不包含子目录)的文件和子目录
foreach (FileSystemInfo i in fileinfo)
{
if (i is DirectoryInfo) //判断是否文件夹
{
if (!Directory.Exists(destPath + "\\" + i.Name))
{
Directory.CreateDirectory(destPath + "\\" + i.Name); //目标目录下不存在此文件夹即创建子文件夹
}
CopyDirectory(i.FullName, destPath + "\\" + i.Name); //递归调用复制子文件夹
}
else
{
File.Copy(i.FullName, destPath + "\\" + i.Name, true); //不是文件夹即复制文件,true表示可以覆盖同名文件
}
}
}
catch (Exception e)
{
throw;
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseOffset = new Point(-e.X, -e.Y);
isMouseDown = true;
}
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
isMouseDown = false;
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (isMouseDown)
{
// 获取鼠标的位置
Point mousePos = MousePosition;
mousePos.Offset(mouseOffset.X, mouseOffset.Y);
Location = mousePos;
}
}
private void btnClose_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void CloseMainProgram()
{
string in_sAppName = Program.softName; //(一个word文档程序)
in_sAppName = in_sAppName.Replace(".exe", "");
try
{
System.Diagnostics.Process[] psiNewcas = System.Diagnostics.Process.GetProcessesByName(in_sAppName);
//System.Diagnostics.Process.GetProcessesByName("");
//var pro = System.Diagnostics.Process.GetProcesses();
//foreach(var p in pro)
//{
// Console.WriteLine(p.ProcessName);
//}
foreach (System.Diagnostics.Process p in psiNewcas)
{
p.Kill();
//p.WaitForExit();
//p.Close();
//Console.WriteLine(in_sAppName + "已经停止了");
}
}
catch
{
Console.WriteLine(in_sAppName + "停止失败");
}
}
private void panel2_Paint(object sender, PaintEventArgs e)
{
}
}
public class Changelog
{
public bool Ok { get; set; }
public ChangelogData Data { get; set; }
}
public class ChangelogData
{
public List<ChangelogItem> versions { get; set; }
}
/// <summary>
/// 单个版本的更新日志
/// </summary>
public class ChangelogItem
{
public string Version { get; set; }
public string PublishedAt => ChangeTime.ToString("yyyy-MM-dd");
public DateTime ChangeTime { get; set; }
public string Notes { get; set; }
public string[] Items
{
get
{
string[] temp = new string[0];
if (string.IsNullOrEmpty(Notes)) return temp;
return Notes.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
}
}
}
/// <summary>
/// 更新日志中的单个版本区块:版本标题行(色条 + 版本号 + 最新标记 + 日期)与条目列表
/// </summary>
public class ChangelogBlock : Panel
{
private const int LeftPad = 28;
private const int RightPad = 28;
private const int BarWidth = 3;
private const int BarHeight = 16;
private const int TextLeft = 55; // 条目文字左边,留出圆点位置
private const int ItemPadding = 5; // 条目上下内边距
private const int BottomGap = 20; // 区块底部留白
private const int HeaderHeight = 28;
private readonly bool isNewest;
private readonly Font versionFont = new Font("微软雅黑", 12F, FontStyle.Bold);
private readonly Font dateFont = new Font("微软雅黑", 9F);
private readonly Font badgeFont = new Font("微软雅黑", 8.5F);
private readonly Font itemFont = new Font("微软雅黑", 10.5F);
private readonly Size versionSize;
private readonly Size dateSize;
private readonly List<System.Windows.Forms.Label> lblItems = new List<System.Windows.Forms.Label>();
private readonly System.Windows.Forms.Label lblVersion = new System.Windows.Forms.Label();
private readonly System.Windows.Forms.Label lblDate = new System.Windows.Forms.Label();
private Rectangle badgeRect = Rectangle.Empty;
private Rectangle barRect = Rectangle.Empty;
private readonly List<Point> bulletPoints = new List<Point>();
private int laidOutWidth = -1;
public ChangelogBlock(ChangelogItem entry, bool isNewest, int width)
{
this.isNewest = isNewest;
BackColor = Color.White;
DoubleBuffered = true;
versionSize = TextRenderer.MeasureText("v" + entry.Version, versionFont);
dateSize = TextRenderer.MeasureText(entry.PublishedAt, dateFont);
lblVersion.Font = versionFont;
lblVersion.ForeColor = Accent;
lblVersion.BackColor = Color.White;
lblVersion.Text = "v" + entry.Version;
Controls.Add(lblVersion);
lblDate.Font = dateFont;
lblDate.ForeColor = SubColor;
lblDate.BackColor = Color.White;
lblDate.Text = entry.PublishedAt;
Controls.Add(lblDate);
foreach (string item in entry.Items)
{
var label = new System.Windows.Forms.Label
{
Font = itemFont,
ForeColor = TextColor,
BackColor = Color.White,
Padding = new Padding(0, ItemPadding, 0, ItemPadding),
Text = item
};
lblItems.Add(label);
Controls.Add(label);
}
Width = width;
}
protected override void OnResize(EventArgs eventargs)
{
base.OnResize(eventargs);
LayoutContent(Width);
}
private void LayoutContent(int width)
{
if (width <= 0 || width == laidOutWidth)
return;
laidOutWidth = width;
SuspendLayout();
barRect = new Rectangle(LeftPad, (HeaderHeight - BarHeight) / 2, BarWidth, BarHeight);
lblVersion.SetBounds(LeftPad + BarWidth + 8, (HeaderHeight - versionSize.Height) / 2, versionSize.Width, versionSize.Height);
badgeRect = Rectangle.Empty;
int headerRight = lblVersion.Right;
if (isNewest)
{
Size badgeSize = TextRenderer.MeasureText("最新", badgeFont, Size.Empty, TextFormatFlags.NoPadding);
badgeRect = new Rectangle(headerRight + 8, (HeaderHeight - 18) / 2, badgeSize.Width + 16, 18);
headerRight = badgeRect.Right;
}
lblDate.SetBounds(Math.Max(headerRight + 8, width - RightPad - dateSize.Width),
(HeaderHeight - dateSize.Height) / 2, dateSize.Width, dateSize.Height);
int lineHeight = TextRenderer.MeasureText("中", itemFont, Size.Empty, TextFormatFlags.NoPadding).Height;
int textWidth = Math.Max(60, width - TextLeft - RightPad);
bulletPoints.Clear();
int y = HeaderHeight;
foreach (var label in lblItems)
{
int measured = TextRenderer.MeasureText(label.Text, itemFont, new Size(textWidth, 0), TextFormatFlags.WordBreak).Height;
label.SetBounds(TextLeft, y, textWidth, measured + ItemPadding * 2);
bulletPoints.Add(new Point(TextLeft - 14, y + ItemPadding + lineHeight / 2));
y += label.Height;
}
Height = y + BottomGap;
ResumeLayout(false);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
using (var path = RoundedRect(barRect, BarWidth / 2f))
using (var brush = new SolidBrush(Accent))
g.FillPath(brush, path);
if (isNewest && badgeRect.Width > 0)
{
using (var path = RoundedRect(badgeRect, badgeRect.Height / 2f))
using (var brush = new SolidBrush(Accent))
g.FillPath(brush, path);
TextRenderer.DrawText(g, "最新", badgeFont, badgeRect, Color.White,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.NoPadding);
}
using (var dot = new SolidBrush(Accent))
foreach (Point p in bulletPoints)
g.FillEllipse(dot, p.X - 3, p.Y - 3, 6, 6);
}
private static GraphicsPath RoundedRect(Rectangle rect, float radius)
{
var path = new GraphicsPath();
float d = radius * 2;
path.AddArc(rect.X, rect.Y, d, d, 180, 90);
path.AddArc(rect.Right - d, rect.Y, d, d, 270, 90);
path.AddArc(rect.Right - d, rect.Bottom - d, d, d, 0, 90);
path.AddArc(rect.X, rect.Bottom - d, d, d, 90, 90);
path.CloseFigure();
return path;
}
}
public enum FormLevel
{
SMALL,
MEDIUM,
LARGE = 500
}
/// <summary>
/// 更新日志窗口的配色,与设计稿保持一致
/// </summary>
internal static class ChangelogTheme
{
public static readonly Color Accent = Color.FromArgb(152, 99, 143);
public static readonly Color AccentBg = Color.FromArgb(245, 237, 244);
public static readonly Color SubColor = Color.FromArgb(107, 114, 128);
public static readonly Color LineColor = Color.FromArgb(229, 231, 238);
public static readonly Color TextColor = Color.FromArgb(31, 36, 48);
}
}
+216 -128
View File
@@ -29,135 +29,217 @@ namespace Update
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.lblMessage = new System.Windows.Forms.Label();
this.btnOk = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.panel1 = new System.Windows.Forms.Panel();
this.btnClose = new System.Windows.Forms.Button();
this.panel2 = new System.Windows.Forms.Panel();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.panel1.SuspendLayout();
this.panel2.SuspendLayout();
this.SuspendLayout();
//
// lblMessage
//
this.lblMessage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.lblMessage = new System.Windows.Forms.Label();
this.btnOk = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.panel1 = new System.Windows.Forms.Panel();
this.lb_title = new System.Windows.Forms.Label();
this.btnClose = new System.Windows.Forms.Button();
this.panel2 = new System.Windows.Forms.Panel();
this.heroPanel = new System.Windows.Forms.Panel();
this.lblHeroTitle = new System.Windows.Forms.Label();
this.lblHeroMeta = new System.Windows.Forms.Label();
this.panelChangelog = new System.Windows.Forms.Panel();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.panel3 = new System.Windows.Forms.Panel();
this.panel1.SuspendLayout();
this.panel2.SuspendLayout();
this.heroPanel.SuspendLayout();
this.SuspendLayout();
//
// lblMessage
//
this.lblMessage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lblMessage.Location = new System.Drawing.Point(14, 33);
this.lblMessage.Name = "lblMessage";
this.lblMessage.Size = new System.Drawing.Size(327, 98);
this.lblMessage.TabIndex = 0;
this.lblMessage.Text = "发现新版本,即将为您升级!";
this.lblMessage.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// btnOk
//
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnOk.BackColor = System.Drawing.Color.Blue;
this.btnOk.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnOk.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.btnOk.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnOk.Font = new System.Drawing.Font("微软雅黑", 11F);
this.btnOk.ForeColor = System.Drawing.Color.White;
this.btnOk.Location = new System.Drawing.Point(232, 177);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(109, 30);
this.btnOk.TabIndex = 9;
this.btnOk.TabStop = false;
this.btnOk.Text = "确 定";
this.btnOk.UseVisualStyleBackColor = false;
this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
//
// btnCancel
//
this.btnCancel.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnCancel.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnCancel.Font = new System.Drawing.Font("微软雅黑", 11F);
this.btnCancel.ForeColor = System.Drawing.Color.Blue;
this.btnCancel.Location = new System.Drawing.Point(14, 177);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(109, 30);
this.btnCancel.TabIndex = 10;
this.btnCancel.TabStop = false;
this.btnCancel.Text = "取 消";
this.btnCancel.UseVisualStyleBackColor = false;
this.btnCancel.Visible = false;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.Blue;
this.panel1.Controls.Add(this.btnClose);
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
this.panel1.Location = new System.Drawing.Point(2, 2);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(355, 24);
this.panel1.TabIndex = 11;
this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseDown);
this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseMove);
this.panel1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseUp);
//
// btnClose
//
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnClose.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnClose.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnClose.Font = new System.Drawing.Font("微软雅黑", 11F);
this.btnClose.ForeColor = System.Drawing.Color.White;
this.btnClose.Location = new System.Drawing.Point(339, -5);
this.btnClose.Name = "btnClose";
this.btnClose.Size = new System.Drawing.Size(17, 28);
this.btnClose.TabIndex = 11;
this.btnClose.TabStop = false;
this.btnClose.Text = "x";
this.btnClose.UseVisualStyleBackColor = false;
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
//
// panel2
//
this.panel2.BackColor = System.Drawing.Color.White;
this.panel2.Controls.Add(this.progressBar1);
this.panel2.Controls.Add(this.lblMessage);
this.panel2.Controls.Add(this.btnOk);
this.panel2.Controls.Add(this.btnCancel);
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel2.Location = new System.Drawing.Point(2, 2);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(355, 221);
this.panel2.TabIndex = 12;
//
// progressBar1
//
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
this.lblMessage.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(107)))), ((int)(((byte)(114)))), ((int)(((byte)(128)))));
this.lblMessage.Location = new System.Drawing.Point(20, 416);
this.lblMessage.Name = "lblMessage";
this.lblMessage.Size = new System.Drawing.Size(607, 45);
this.lblMessage.TabIndex = 0;
this.lblMessage.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btnOk
//
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOk.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
this.btnOk.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnOk.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
this.btnOk.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnOk.Font = new System.Drawing.Font("微软雅黑", 11F);
this.btnOk.ForeColor = System.Drawing.Color.White;
this.btnOk.Location = new System.Drawing.Point(522, 521);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(109, 30);
this.btnOk.TabIndex = 9;
this.btnOk.TabStop = false;
this.btnOk.Text = "确 定";
this.btnOk.UseVisualStyleBackColor = false;
this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnCancel.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnCancel.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnCancel.Font = new System.Drawing.Font("微软雅黑", 11F);
this.btnCancel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
this.btnCancel.Location = new System.Drawing.Point(24, 521);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(109, 30);
this.btnCancel.TabIndex = 10;
this.btnCancel.TabStop = false;
this.btnCancel.Text = "取 消";
this.btnCancel.UseVisualStyleBackColor = false;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
this.panel1.Controls.Add(this.lb_title);
this.panel1.Controls.Add(this.btnClose);
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
this.panel1.Location = new System.Drawing.Point(2, 2);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(663, 24);
this.panel1.TabIndex = 11;
this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseDown);
this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseMove);
this.panel1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseUp);
//
// lb_title
//
this.lb_title.AutoSize = true;
this.lb_title.ForeColor = System.Drawing.Color.White;
this.lb_title.Location = new System.Drawing.Point(3, 1);
this.lb_title.Name = "lb_title";
this.lb_title.Size = new System.Drawing.Size(50, 20);
this.lb_title.TabIndex = 12;
this.lb_title.Text = "label1";
//
// btnClose
//
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnClose.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnClose.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnClose.Font = new System.Drawing.Font("微软雅黑", 13F);
this.btnClose.ForeColor = System.Drawing.Color.White;
this.btnClose.Location = new System.Drawing.Point(629, -6);
this.btnClose.Margin = new System.Windows.Forms.Padding(0);
this.btnClose.Name = "btnClose";
this.btnClose.Size = new System.Drawing.Size(35, 35);
this.btnClose.TabIndex = 11;
this.btnClose.TabStop = false;
this.btnClose.Text = "✕";
this.btnClose.UseVisualStyleBackColor = false;
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
//
// panel2
//
this.panel2.BackColor = System.Drawing.Color.White;
this.panel2.Controls.Add(this.panel3);
this.panel2.Controls.Add(this.heroPanel);
this.panel2.Controls.Add(this.panelChangelog);
this.panel2.Controls.Add(this.progressBar1);
this.panel2.Controls.Add(this.lblMessage);
this.panel2.Controls.Add(this.btnOk);
this.panel2.Controls.Add(this.btnCancel);
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel2.Location = new System.Drawing.Point(2, 2);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(663, 583);
this.panel2.TabIndex = 12;
this.panel2.Paint += new System.Windows.Forms.PaintEventHandler(this.panel2_Paint);
//
// heroPanel
//
this.heroPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.progressBar1.Location = new System.Drawing.Point(14, 139);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(327, 23);
this.progressBar1.TabIndex = 11;
this.progressBar1.Visible = false;
//
// MainForm
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.ClientSize = new System.Drawing.Size(359, 225);
this.Controls.Add(this.panel1);
this.Controls.Add(this.panel2);
this.Font = new System.Drawing.Font("微软雅黑", 10F);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "MainForm";
this.Padding = new System.Windows.Forms.Padding(2);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "MessageForm";
this.Paint += new System.Windows.Forms.PaintEventHandler(this.MessageForm_Paint);
this.panel1.ResumeLayout(false);
this.panel2.ResumeLayout(false);
this.ResumeLayout(false);
this.heroPanel.Controls.Add(this.lblHeroTitle);
this.heroPanel.Controls.Add(this.lblHeroMeta);
this.heroPanel.Location = new System.Drawing.Point(0, 24);
this.heroPanel.Name = "heroPanel";
this.heroPanel.Size = new System.Drawing.Size(663, 92);
this.heroPanel.TabIndex = 13;
this.heroPanel.Paint += new System.Windows.Forms.PaintEventHandler(this.heroPanel_Paint);
//
// lblHeroTitle
//
this.lblHeroTitle.AutoSize = true;
this.lblHeroTitle.BackColor = System.Drawing.Color.Transparent;
this.lblHeroTitle.Font = new System.Drawing.Font("微软雅黑", 16F, System.Drawing.FontStyle.Bold);
this.lblHeroTitle.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
this.lblHeroTitle.Location = new System.Drawing.Point(28, 18);
this.lblHeroTitle.Name = "lblHeroTitle";
this.lblHeroTitle.Size = new System.Drawing.Size(183, 30);
this.lblHeroTitle.TabIndex = 0;
this.lblHeroTitle.Text = "v1.0.0 → v1.3.0";
//
// lblHeroMeta
//
this.lblHeroMeta.AutoSize = true;
this.lblHeroMeta.BackColor = System.Drawing.Color.Transparent;
this.lblHeroMeta.Font = new System.Drawing.Font("微软雅黑", 9F);
this.lblHeroMeta.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(107)))), ((int)(((byte)(114)))), ((int)(((byte)(128)))));
this.lblHeroMeta.Location = new System.Drawing.Point(30, 58);
this.lblHeroMeta.Name = "lblHeroMeta";
this.lblHeroMeta.Size = new System.Drawing.Size(155, 17);
this.lblHeroMeta.TabIndex = 1;
this.lblHeroMeta.Text = "共包含 3 个版本的更新内容";
//
// panelChangelog
//
this.panelChangelog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panelChangelog.AutoScroll = true;
this.panelChangelog.BackColor = System.Drawing.Color.White;
this.panelChangelog.Location = new System.Drawing.Point(0, 116);
this.panelChangelog.Name = "panelChangelog";
this.panelChangelog.Size = new System.Drawing.Size(663, 291);
this.panelChangelog.TabIndex = 14;
//
// progressBar1
//
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.progressBar1.Location = new System.Drawing.Point(24, 468);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(607, 16);
this.progressBar1.TabIndex = 11;
this.progressBar1.Visible = false;
//
// panel3
//
this.panel3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(229)))), ((int)(((byte)(231)))), ((int)(((byte)(238)))));
this.panel3.Location = new System.Drawing.Point(0, 496);
this.panel3.Margin = new System.Windows.Forms.Padding(1);
this.panel3.Name = "panel3";
this.panel3.Size = new System.Drawing.Size(664, 1);
this.panel3.TabIndex = 15;
//
// MainForm
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
this.ClientSize = new System.Drawing.Size(667, 587);
this.Controls.Add(this.panel1);
this.Controls.Add(this.panel2);
this.Font = new System.Drawing.Font("微软雅黑", 10F);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "MainForm";
this.Padding = new System.Windows.Forms.Padding(2);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "MessageForm";
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.panel2.ResumeLayout(false);
this.heroPanel.ResumeLayout(false);
this.heroPanel.PerformLayout();
this.ResumeLayout(false);
}
@@ -170,5 +252,11 @@ namespace Update
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Button btnClose;
private System.Windows.Forms.ProgressBar progressBar1;
}
private System.Windows.Forms.Panel heroPanel;
private System.Windows.Forms.Label lblHeroTitle;
private System.Windows.Forms.Label lblHeroMeta;
private System.Windows.Forms.Panel panelChangelog;
private System.Windows.Forms.Label lb_title;
private System.Windows.Forms.Panel panel3;
}
}
+699
View File
@@ -0,0 +1,699 @@
/*
* Copyright (c) 2013 Calvin Rien
*
* Based on the JSON parser by Patrick van Bergen
* http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
*
* Simplified it so that it doesn't throw exceptions
* and can be used in Unity iPhone with maximum code stripping.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
namespace MiniJson
{
// Example usage:
//
// using UnityEngine;
// using System.Collections;
// using System.Collections.Generic;
// using MiniJSON;
//
// public class MiniJSONTest : MonoBehaviour {
// void Start () {
// var jsonString = "{ \"array\": [1.44,2,3], " +
// "\"object\": {\"key1\":\"value1\", \"key2\":256}, " +
// "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " +
// "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " +
// "\"int\": 65536, " +
// "\"float\": 3.1415926, " +
// "\"bool\": true, " +
// "\"null\": null }";
//
// var dict = Json.Deserialize(jsonString) as Dictionary<string,object>;
//
// Debug.Log("deserialized: " + dict.GetType());
// Debug.Log("dict['array'][0]: " + ((List<object>) dict["array"])[0]);
// Debug.Log("dict['string']: " + (string) dict["string"]);
// Debug.Log("dict['float']: " + (double) dict["float"]); // floats come out as doubles
// Debug.Log("dict['int']: " + (long) dict["int"]); // ints come out as longs
// Debug.Log("dict['unicode']: " + (string) dict["unicode"]);
//
// var str = Json.Serialize(dict);
//
// Debug.Log("serialized: " + str);
// }
// }
/// <summary>
/// This class encodes and decodes JSON strings.
/// Spec. details, see http://www.json.org/
///
/// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary.
/// All numbers are parsed to doubles.
/// </summary>
public static class Json
{
/// <summary>
/// Parses the string json into a value
/// </summary>
/// <param name="json">A JSON string.</param>
/// <returns>An List&lt;object&gt;, a Dictionary&lt;string, object&gt;, a double, an integer,a string, null, true, or false</returns>
public static object Deserialize(string json)
{
// save the string for debug information
if (json == null)
{
return null;
}
return Parser.Parse(json);
}
public static T Deserialize<T>(string json)
where T:class,new()
{
T model =new T();
Dictionary<string,object> dic=Deserialize(json) as Dictionary<string,object>;
if (dic != null)
{
var properties = model.GetType().GetProperties();
foreach (var pro in properties)
{
if (dic.ContainsKey(pro.Name))
{
object val;
if (dic[pro.Name]==null && pro.PropertyType.IsValueType)
{
val = null;
}
else
{
val = Convert.ChangeType(dic[pro.Name], pro.PropertyType);
}
pro.SetValue(model, val,null);
}
}
}
return model;
}
/// <summary>
/// Converts a Dictionary / List object or a simple type or a class type (string, int, etc.) into a JSON string
/// </summary>
/// <param name="obj">A Dictionary&lt;string, object&gt; / List&lt;object&gt;</param>
/// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>
//public static string Serialize(object obj)
//{
// return Serializer.Serialize(obj);
//}
public static string Serialize(object obj)
{
if (obj.GetType() == typeof(Dictionary<string, object>) || obj.GetType() == typeof(List<object>))
{
return Serializer.Serialize(obj);
}
else if (obj.GetType().IsClass)
{
var properties = obj.GetType().GetProperties();
Dictionary<string, object> dic = new Dictionary<string, object>();
foreach (var pro in properties)
{
dic.Add(pro.Name, pro.GetValue(obj, null));
}
return Serializer.Serialize(dic);
}
else
return null;
}
sealed class Parser : IDisposable
{
const string WORD_BREAK = "{}[],:\"";
public static bool IsWordBreak(char c)
{
return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1;
}
const string HEX_DIGIT = "0123456789ABCDEFabcdef";
public static bool IsHexDigit(char c)
{
return HEX_DIGIT.IndexOf(c) != -1;
}
enum TOKEN
{
NONE,
CURLY_OPEN,
CURLY_CLOSE,
SQUARED_OPEN,
SQUARED_CLOSE,
COLON,
COMMA,
STRING,
NUMBER,
TRUE,
FALSE,
NULL
};
StringReader json;
Parser(string jsonString)
{
json = new StringReader(jsonString);
}
public static object Parse(string jsonString)
{
using (var instance = new Parser(jsonString))
{
return instance.ParseValue();
}
}
public void Dispose()
{
json.Dispose();
json = null;
}
Dictionary<string, object> ParseObject()
{
Dictionary<string, object> table = new Dictionary<string, object>();
// ditch opening brace
json.Read();
// {
while (true)
{
switch (NextToken)
{
case TOKEN.NONE:
return null;
case TOKEN.COMMA:
continue;
case TOKEN.CURLY_CLOSE:
return table;
case TOKEN.STRING:
// name
string name = ParseString();
if (name == null)
{
return null;
}
// :
if (NextToken != TOKEN.COLON)
{
return null;
}
// ditch the colon
json.Read();
// value
TOKEN valueToken = NextToken;
object value = ParseByToken(valueToken);
if (value == null && valueToken != TOKEN.NULL)
return null;
table[name] = value;
break;
default:
return null;
}
}
}
List<object> ParseArray()
{
List<object> array = new List<object>();
// ditch opening bracket
json.Read();
// [
var parsing = true;
while (parsing)
{
TOKEN nextToken = NextToken;
switch (nextToken)
{
case TOKEN.NONE:
return null;
case TOKEN.COMMA:
continue;
case TOKEN.SQUARED_CLOSE:
parsing = false;
break;
default:
object value = ParseByToken(nextToken);
if (value == null && nextToken != TOKEN.NULL)
return null;
array.Add(value);
break;
}
}
return array;
}
object ParseValue()
{
TOKEN nextToken = NextToken;
return ParseByToken(nextToken);
}
object ParseByToken(TOKEN token)
{
switch (token)
{
case TOKEN.STRING:
return ParseString();
case TOKEN.NUMBER:
return ParseNumber();
case TOKEN.CURLY_OPEN:
return ParseObject();
case TOKEN.SQUARED_OPEN:
return ParseArray();
case TOKEN.TRUE:
return true;
case TOKEN.FALSE:
return false;
case TOKEN.NULL:
return null;
default:
return null;
}
}
string ParseString()
{
StringBuilder s = new StringBuilder();
char c;
// ditch opening quote
json.Read();
bool parsing = true;
while (parsing)
{
if (json.Peek() == -1)
{
parsing = false;
break;
}
c = NextChar;
switch (c)
{
case '"':
parsing = false;
break;
case '\\':
if (json.Peek() == -1)
{
parsing = false;
break;
}
c = NextChar;
switch (c)
{
case '"':
case '\\':
case '/':
s.Append(c);
break;
case 'b':
s.Append('\b');
break;
case 'f':
s.Append('\f');
break;
case 'n':
s.Append('\n');
break;
case 'r':
s.Append('\r');
break;
case 't':
s.Append('\t');
break;
case 'u':
var hex = new char[4];
for (int i = 0; i < 4; i++)
{
hex[i] = NextChar;
if (!IsHexDigit(hex[i]))
return null;
}
s.Append((char)Convert.ToInt32(new string(hex), 16));
break;
}
break;
default:
s.Append(c);
break;
}
}
return s.ToString();
}
object ParseNumber()
{
string number = NextWord;
if (number.IndexOf('.') == -1 && number.IndexOf('E') == -1 && number.IndexOf('e') == -1)
{
long parsedInt;
Int64.TryParse(number, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out parsedInt);
return parsedInt;
}
double parsedDouble;
Double.TryParse(number, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out parsedDouble);
return parsedDouble;
}
void EatWhitespace()
{
while (Char.IsWhiteSpace(PeekChar))
{
json.Read();
if (json.Peek() == -1)
{
break;
}
}
}
char PeekChar
{
get
{
return Convert.ToChar(json.Peek());
}
}
char NextChar
{
get
{
return Convert.ToChar(json.Read());
}
}
string NextWord
{
get
{
StringBuilder word = new StringBuilder();
while (!IsWordBreak(PeekChar))
{
word.Append(NextChar);
if (json.Peek() == -1)
{
break;
}
}
return word.ToString();
}
}
TOKEN NextToken
{
get
{
EatWhitespace();
if (json.Peek() == -1)
{
return TOKEN.NONE;
}
switch (PeekChar)
{
case '{':
return TOKEN.CURLY_OPEN;
case '}':
json.Read();
return TOKEN.CURLY_CLOSE;
case '[':
return TOKEN.SQUARED_OPEN;
case ']':
json.Read();
return TOKEN.SQUARED_CLOSE;
case ',':
json.Read();
return TOKEN.COMMA;
case '"':
return TOKEN.STRING;
case ':':
return TOKEN.COLON;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
return TOKEN.NUMBER;
}
switch (NextWord)
{
case "false":
return TOKEN.FALSE;
case "true":
return TOKEN.TRUE;
case "null":
return TOKEN.NULL;
}
return TOKEN.NONE;
}
}
}
sealed class Serializer
{
StringBuilder builder;
Serializer()
{
builder = new StringBuilder();
}
public static string Serialize(object obj)
{
var instance = new Serializer();
instance.SerializeValue(obj);
return instance.builder.ToString();
}
void SerializeValue(object value)
{
IList asList;
IDictionary asDict;
string asStr;
if (value == null)
{
builder.Append("null");
}
else if ((asStr = value as string) != null)
{
SerializeString(asStr);
}
else if (value is bool)
{
builder.Append((bool)value ? "true" : "false");
}
else if ((asList = value as IList) != null)
{
SerializeArray(asList);
}
else if ((asDict = value as IDictionary) != null)
{
SerializeObject(asDict);
}
else if (value is char)
{
SerializeString(new string((char)value, 1));
}
else
{
SerializeOther(value);
}
}
void SerializeObject(IDictionary obj)
{
bool first = true;
builder.Append('{');
foreach (object e in obj.Keys)
{
if (!first)
{
builder.Append(',');
}
SerializeString(e.ToString());
builder.Append(':');
SerializeValue(obj[e]);
first = false;
}
builder.Append('}');
}
void SerializeArray(IList anArray)
{
builder.Append('[');
bool first = true;
for (int i = 0; i < anArray.Count; i++)
{
object obj = anArray[i];
if (!first)
{
builder.Append(',');
}
SerializeValue(obj);
first = false;
}
builder.Append(']');
}
void SerializeString(string str)
{
builder.Append('\"');
char[] charArray = str.ToCharArray();
for (int i = 0; i < charArray.Length; i++)
{
char c = charArray[i];
switch (c)
{
case '"':
builder.Append("\\\"");
break;
case '\\':
builder.Append("\\\\");
break;
case '\b':
builder.Append("\\b");
break;
case '\f':
builder.Append("\\f");
break;
case '\n':
builder.Append("\\n");
break;
case '\r':
builder.Append("\\r");
break;
case '\t':
builder.Append("\\t");
break;
default:
int codepoint = Convert.ToInt32(c);
if ((codepoint >= 32) && (codepoint <= 126))
{
builder.Append(c);
}
else
{
builder.Append("\\u");
builder.Append(codepoint.ToString("x4"));
}
break;
}
}
builder.Append('\"');
}
void SerializeOther(object value)
{
// NOTE: decimals lose precision during serialization.
// They always have, I'm just letting you know.
// Previously floats and doubles lost precision too.
if (value is float)
{
builder.Append(((float)value).ToString("R", System.Globalization.CultureInfo.InvariantCulture));
}
else if (value is int
|| value is uint
|| value is long
|| value is sbyte
|| value is byte
|| value is short
|| value is ushort
|| value is ulong)
{
builder.Append(value);
}
else if (value is double
|| value is decimal)
{
builder.Append(Convert.ToDouble(value).ToString("R", System.Globalization.CultureInfo.InvariantCulture));
}
else
{
SerializeString(value.ToString());
}
}
}
}
}
+6 -1
View File
@@ -25,7 +25,12 @@ namespace Update
[STAThread]
static void Main(string[] args)
{
if (args.Length > 0)
//Program.oldVersion = 1332;
//Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new MainForm());
//return;
if (args.Length > 0)
{
try
{
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.2.0.0")]
[assembly: AssemblyFileVersion("1.2.0.0")]
+1
View File
@@ -62,6 +62,7 @@
<Compile Include="MainForm.designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="MiniJson.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WebClientUtils.cs">
+81 -5
View File
@@ -1,4 +1,5 @@
using AllBase;
using AllBase.Helper;
using AllBase.Model.Result;
using Newtonsoft.Json;
using System;
@@ -14,11 +15,17 @@ namespace Work.Services
/// </summary>
public class CloudGoodsService
{
private const string ServerUrl = "http://103.90.155.78:14312";
private static string ServerUrl = "http://103.90.155.78:9001";
static CloudGoodsService()
{
if (EnvironmentHelper.IsDevelopment)
{
ServerUrl = "http://localhost:9001";
}
}
public static async Task<PageData<CloudGoods>> GetGoods(GoodsSearchRequest request)
{
string data = JsonHelper.SerializeObject(request);
var html = await GetHtml.PostUtf8Async(ServerUrl + "/Goods/SearchGoods", data, "application/json");
var html = await GetHtml.PostJsonAsync(ServerUrl + "/api/CloudGoods/SearchGoods", request);
var ret = JsonConvert.DeserializeObject<Result<PageData<CloudGoods>>>(html);
if (ret.Code != 200)
@@ -29,7 +36,7 @@ namespace Work.Services
}
public static string GetGoodsDetail(long goodsId)
{
var html = GetHtml.GetUtf8(ServerUrl + $"/Goods/GetGoodsRawData?goodsId={goodsId}", "application/json");
var html = GetHtml.PostJson(ServerUrl + $"/api/CloudGoods/GetGoodsRawData?goodsId={goodsId}", "");
var ret = JsonConvert.DeserializeObject<Result<string>>(html);
if (ret.Code != 200)
@@ -38,6 +45,72 @@ namespace Work.Services
}
return ret.Data;
}
#region user
/// <summary>
/// 搜索收藏
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static async Task<PageData<CloudGoods>> SearchFavorites(UserFavoritesGoodsSearchRequest request)
{
request.UserName = BaseClass.UserName;
var html = await GetHtml.PostJsonAsync(ServerUrl + "/api/CloudGoods/SearchFavorites", request);
var ret = JsonConvert.DeserializeObject<Result<PageData<CloudGoods>>>(html);
if (ret.Code != 200)
{
throw new Exception(ret.Msg);
}
return ret.Data;
}
/// <summary>
/// 收藏
/// </summary>
/// <param name="goodsIds"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static async Task<int> Favorite(List<long> goodsIds)
{
var html = await GetHtml.PostJsonAsync(ServerUrl + $"/api/CloudGoods/AddFavorite", new
{
UserName = BaseClass.UserName,
GoodsIds = goodsIds,
});
var ret = JsonConvert.DeserializeObject<Result<int>>(html);
if (ret.Code != 200)
{
throw new Exception(ret.Msg);
}
return ret.Data;
}
/// <summary>
/// 取消收藏
/// </summary>
/// <param name="goodsIds"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static async Task<int> RemoveFavorites(List<long> goodsIds)
{
var html = await GetHtml.PostJsonAsync(ServerUrl + $"/api/CloudGoods/RemoveFavorites", new
{
UserName = BaseClass.UserName,
GoodsIds = goodsIds,
});
var ret = JsonConvert.DeserializeObject<Result<int>>(html);
if (ret.Code != 200)
{
throw new Exception(ret.Msg);
}
return ret.Data;
}
#endregion
}
/// <summary>
/// 商品搜索请求
@@ -105,7 +178,10 @@ namespace Work.Services
public int PageSize { get; set; } = 20;
}
public class UserFavoritesGoodsSearchRequest : GoodsSearchRequest
{
public string UserName { get; set; }
}
/// <summary>
/// 商品搜索返回结果
/// </summary>
+1 -1
View File
@@ -143,7 +143,7 @@ namespace KJD.Test
[Test]
public void TestWXToPDDV4()
{
string filePath = @"C:\Users\chaih\Documents\xwechat_files\hongfei357_a567\msg\file\2026-10\10000033063024.json";
string filePath = @"C:\Users\chaih\Documents\xwechat_files\hongfei357_a567\msg\file\2026-10\导入失败数据包\10000023711970.txt";
var frontProdInfo = ConverterToPddFactory.Convert(filePath);
var isMatch = frontProdInfo != null;
Console.WriteLine(frontProdInfo.Skus.Count);