Merge branch 'master' of github.com:KJD2025/KJD
This commit is contained in:
commit
737670adec
17 files changed
+3826
-1064
No files matched your search
@@ -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
|
||||
|
||||
@@ -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>
|
||||
+541
-501
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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Generated
+216
-128
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<object>, a Dictionary<string, object>, 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<string, object> / List<object></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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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")]
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user