83 changed files with 6221 additions and 46 deletions
@ -0,0 +1,58 @@ |
|||
using BBWY.Common.Http; |
|||
using BBWY.Common.Models; |
|||
using Newtonsoft.Json; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Net.Http; |
|||
using Microsoft.Extensions.Configuration; |
|||
namespace BBWY.Client.APIServices |
|||
{ |
|||
public class BaseApiService |
|||
{ |
|||
private RestApiService restApiService; |
|||
|
|||
protected GlobalContext globalContext; |
|||
|
|||
public BaseApiService(RestApiService restApiService, GlobalContext globalContext) |
|||
{ |
|||
this.restApiService = restApiService; |
|||
this.globalContext = globalContext; |
|||
} |
|||
|
|||
protected ApiResponse<T> SendRequest<T>(string apiHost, |
|||
string apiPath, |
|||
object param, |
|||
IDictionary<string, string> headers, |
|||
HttpMethod httpMethod, |
|||
string contentType = RestApiService.ContentType_Json, |
|||
ParamPosition paramPosition = ParamPosition.Body, |
|||
bool enableRandomTimeStamp = false) |
|||
{ |
|||
try |
|||
{ |
|||
if (headers == null) |
|||
headers = new Dictionary<string, string>(); |
|||
if (!headers.ContainsKey("ClientCode")) |
|||
headers.Add("ClientCode", "BBWY"); |
|||
if (!headers.ContainsKey("ClientVersion")) |
|||
headers.Add("ClientVersion", "1.0.0.0"); |
|||
if (!headers.ContainsKey("Authorization") && !string.IsNullOrEmpty(globalContext.UserToken)) |
|||
headers.Add("Authorization", $"Bearer {globalContext.UserToken}"); |
|||
if (!headers.ContainsKey("qy")) |
|||
headers.Add("qy", "qy"); |
|||
|
|||
var result = restApiService.SendRequest(apiHost, apiPath, param, headers, httpMethod, contentType, paramPosition, enableRandomTimeStamp); |
|||
if (result.StatusCode != System.Net.HttpStatusCode.OK && |
|||
result.Content.Contains("\"Success\"") && |
|||
result.Content.Contains("\"Msg\"") && |
|||
result.Content.Contains("\"Data\"")) |
|||
throw new BusinessException($"{result.StatusCode} {result.Content}") { Code = (int)result.StatusCode }; |
|||
return JsonConvert.DeserializeObject<ApiResponse<T>>(result.Content); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
return ApiResponse<T>.Error((ex is BusinessException) ? (ex as BusinessException).Code : 0, ex.Message); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,113 @@ |
|||
using BBWYB.Client.Models; |
|||
using BBWY.Common.Http; |
|||
using BBWY.Common.Models; |
|||
using Newtonsoft.Json.Linq; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Net.Http; |
|||
|
|||
namespace BBWY.Client.APIServices |
|||
{ |
|||
public class MdsApiService : BaseApiService, IDenpendency |
|||
{ |
|||
public MdsApiService(RestApiService restApiService, GlobalContext globalContext) : base(restApiService, globalContext) |
|||
{ |
|||
|
|||
} |
|||
|
|||
public ApiResponse<MDSUserResponse> GetUserInfo(string userToken) |
|||
{ |
|||
return SendRequest<MDSUserResponse>(globalContext.MDSApiHost, |
|||
"/TaskList/User/GetUserInfo", |
|||
null, |
|||
new Dictionary<string, string>() |
|||
{ |
|||
{ "Authorization", $"Bearer {userToken}" } |
|||
}, HttpMethod.Get); |
|||
} |
|||
|
|||
|
|||
|
|||
//public ApiResponse<IList<ShopResponse>> GetShopsByUserTeam(long userId)
|
|||
//{
|
|||
// return SendRequest<IList<ShopResponse>>(globalContext.MDSApiHost, "TaskList/Shop/GetShopsByUserTeam", $"userId={userId}", null, System.Net.Http.HttpMethod.Get);
|
|||
//}
|
|||
|
|||
public ApiResponse<IList<Department>> GetShopDetailList() |
|||
{ |
|||
var response = new ApiResponse<IList<Department>>(); |
|||
var response2 = SendRequest<JArray>(globalContext.MDSApiHost, "TaskList/UserDepartment/GetShopDetailList", null, null, HttpMethod.Get); |
|||
if (!response.Success) |
|||
{ |
|||
response.Code = response2.Code; |
|||
response.Msg = response2.Msg; |
|||
return response; |
|||
} |
|||
|
|||
response.Data = new List<Department>(); |
|||
foreach (var jDepartment in response2.Data) |
|||
{ |
|||
var jayShops = jDepartment.Value<JArray>("ShopList"); |
|||
if (jayShops == null || !jayShops.HasValues) |
|||
continue; //排除空店部门
|
|||
var d = new Department() |
|||
{ |
|||
Id = jDepartment.Value<string>("Id"), |
|||
Name = jDepartment.Value<string>("DepartmentName") |
|||
}; |
|||
response.Data.Add(d); |
|||
foreach (var jShop in jayShops) |
|||
{ |
|||
var shopId = jShop.Value<long?>("ShopId"); |
|||
if (shopId == null || string.IsNullOrEmpty(jShop.Value<string>("AppToken"))) |
|||
continue; //排除未授权
|
|||
try |
|||
{ |
|||
var jayAccounts = jShop.Value<JArray>("AccountList"); |
|||
if ((jayAccounts == null || !jayAccounts.HasValues) && d.ShopList.Count(s => s.ShopId == shopId) > 0) |
|||
{ |
|||
continue; |
|||
} |
|||
var shop = new Shop() |
|||
{ |
|||
ShopId = shopId.Value, |
|||
AppKey = jShop.Value<string>("AppKey"), |
|||
AppSecret = jShop.Value<string>("AppSecret"), |
|||
AppToken = jShop.Value<string>("AppToken"), |
|||
ManagePwd = jShop.Value<string>("ManagePwd"), |
|||
Platform = (Platform)jShop.Value<int>("PlatformId"), |
|||
PlatformCommissionRatio = jShop.Value<decimal?>("PlatformCommissionRatio") ?? 0.05M, |
|||
ShopName = jShop.Value<string>("ShopName"), |
|||
VenderType = jShop.Value<string>("ShopType"), |
|||
TeamId = jShop.Value<string>("TeamId") |
|||
}; |
|||
d.ShopList.Add(shop); |
|||
|
|||
shop.PurchaseAccountList = new List<PurchaseAccount>(); |
|||
foreach (var jPurchaseAccount in jayAccounts) |
|||
{ |
|||
shop.PurchaseAccountList.Add(new PurchaseAccount() |
|||
{ |
|||
Id = jPurchaseAccount.Value<long>("Id"), |
|||
AccountName = jPurchaseAccount.Value<string>("AccountName"), |
|||
AppKey = jPurchaseAccount.Value<string>("AppKey"), |
|||
AppSecret = jPurchaseAccount.Value<string>("AppSecret"), |
|||
AppToken = jPurchaseAccount.Value<string>("AppToken"), |
|||
ShopId = shop.ShopId, |
|||
PurchasePlatformId = (Platform)jPurchaseAccount.Value<int>("AppPlatformId") |
|||
}); |
|||
} |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
Console.WriteLine(jShop.ToString()); |
|||
throw; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,51 @@ |
|||
using BBWY.Common.Http; |
|||
using BBWY.Common.Models; |
|||
using Newtonsoft.Json.Linq; |
|||
using System; |
|||
using System.Net.Http; |
|||
|
|||
namespace BBWY.Client.APIServices |
|||
{ |
|||
public class OneBoundAPIService : IDenpendency |
|||
{ |
|||
private RestApiService restApiService; |
|||
private string key = "t5060712539"; |
|||
private string secret = "20211103"; |
|||
|
|||
public OneBoundAPIService(RestApiService restApiService) |
|||
{ |
|||
this.restApiService = restApiService; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 产品详细信息接口
|
|||
/// </summary>
|
|||
/// <param name="platform">1699/jd/taobao 更多值参阅https://open.onebound.cn/help/api/</param>
|
|||
/// <param name="key"></param>
|
|||
/// <param name="secret"></param>
|
|||
/// <param name="productId"></param>
|
|||
/// <returns></returns>
|
|||
public ApiResponse<JObject> GetProductInfo(string platform, string productId) |
|||
{ |
|||
try |
|||
{ |
|||
//https://api-gw.onebound.cn/1688/item_get/key=t5060712539&secret=20211103&num_iid=649560646832&lang=zh-CN&cache=no
|
|||
var result = restApiService.SendRequest("https://api-gw.onebound.cn/", $"{platform}/item_get", $"key={key}&secret={secret}&num_iid={productId}&lang=zh-CN&cache=no", null, HttpMethod.Get, paramPosition: ParamPosition.Query, enableRandomTimeStamp: true); |
|||
if (result.StatusCode != System.Net.HttpStatusCode.OK) |
|||
throw new Exception($"{result.StatusCode} {result.Content}"); |
|||
|
|||
var j = JObject.Parse(result.Content); |
|||
return new ApiResponse<JObject>() |
|||
{ |
|||
Data = j, |
|||
Code = j.Value<string>("error_code") == "0000" ? 200 : 0, |
|||
Msg = j.Value<string>("error") |
|||
}; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
return ApiResponse<JObject>.Error(0, ex.Message); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,49 @@ |
|||
using BBWYB.Client.Models; |
|||
using BBWY.Common.Http; |
|||
using BBWY.Common.Models; |
|||
using System.Collections.Generic; |
|||
using System.Net.Http; |
|||
|
|||
namespace BBWY.Client.APIServices |
|||
{ |
|||
public class ProductService : BaseApiService, IDenpendency |
|||
{ |
|||
public ProductService(RestApiService restApiService, GlobalContext globalContext) : base(restApiService, globalContext) { } |
|||
|
|||
public ApiResponse<ProductListResponse> GetProductList(string spu, string productName, string productItem, int pageIndex) |
|||
{ |
|||
return SendRequest<ProductListResponse>(globalContext.BBYWApiHost, |
|||
"api/product/GetProductList", |
|||
new |
|||
{ |
|||
Spu = spu, |
|||
ProductName = productName, |
|||
ProductItem = productItem, |
|||
PageIndex = pageIndex, |
|||
Platform = globalContext.User.Shop.Platform, |
|||
AppKey = globalContext.User.Shop.AppKey, |
|||
AppSecret = globalContext.User.Shop.AppSecret, |
|||
AppToken = globalContext.User.Shop.AppToken |
|||
}, |
|||
null, |
|||
HttpMethod.Post); |
|||
} |
|||
|
|||
public ApiResponse<IList<ProductSku>> GetProductSkuList(string spu, string sku) |
|||
{ |
|||
return SendRequest<IList<ProductSku>>(globalContext.BBYWApiHost, |
|||
"api/product/GetProductSkuList", |
|||
new |
|||
{ |
|||
Spu = spu, |
|||
Sku = sku, |
|||
Platform = globalContext.User.Shop.Platform, |
|||
AppKey = globalContext.User.Shop.AppKey, |
|||
AppSecret = globalContext.User.Shop.AppSecret, |
|||
AppToken = globalContext.User.Shop.AppToken |
|||
}, |
|||
null, |
|||
HttpMethod.Post); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,166 @@ |
|||
using BBWYB.Client.Models; |
|||
using BBWY.Common.Http; |
|||
using BBWY.Common.Models; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Net.Http; |
|||
|
|||
namespace BBWY.Client.APIServices |
|||
{ |
|||
public class PurchaseOrderService : BaseApiService, IDenpendency |
|||
{ |
|||
public PurchaseOrderService(RestApiService restApiService, GlobalContext globalContext) : base(restApiService, globalContext) |
|||
{ |
|||
|
|||
} |
|||
|
|||
public ApiResponse<object> AddPurchaseOrder(PurchaseOrder purchaseOrder) |
|||
{ |
|||
return SendRequest<object>(globalContext.BBYWApiHost, |
|||
"api/PurchaseOrder/AddPurchaseOrder", |
|||
purchaseOrder, |
|||
null, |
|||
HttpMethod.Post); |
|||
} |
|||
|
|||
public ApiResponse<object> EditPurchaseOrder(PurchaseOrder purchaseOrder) |
|||
{ |
|||
return SendRequest<object>(globalContext.BBYWApiHost, |
|||
"api/PurchaseOrder/EditPurchaseOrder", |
|||
purchaseOrder, |
|||
null, |
|||
HttpMethod.Put); |
|||
} |
|||
|
|||
public ApiResponse<IList<PurchaseOrderResponse>> GetList(IList<string> skuIdList, StorageType storageType, long shopId) |
|||
{ |
|||
return SendRequest<IList<PurchaseOrderResponse>>(globalContext.BBYWApiHost, |
|||
"api/PurchaseOrder/GetList", |
|||
new { SkuIdList = skuIdList, StorageType = storageType, ShopId = shopId }, |
|||
null, |
|||
HttpMethod.Post); |
|||
} |
|||
|
|||
public ApiResponse<object> DeletePurchaseOrder(long id) |
|||
{ |
|||
return SendRequest<object>(globalContext.BBYWApiHost, |
|||
$"api/purchaseOrder/deletePurchaseOrder/{id}", |
|||
null, |
|||
null, |
|||
HttpMethod.Delete); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 预览订单
|
|||
/// </summary>
|
|||
/// <param name="consignee"></param>
|
|||
/// <param name="purchaseSchemeProductSkuList"></param>
|
|||
/// <returns></returns>
|
|||
public ApiResponse<PreviewOrderResponse> PreviewPurchaseOrder(Consignee consignee, IList<PurchaseSchemeProductSku> purchaseSchemeProductSkuList, Platform purchasePlatform, PurchaseAccount purchaseAccount, PurchaseOrderMode purchaseOrderMode) |
|||
{ |
|||
return SendRequest<PreviewOrderResponse>(globalContext.BBYWApiHost, "api/purchaseOrder/PreviewPurchaseOrder", new |
|||
{ |
|||
purchaseOrderMode, |
|||
consignee, |
|||
CargoParamList = purchaseSchemeProductSkuList.Select(sku => new |
|||
{ |
|||
ProductId = sku.PurchaseProductId, |
|||
SkuId = sku.PurchaseSkuId, |
|||
SpecId = sku.PurchaseSkuSpecId, |
|||
Quantity = sku.ItemTotal, |
|||
BelongSkuId = sku.SkuId |
|||
}), |
|||
Platform = purchasePlatform, |
|||
AppKey = purchaseAccount.AppKey, |
|||
AppSecret = purchaseAccount.AppSecret, |
|||
AppToken = purchaseAccount.AppToken, |
|||
SaveResponseLog = true |
|||
}, null, HttpMethod.Post); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 创建采购单
|
|||
/// </summary>
|
|||
/// <param name="consignee"></param>
|
|||
/// <param name="purchaseSchemeProductSkuList"></param>
|
|||
/// <param name="purchasePlatform"></param>
|
|||
/// <param name="purchaseAccount"></param>
|
|||
/// <param name="purchaseOrderMode"></param>
|
|||
/// <param name="tradeMode"></param>
|
|||
/// <param name="remark"></param>
|
|||
/// <param name="orderId"></param>
|
|||
/// <param name="shopId"></param>
|
|||
/// <param name="purchaseAccountId"></param>
|
|||
/// <param name="buyerAccount"></param>
|
|||
/// <param name="sellerAccount"></param>
|
|||
/// <param name="purchaserId"></param>
|
|||
/// <param name="platformCommissionRatio"></param>
|
|||
/// <param name="extensions"></param>
|
|||
/// <returns></returns>
|
|||
public ApiResponse<object> FastCreateOrder(Consignee consignee, |
|||
IList<PurchaseSchemeProductSku> purchaseSchemeProductSkuList, |
|||
Platform purchasePlatform, |
|||
PurchaseAccount purchaseAccount, |
|||
PurchaseOrderMode purchaseOrderMode, |
|||
string tradeMode, |
|||
string remark, |
|||
string orderId, |
|||
long shopId, |
|||
long purchaseAccountId, |
|||
string buyerAccount, |
|||
string sellerAccount, |
|||
string purchaserId, |
|||
decimal platformCommissionRatio, |
|||
string extensions) |
|||
{ |
|||
return SendRequest<object>(globalContext.BBYWApiHost, "api/purchaseOrder/NewFastCreateOrder", new |
|||
{ |
|||
purchaseOrderMode, |
|||
consignee, |
|||
CargoParamList = purchaseSchemeProductSkuList.Select(sku => new |
|||
{ |
|||
ProductId = sku.PurchaseProductId, |
|||
SkuId = sku.PurchaseSkuId, |
|||
SpecId = sku.PurchaseSkuSpecId, |
|||
Quantity = sku.ItemTotal, |
|||
BelongSkuId = sku.SkuId |
|||
}), |
|||
Platform = purchasePlatform, |
|||
AppKey = purchaseAccount.AppKey, |
|||
AppSecret = purchaseAccount.AppSecret, |
|||
AppToken = purchaseAccount.AppToken, |
|||
SaveResponseLog = true, |
|||
tradeMode, |
|||
remark, |
|||
orderId, |
|||
shopId, |
|||
purchaseAccountId, |
|||
buyerAccount, |
|||
sellerAccount, |
|||
purchaserId, |
|||
platformCommissionRatio, |
|||
extensions |
|||
}, null, HttpMethod.Post); |
|||
} |
|||
|
|||
|
|||
|
|||
/// <summary>
|
|||
/// 查询审核采购单
|
|||
/// </summary>
|
|||
/// <param name="shopIdList"></param>
|
|||
/// <param name="startDate"></param>
|
|||
/// <param name="endDate"></param>
|
|||
/// <returns></returns>
|
|||
public ApiResponse<IList<AuditPurchaseOrderResponse>> GetAuditPurchaseOrderList(IList<long> shopIdList, DateTime startDate, DateTime endDate) |
|||
{ |
|||
return SendRequest<IList<AuditPurchaseOrderResponse>>(globalContext.BBYWApiHost, "Api/PurchaseOrder/GetAuditPurchaseOrderList", new |
|||
{ |
|||
startDate, |
|||
endDate, |
|||
shopIdList |
|||
}, null, HttpMethod.Post); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,278 @@ |
|||
using BBWY.Common.Http; |
|||
using BBWY.Common.Models; |
|||
using Microsoft.Extensions.Caching.Memory; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Net.Http; |
|||
using System.Text.RegularExpressions; |
|||
|
|||
namespace BBWY.Client.APIServices |
|||
{ |
|||
public class PurchaseProductAPIService : IDenpendency |
|||
{ |
|||
private RestApiService restApiService; |
|||
private IMemoryCache memoryCache; |
|||
private string oneBoundKey = "t5060712539"; |
|||
private string oneBoundSecret = "20211103"; |
|||
|
|||
private string qtAppId = "BBWY2023022001"; |
|||
private string qtAppSecret = "908e131365d5448ca651ba20ed7ddefe"; |
|||
|
|||
private TimeSpan purchaseProductCacheTimeSpan; |
|||
//private TimeSpan _1688SessionIdTimeSpan;
|
|||
|
|||
//private ConcurrentDictionary<string, (Purchaser purchaser, IList<PurchaseSchemeProductSku> purchaseSchemeProductSkus)> productChaches;
|
|||
|
|||
private IDictionary<string, string> _1688ProductDetailRequestHeader; |
|||
|
|||
public PurchaseProductAPIService(RestApiService restApiService, IMemoryCache memoryCache) |
|||
{ |
|||
this.restApiService = restApiService; |
|||
this.memoryCache = memoryCache; |
|||
_1688ProductDetailRequestHeader = new Dictionary<string, string>() |
|||
{ |
|||
{ "Host","detail.1688.com"}, |
|||
{ "User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.70"}, |
|||
{ "Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"}, |
|||
{ "Accept-Encoding","gzip, deflate, br"}, |
|||
{ "Accept-Language","zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"} |
|||
}; |
|||
purchaseProductCacheTimeSpan = TimeSpan.FromDays(1); |
|||
} |
|||
|
|||
public (Purchaser purchaser, IList<PurchaseSchemeProductSku> purchaseSchemeProductSkus)? GetProductInfo(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode, PurchaseProductAPIMode apiMode) |
|||
{ |
|||
if (memoryCache.TryGetValue<(Purchaser, IList<PurchaseSchemeProductSku>)>($"{purchaseProductId}_{priceMode}", out var tuple)) |
|||
return tuple.Copy(); |
|||
|
|||
(Purchaser purchaser, IList<PurchaseSchemeProductSku> purchaseSchemeProductSkus)? data = null; |
|||
|
|||
if (apiMode == PurchaseProductAPIMode.Spider) |
|||
{ |
|||
data = LoadFromSpider(platform, productId, skuId, purchaseProductId, priceMode); |
|||
if (data == null) |
|||
data = LoadFromOneBound(platform, productId, skuId, purchaseProductId, priceMode); |
|||
} |
|||
else if (apiMode == PurchaseProductAPIMode.OneBound) |
|||
{ |
|||
data = LoadFromOneBound(platform, productId, skuId, purchaseProductId, priceMode); |
|||
if (data == null) |
|||
data = LoadFromSpider(platform, productId, skuId, purchaseProductId, priceMode); |
|||
} |
|||
|
|||
if (data != null) |
|||
{ |
|||
try |
|||
{ |
|||
memoryCache.Set<(Purchaser, IList<PurchaseSchemeProductSku>)>($"{purchaseProductId}_{priceMode}", data.Value, purchaseProductCacheTimeSpan); |
|||
} |
|||
catch { } |
|||
} |
|||
|
|||
return data?.Copy(); |
|||
} |
|||
|
|||
private (Purchaser purchaser, IList<PurchaseSchemeProductSku> purchaseSchemeProductSkus)? LoadFromOneBound(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode) |
|||
{ |
|||
try |
|||
{ |
|||
string platformStr = string.Empty; |
|||
if (platform == Platform.阿里巴巴) |
|||
platformStr = "1688"; |
|||
|
|||
if (string.IsNullOrEmpty(platformStr)) |
|||
return null; |
|||
|
|||
var result = restApiService.SendRequest("https://api-gw.onebound.cn/", $"{platformStr}/item_get", $"key={oneBoundKey}&secret={oneBoundSecret}&num_iid={purchaseProductId}&lang=zh-CN&cache=no&agent={(priceMode == PurchaseOrderMode.批发 ? 0 : 1)}", null, HttpMethod.Get, paramPosition: ParamPosition.Query, enableRandomTimeStamp: true); |
|||
if (result.StatusCode != System.Net.HttpStatusCode.OK) |
|||
throw new Exception($"{result.StatusCode} {result.Content}"); |
|||
|
|||
var jobject = JObject.Parse(result.Content); |
|||
var isOK = jobject.Value<string>("error_code") == "0000"; |
|||
if (isOK) |
|||
{ |
|||
var skuJArray = (JArray)jobject["item"]["skus"]["sku"]; |
|||
if (skuJArray.Count == 0) |
|||
{ |
|||
//errorMsg = $"商品{purchaseSchemeProduct.PurchaseProductId}缺少sku信息";
|
|||
return null; |
|||
} |
|||
|
|||
var list = skuJArray.Select(j => new PurchaseSchemeProductSku() |
|||
{ |
|||
ProductId = productId, |
|||
SkuId = skuId, |
|||
PurchaseProductId = purchaseProductId, |
|||
Price = j.Value<decimal>("price"), |
|||
PurchaseSkuId = j.Value<string>("sku_id"), |
|||
PurchaseSkuSpecId = j.Value<string>("spec_id"), |
|||
Title = j.Value<string>("properties_name"), |
|||
Logo = GetOneBoundSkuLogo(j, (JArray)jobject["item"]["prop_imgs"]["prop_img"]) |
|||
}).ToList(); |
|||
|
|||
var purchaserId = jobject["item"]["seller_info"].Value<string>("user_num_id"); |
|||
var purchaserName = jobject["item"]["seller_info"].Value<string>("title"); |
|||
if (string.IsNullOrEmpty(purchaserName)) |
|||
purchaserName = jobject["item"]["seller_info"].Value<string>("shop_name"); |
|||
var purchaserLocation = jobject["item"].Value<string>("location"); |
|||
|
|||
return (new Purchaser() |
|||
{ |
|||
Id = purchaserId, |
|||
Name = purchaserName, |
|||
Location = purchaserLocation |
|||
}, list); |
|||
} |
|||
} |
|||
catch { } |
|||
{ |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
private string GetOneBoundSkuLogo(JToken skuJToken, JArray prop_img) |
|||
{ |
|||
if (!prop_img.HasValues) |
|||
return "pack://application:,,,/Resources/Images/defaultItem.png"; |
|||
var properties = skuJToken.Value<string>("properties").Split(';', StringSplitOptions.RemoveEmptyEntries); |
|||
foreach (var p in properties) |
|||
{ |
|||
var imgJToken = prop_img.FirstOrDefault(g => g.Value<string>("properties") == p); |
|||
if (imgJToken != null) |
|||
return imgJToken.Value<string>("url"); |
|||
} |
|||
return "pack://application:,,,/Resources/Images/defaultItem.png"; |
|||
} |
|||
|
|||
private (Purchaser purchaser, IList<PurchaseSchemeProductSku> purchaseSchemeProductSkus)? LoadFromSpider(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode) |
|||
{ |
|||
switch (platform) |
|||
{ |
|||
case Platform.阿里巴巴: |
|||
return LoadFrom1688Spider(platform, productId, skuId, purchaseProductId, priceMode); |
|||
case Platform.拳探: |
|||
return LoadFromQTSpider(platform, productId, skuId, purchaseProductId, priceMode); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
private (Purchaser purchaser, IList<PurchaseSchemeProductSku> purchaseSchemeProductSkus)? LoadFrom1688Spider(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode) |
|||
{ |
|||
//https://detail.1688.com/offer/672221374773.html?clickid=65f3772cd5d16f190ce4991414607&sessionid=3de47a0c26dcbfde4692064bd55861&sk=order
|
|||
|
|||
//globalData/tempModel/sellerUserId
|
|||
//globalData/tempModel/companyName
|
|||
//data/1081181309101/data/location
|
|||
|
|||
|
|||
//data/1081181309582/data/pirceModel/[currentPrices]/[0]price
|
|||
|
|||
try |
|||
{ |
|||
var _1688pageResult = restApiService.SendRequest("https://detail.1688.com", |
|||
$"offer/{purchaseProductId}.html", |
|||
$"clickid={Guid.NewGuid().ToString().Md5Encrypt()}&sessionid={Guid.NewGuid().ToString().Md5Encrypt()}&sk={(priceMode == PurchaseOrderMode.批发 ? "order" : "consign")}", |
|||
_1688ProductDetailRequestHeader, |
|||
HttpMethod.Get, |
|||
httpClientName: "gzip"); |
|||
|
|||
if (_1688pageResult.StatusCode != System.Net.HttpStatusCode.OK) |
|||
return null; |
|||
|
|||
var match = Regex.Match(_1688pageResult.Content, @"(window\.__INIT_DATA=)(.*)(\r*\n*\s*</script>)"); |
|||
if (!match.Success) |
|||
return null; |
|||
|
|||
var jsonStr = match.Groups[2].Value; |
|||
var jobject = JObject.Parse(jsonStr); |
|||
|
|||
//16347413030323
|
|||
var purchaser = new Purchaser() |
|||
{ |
|||
Id = jobject["globalData"]["tempModel"]["sellerUserId"].ToString(), |
|||
Name = jobject["globalData"]["tempModel"]["companyName"].ToString(), |
|||
Location = jobject["data"]["1081181309101"] != null ? |
|||
jobject["data"]["1081181309101"]["data"]["location"].ToString() : |
|||
jobject["data"]["16347413030323"]["data"]["location"].ToString() |
|||
}; |
|||
|
|||
var colorsProperty = jobject["globalData"]["skuModel"]["skuProps"].FirstOrDefault(j => j.Value<int>("fid") == 3216 || |
|||
j.Value<int>("fid") == 1627207 || |
|||
j.Value<int>("fid") == 1234 || |
|||
j.Value<int>("fid") == 3151)["value"] |
|||
.Children() |
|||
.Select(j => new |
|||
{ |
|||
name = j.Value<string>("name"), |
|||
imageUrl = j.Value<string>("imageUrl") |
|||
}).ToList(); |
|||
|
|||
var firstPrice = jobject["data"]["1081181309582"] != null ? |
|||
jobject["data"]["1081181309582"]["data"]["priceModel"]["currentPrices"][0].Value<decimal>("price") : |
|||
jobject["data"]["16347413030316"]["data"]["priceModel"]["currentPrices"][0].Value<decimal>("price"); |
|||
|
|||
var purchaseSchemeProductSkus = new List<PurchaseSchemeProductSku>(); |
|||
|
|||
foreach (var jsku in jobject["globalData"]["skuModel"]["skuInfoMap"].Children()) |
|||
{ |
|||
var jskuProperty = jsku as JProperty; |
|||
var name = jskuProperty.Name; |
|||
var matchName = name.Contains(">") ? name.Substring(0, name.IndexOf(">")) : name; |
|||
var value = jskuProperty.Value; |
|||
|
|||
var skuPrice = value.Value<decimal>("price"); |
|||
|
|||
purchaseSchemeProductSkus.Add(new PurchaseSchemeProductSku() |
|||
{ |
|||
ProductId = productId, |
|||
SkuId = skuId, |
|||
PurchaseProductId = purchaseProductId, |
|||
Price = skuPrice == 0M ? firstPrice : skuPrice, |
|||
Title = name, |
|||
PurchaseSkuId = value.Value<string>("skuId"), |
|||
PurchaseSkuSpecId = value.Value<string>("specId"), |
|||
Logo = colorsProperty.FirstOrDefault(c => c.name == matchName)?.imageUrl ?? "pack://application:,,,/Resources/Images/defaultItem.png" |
|||
}); |
|||
} |
|||
|
|||
return (purchaser, purchaseSchemeProductSkus); |
|||
} |
|||
catch |
|||
{ |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
|
|||
private (Purchaser purchaser, IList<PurchaseSchemeProductSku> purchaseSchemeProductSkus)? LoadFromQTSpider(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode) |
|||
{ |
|||
try |
|||
{ |
|||
var response = quanTanProductClient.GetProductInfo(purchaseProductId, qtAppId, qtAppSecret); |
|||
if (response.Status != 200) |
|||
return null; |
|||
return (new Purchaser() |
|||
{ |
|||
Id = response.Data.Supplier.VenderId, |
|||
Name = response.Data.Supplier.VerdenName, |
|||
Location = response.Data.Supplier.Location |
|||
}, response.Data.ProductSku.Select(qtsku => new PurchaseSchemeProductSku() |
|||
{ |
|||
ProductId = productId, |
|||
SkuId = skuId, |
|||
PurchaseProductId = purchaseProductId, |
|||
Price = qtsku.Price, |
|||
Title = qtsku.Title, |
|||
PurchaseSkuId = qtsku.SkuId, |
|||
PurchaseSkuSpecId = string.Empty, |
|||
Logo = qtsku.Logo |
|||
}).ToList()); |
|||
} |
|||
catch |
|||
{ |
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,84 @@ |
|||
using BBWYB.Client.Models; |
|||
using BBWY.Common.Http; |
|||
using BBWY.Common.Models; |
|||
using System.Collections.Generic; |
|||
using System.Net.Http; |
|||
|
|||
namespace BBWY.Client.APIServices |
|||
{ |
|||
public class PurchaseService : BaseApiService, IDenpendency |
|||
{ |
|||
public PurchaseService(RestApiService restApiService, GlobalContext globalContext) : base(restApiService, globalContext) { } |
|||
|
|||
/// <summary>
|
|||
/// 获取采购方案
|
|||
/// </summary>
|
|||
/// <param name="skuIdList"></param>
|
|||
/// <param name="purchaserId"></param>
|
|||
/// <param name="shopId"></param>
|
|||
/// <param name="schemeId"></param>
|
|||
/// <param name="platform"></param>
|
|||
/// <returns></returns>
|
|||
public ApiResponse<IList<PurchaseSchemeResponse>> GetPurchaseSchemeList(IList<string> skuIdList = null, |
|||
string purchaserId = "", |
|||
long? shopId = null, |
|||
long? schemeId = null, |
|||
Platform? purchasePlatform = null) |
|||
{ |
|||
return SendRequest<IList<PurchaseSchemeResponse>>(globalContext.BBYWApiHost, |
|||
"api/PurchaseScheme/GetPurchaseSchemeList", |
|||
new |
|||
{ |
|||
skuIdList, |
|||
purchaserId, |
|||
shopId, |
|||
schemeId, |
|||
purchasePlatform |
|||
}, |
|||
null, |
|||
HttpMethod.Post); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取共有采购商
|
|||
/// </summary>
|
|||
/// <param name="skuId"></param>
|
|||
/// <param name="shopId"></param>
|
|||
/// <returns></returns>
|
|||
public ApiResponse<IList<Purchaser>> GetSharePurchaser(IList<string> skuIdList, long shopId) |
|||
{ |
|||
return SendRequest<IList<Purchaser>>(globalContext.BBYWApiHost, |
|||
"api/PurchaseScheme/GetSharePurchaser", |
|||
new { skuIdList, shopId }, |
|||
null, |
|||
HttpMethod.Post); |
|||
} |
|||
|
|||
public ApiResponse<object> EditPurchaseScheme(IList<PurchaseScheme> addPurchaseSchemeList, IList<PurchaseScheme> editPurchaseSchemeList) |
|||
{ |
|||
return SendRequest<object>(globalContext.BBYWApiHost, |
|||
"api/purchasescheme/EditPurchaseScheme", |
|||
new |
|||
{ |
|||
AddPurchaseSchemeList = addPurchaseSchemeList, |
|||
EditPurchaseSchemeList = editPurchaseSchemeList |
|||
}, |
|||
null, |
|||
HttpMethod.Post); |
|||
} |
|||
|
|||
public ApiResponse<object> DeletePurchaser(string productId, string purchaserId) |
|||
{ |
|||
return SendRequest<object>(globalContext.BBYWApiHost, |
|||
"api/purchasescheme/DeletePurchaser", |
|||
new { productId, purchaserId }, |
|||
null, |
|||
HttpMethod.Delete); |
|||
} |
|||
|
|||
public ApiResponse<object> DeletePurchaseScheme(long schemeId) |
|||
{ |
|||
return SendRequest<object>(globalContext.BBYWApiHost, $"api/purchasescheme/DeletePurchaseScheme/{schemeId}", null, null, HttpMethod.Delete); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,91 @@ |
|||
using BBWYB.Client.Models; |
|||
using BBWY.Common.Http; |
|||
using BBWY.Common.Models; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Net.Http; |
|||
using System.Text; |
|||
|
|||
namespace BBWY.Client.APIServices |
|||
{ |
|||
public class ShopService : BaseApiService, IDenpendency |
|||
{ |
|||
public ShopService(RestApiService restApiService, GlobalContext globalContext) : base(restApiService, globalContext) { } |
|||
|
|||
public ApiResponse<long> SaveShopSetting(long shopId, |
|||
string managerPwd, |
|||
decimal platformCommissionRatio, |
|||
PurchaseAccount purchaseAccount, |
|||
string dingDingWebHook, |
|||
string dingDingKey, |
|||
int skuSafeTurnoverDays, |
|||
string siNanDingDingWebHook, |
|||
string siNanDingDingKey, |
|||
int siNanPolicyLevel) |
|||
{ |
|||
return SendRequest<long>(globalContext.BBYWApiHost, "api/vender/SaveShopSetting", new |
|||
{ |
|||
shopId, |
|||
managerPwd, |
|||
platformCommissionRatio, |
|||
PurchaseAccountId = purchaseAccount.Id, |
|||
purchaseAccount.AccountName, |
|||
purchaseAccount.AppKey, |
|||
purchaseAccount.AppSecret, |
|||
purchaseAccount.AppToken, |
|||
purchaseAccount.PurchasePlatformId, |
|||
dingDingWebHook, |
|||
dingDingKey, |
|||
skuSafeTurnoverDays, |
|||
siNanDingDingWebHook, |
|||
siNanDingDingKey, |
|||
siNanPolicyLevel |
|||
}, null, HttpMethod.Post); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 根据订单Id查询归属店铺
|
|||
/// </summary>
|
|||
/// <param name="orderIdList"></param>
|
|||
/// <returns></returns>
|
|||
public ApiResponse<IList<OrderBelongShopResponse>> GetOrderBelongShop(IList<string> orderIdList) |
|||
{ |
|||
return SendRequest<IList<OrderBelongShopResponse>>(globalContext.BBYWApiHost, "api/order/GetOrderBelongShop", orderIdList, null, HttpMethod.Post); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取部门及下属店铺
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
public ApiResponse<IList<DepartmentResponse>> GetDepartmentList() |
|||
{ |
|||
return SendRequest<IList<DepartmentResponse>>(globalContext.BBYWApiHost, "api/vender/GetDeparmentList", null, |
|||
new Dictionary<string, string>() |
|||
{ |
|||
{ "bbwyTempKey", "21jfhayu27q" } |
|||
}, HttpMethod.Get); |
|||
} |
|||
|
|||
public ApiResponse<IList<ShopResponse>> GetShopListByIds(IList<string> shopIds) |
|||
{ |
|||
return SendRequest<IList<ShopResponse>>(globalContext.BBYWApiHost, "api/vender/GetShopListByShopIds", new |
|||
{ |
|||
shopIds |
|||
}, new Dictionary<string, string>() |
|||
{ |
|||
{ "bbwyTempKey", "21jfhayu27q" } |
|||
}, HttpMethod.Post); |
|||
} |
|||
|
|||
public ApiResponse<IList<WaiterResponse>> GetServiceGroupList() |
|||
{ |
|||
return SendRequest<IList<WaiterResponse>>(globalContext.BBYWApiHost, "api/vender/GetServiceGroupList", new |
|||
{ |
|||
globalContext.User.Shop.Platform, |
|||
globalContext.User.Shop.AppKey, |
|||
globalContext.User.Shop.AppSecret, |
|||
globalContext.User.Shop.AppToken, |
|||
}, null, HttpMethod.Post); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
using BBWYB.Client.Models; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BBWYB.Client |
|||
{ |
|||
public class GlobalContext : NotifyObject |
|||
{ |
|||
public GlobalContext() |
|||
{ |
|||
} |
|||
|
|||
private User user; |
|||
|
|||
public User User { get => user; set { Set(ref user, value); } } |
|||
|
|||
public string UserToken { get; set; } |
|||
|
|||
public IList<LogisticsResponse> LogisticsResponseList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// JD客户端
|
|||
/// </summary>
|
|||
//public IJdClient JdClient { get; set; }
|
|||
|
|||
#region APIHost
|
|||
public string BBYWApiHost { get; set; } |
|||
|
|||
public string MDSApiHost { get; set; } |
|||
#endregion
|
|||
} |
|||
} |
@ -1,12 +0,0 @@ |
|||
<Window x:Class="BBWYB.Client.MainWindow" |
|||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|||
xmlns:local="clr-namespace:BBWYB.Client" |
|||
mc:Ignorable="d" |
|||
Title="MainWindow" Height="450" Width="800"> |
|||
<Grid> |
|||
|
|||
</Grid> |
|||
</Window> |
@ -1,28 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
using System.Windows.Data; |
|||
using System.Windows.Documents; |
|||
using System.Windows.Input; |
|||
using System.Windows.Media; |
|||
using System.Windows.Media.Imaging; |
|||
using System.Windows.Navigation; |
|||
using System.Windows.Shapes; |
|||
|
|||
namespace BBWYB.Client |
|||
{ |
|||
/// <summary>
|
|||
/// Interaction logic for MainWindow.xaml
|
|||
/// </summary>
|
|||
public partial class MainWindow : Window |
|||
{ |
|||
public MainWindow() |
|||
{ |
|||
InitializeComponent(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class BillCorrectionRequest |
|||
{ |
|||
public string OrderId { get; set; } |
|||
|
|||
public decimal NewDeliveryExpressFreight { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class AfterSaleOrderListResponse |
|||
{ |
|||
public int Count { get; set; } |
|||
|
|||
public IList<AfterSaleOrderResponse> Items { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,160 @@ |
|||
using System; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class AfterSaleOrderResponse |
|||
{ |
|||
|
|||
public long Id { get; set; } |
|||
|
|||
|
|||
public DateTime? CreateTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 申请时间
|
|||
/// </summary>
|
|||
|
|||
public DateTime? ApplyTime { get; set; } |
|||
|
|||
|
|||
public string OrderId { get; set; } |
|||
|
|||
|
|||
public string ProductId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 商品处理结果
|
|||
/// </summary>
|
|||
public ProductResult? ProductResult { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 退款金额
|
|||
/// </summary>
|
|||
public decimal? RefundAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 退款时间
|
|||
/// </summary>
|
|||
public DateTime? RefundTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 售后补发成本
|
|||
/// </summary>
|
|||
public decimal? ReissueAfterSaleAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 补发快递费
|
|||
/// </summary>
|
|||
public decimal? ReissueFreight { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 补发货款成本
|
|||
/// </summary>
|
|||
public decimal? ReissueProductAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 服务单处理结果
|
|||
/// </summary>
|
|||
public ServiceResult? ServiceResult { get; set; } |
|||
|
|||
public long? ShopId { get; set; } |
|||
|
|||
public string SkuId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 服务单号
|
|||
/// </summary>
|
|||
public string ServiceId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 退货入仓操作费
|
|||
/// </summary>
|
|||
public decimal? RefundInStorageAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 退款采购成本
|
|||
/// </summary>
|
|||
public decimal? RefundPurchaseAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 耗材费
|
|||
/// </summary>
|
|||
public decimal? ConsumableAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 发货快递费
|
|||
/// </summary>
|
|||
public decimal? DeliveryExpressFreight { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 头程费
|
|||
/// </summary>
|
|||
public decimal? FirstFreight { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 入仓操作费
|
|||
/// </summary>
|
|||
public decimal? InStorageAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 出仓操作费
|
|||
/// </summary>
|
|||
public decimal? OutStorageAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 商品情况
|
|||
/// </summary>
|
|||
public ProductHealth? ProductHealth { get; set; } |
|||
|
|||
public string Logo { get; set; } |
|||
|
|||
public string Title { get; set; } |
|||
|
|||
public int ItemTotal { get; set; } |
|||
|
|||
public decimal Price { get; set; } |
|||
|
|||
public string ContactName { get; set; } |
|||
|
|||
public string Mobile { get; set; } |
|||
|
|||
public decimal AfterTotalCost { get; set; } = 0.0M; |
|||
|
|||
public decimal StorageAmount { get; set; } = 0.0M; |
|||
|
|||
/// <summary>
|
|||
/// 退款商户订单号
|
|||
/// </summary>
|
|||
public string RefundMerchantOrderNo { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 退款支付宝订单号
|
|||
/// </summary>
|
|||
public string RefundAlipayOrderNo { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购方式
|
|||
/// </summary>
|
|||
public PurchaseMethod? PurchaseMethod { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购平台
|
|||
/// </summary>
|
|||
public Platform? PurchasePlatform { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购单号
|
|||
/// </summary>
|
|||
public string PurchaseOrderId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购单主键
|
|||
/// </summary>
|
|||
public long? PurchaseOrderPKId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 刷单退货运费
|
|||
/// </summary>
|
|||
public decimal SDRefundFreight { get; set; } = 0.00M; |
|||
} |
|||
} |
@ -0,0 +1,76 @@ |
|||
using System; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class BillCorrectionOrderResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 订单号
|
|||
/// </summary>
|
|||
public string OrderId { get; set; } |
|||
|
|||
public long ShopId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单状态
|
|||
/// </summary>
|
|||
public OrderState? OrderState { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单开始日期
|
|||
/// </summary>
|
|||
public DateTime? StartTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 发货类型
|
|||
/// </summary>
|
|||
public StorageType? StorageType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 销售运费
|
|||
/// </summary>
|
|||
public decimal DeliveryExpressFreight { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// Sku成本(商品成本)
|
|||
/// </summary>
|
|||
public decimal SkuAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 采购运费
|
|||
/// </summary>
|
|||
public decimal PurchaseFreight { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 头程运费
|
|||
/// </summary>
|
|||
public decimal FirstFreight { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 入仓操作费
|
|||
/// </summary>
|
|||
public decimal InStorageAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 出仓操作费
|
|||
/// </summary>
|
|||
public decimal OutStorageAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 耗材费
|
|||
/// </summary>
|
|||
public decimal ConsumableAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 仓储费
|
|||
/// </summary>
|
|||
public decimal StorageAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 售后费用
|
|||
/// </summary>
|
|||
public decimal AfterTotalCost { get; set; } |
|||
|
|||
public string WaybillNo { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,107 @@ |
|||
using System; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class AuditPayBillResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 账单流水号
|
|||
/// </summary>
|
|||
public long PayBillNo { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 归属店铺
|
|||
/// </summary>
|
|||
public string BelongShop { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 归属店铺Id
|
|||
/// </summary>
|
|||
|
|||
public int? BelongShopId { get; set; } |
|||
|
|||
public DateTime? CreateTime { get; set; } |
|||
|
|||
public DateTime? OrderStartTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 支出金额
|
|||
/// </summary>
|
|||
public decimal? ExpenditureAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 收入金额
|
|||
/// </summary>
|
|||
public decimal? IncomeAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否支持商户订单号
|
|||
/// </summary>
|
|||
|
|||
public bool? IsSupportMerchantOrderNo { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 格式化之后的商家订单号
|
|||
/// </summary>
|
|||
|
|||
public string MerchantOrderNo { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 对方账户
|
|||
/// </summary>
|
|||
|
|||
public string OppositeAccount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 账单类型
|
|||
/// </summary>
|
|||
public PayBillType? PayBillType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 支付时间
|
|||
/// </summary>
|
|||
public DateTime? PayTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 商品名称
|
|||
/// </summary>
|
|||
|
|||
public string ProductName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 关联采购订单号
|
|||
/// </summary>
|
|||
public string RelationPurchaseOrderId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 关联平台订单Id
|
|||
/// </summary>
|
|||
public string RelationShopOrderId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 备注
|
|||
/// </summary>
|
|||
|
|||
public string Remark { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 原始商家订单号
|
|||
/// </summary>
|
|||
|
|||
public string SourceMerchantOrderNo { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 导入时选择的店铺
|
|||
/// </summary>
|
|||
public string ImportShopIds { get; set; } |
|||
|
|||
public string ErrorMessage { get; set; } |
|||
|
|||
public AuditCapitalType? AuditCapitalType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 自定义资金类型
|
|||
/// </summary>
|
|||
public string CustomAuditCapitalType { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class LogisticsResponse |
|||
{ |
|||
public string Id { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,72 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class ConsigneeResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 联系人名称
|
|||
/// </summary>
|
|||
public string ContactName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 座机
|
|||
/// </summary>
|
|||
public string TelePhone { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 手机
|
|||
/// </summary>
|
|||
public string Mobile { get; set; } |
|||
|
|||
public string Address { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 省
|
|||
/// </summary>
|
|||
public string Province { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 市
|
|||
/// </summary>
|
|||
public string City { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 县
|
|||
/// </summary>
|
|||
public string County { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 镇
|
|||
/// </summary>
|
|||
public string Town { get; set; } |
|||
|
|||
public bool IsDecode { get; set; } |
|||
} |
|||
|
|||
public class ConsigneeSimpleResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 联系人名称
|
|||
/// </summary>
|
|||
public string ContactName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 座机
|
|||
/// </summary>
|
|||
public string TelePhone { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 手机
|
|||
/// </summary>
|
|||
public string Mobile { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 地址
|
|||
/// </summary>
|
|||
public string Address { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 买家账号
|
|||
/// </summary>
|
|||
//public string BuyerAccount { get; set; }
|
|||
} |
|||
} |
@ -0,0 +1,118 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class ExportOrderResponse |
|||
{ |
|||
public string OrderId { get; set; } |
|||
|
|||
public DateTime OrderStartTime { get; set; } |
|||
|
|||
public string SkuIds { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 代发订单号
|
|||
/// </summary>
|
|||
public string PurchaseOrderIds { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单总额
|
|||
/// </summary>
|
|||
public decimal OrderTotalPrice { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 商品成本
|
|||
/// </summary>
|
|||
public decimal PurchaseSkuAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购运费
|
|||
/// </summary>
|
|||
public decimal PurchaseFreight { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 头程费用
|
|||
/// </summary>
|
|||
public decimal FirstFreight { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 仓储费
|
|||
/// </summary>
|
|||
public decimal StorageAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 发货快递费
|
|||
/// </summary>
|
|||
public decimal DeliveryExpressFreight { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 平台扣点金额
|
|||
/// </summary>
|
|||
public decimal PlatformCommissionAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 补差金额(用户支付)
|
|||
/// </summary>
|
|||
public decimal FreightPrice { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 总成本
|
|||
/// </summary>
|
|||
public decimal TotalCost { get; set; } |
|||
|
|||
public decimal Profit { get; set; } |
|||
|
|||
public decimal ProfitRatio { get; set; } |
|||
|
|||
public string ConsigneeStr { get; set; } |
|||
|
|||
public StorageType? StorageType { get; set; } |
|||
|
|||
public OrderState OrderState { get; set; } |
|||
|
|||
public string VenderRemark { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单货款金额
|
|||
/// </summary>
|
|||
public decimal OrderSellerPrice { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 实收金额
|
|||
/// </summary>
|
|||
public decimal ActualAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 用户应付金额
|
|||
/// </summary>
|
|||
public decimal OrderPayment { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 耗材费
|
|||
/// </summary>
|
|||
public decimal ConsumableAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 入仓操作费
|
|||
/// </summary>
|
|||
public decimal InStorageAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 出仓操作费
|
|||
/// </summary>
|
|||
public decimal OutStorageAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 刷单/空单号费
|
|||
/// </summary>
|
|||
public decimal SDOrderAmount { get; set; } = 0.00M; |
|||
|
|||
public override string ToString() |
|||
{ |
|||
//日期,店铺订单号,SKU编码,订单状态,仓储类型,代发下单单号,售价,商品成本,采购运费,头程费用,仓储服务费,快递费,耗材费,入仓操作费,出仓操作费,刷单/空单号费,平台扣点,补差金额,应付金额,实收金额,利润,利润率,收件人联系方式,商家备注,售后类型,售后与特殊情况备注
|
|||
return $"{OrderStartTime:yyyy-MM-dd HH:mm:ss},{OrderId},{SkuIds},{OrderState},{StorageType},{PurchaseOrderIds},{OrderTotalPrice},{PurchaseSkuAmount},{PurchaseFreight},{FirstFreight},{StorageAmount},{DeliveryExpressFreight},{ConsumableAmount},{InStorageAmount},{OutStorageAmount},{SDOrderAmount},{PlatformCommissionAmount},{FreightPrice},{OrderPayment},{ActualAmount},{Profit},{ProfitRatio},{ConsigneeStr},{VenderRemark}"; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,88 @@ |
|||
using System; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class OrderCostDetailResponse |
|||
{ |
|||
|
|||
public long Id { get; set; } |
|||
|
|||
|
|||
public DateTime? CreateTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 扣减数量
|
|||
/// </summary>
|
|||
public int DeductionQuantity { get; set; } = 0; |
|||
|
|||
/// <summary>
|
|||
/// 发货运费
|
|||
/// </summary>
|
|||
public decimal DeliveryExpressFreight { get; set; } = 0.00M; |
|||
|
|||
public string OrderId { get; set; } |
|||
|
|||
|
|||
public string ProductId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 单件成本
|
|||
/// </summary>
|
|||
public decimal UnitCost { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 采购单流水Id
|
|||
/// </summary>
|
|||
public long PurchaseOrderPKId { get; set; } |
|||
|
|||
public string SkuId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Sku成本(商品成本)
|
|||
/// </summary>
|
|||
public decimal SkuAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 采购运费
|
|||
/// </summary>
|
|||
public decimal PurchaseFreight { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 头程运费
|
|||
/// </summary>
|
|||
public decimal FirstFreight { get; set; } = 0.00M; |
|||
|
|||
|
|||
//public decimal OperationAmount { get; set; } = 0.00M;
|
|||
|
|||
/// <summary>
|
|||
/// 入仓操作费
|
|||
/// </summary>
|
|||
public decimal InStorageAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 出仓操作费
|
|||
/// </summary>
|
|||
public decimal OutStorageAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 耗材费
|
|||
/// </summary>
|
|||
public decimal ConsumableAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 仓储费
|
|||
/// </summary>
|
|||
public decimal StorageAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 总计(不含销售运费 历史遗留)
|
|||
/// </summary>
|
|||
public decimal TotalCost { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 总计 包含销售运费
|
|||
/// </summary>
|
|||
public decimal TotalCost2 { get; set; } = 0.00M; |
|||
} |
|||
} |
@ -0,0 +1,106 @@ |
|||
using System; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class OrderCostResponse |
|||
{ |
|||
|
|||
public string OrderId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 平台扣点金额
|
|||
/// </summary>
|
|||
public decimal PlatformCommissionAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 平台扣点百分比
|
|||
/// </summary>
|
|||
public decimal PlatformCommissionRatio { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 优惠金额
|
|||
/// </summary>
|
|||
public decimal PreferentialAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 毛利
|
|||
/// </summary>
|
|||
public decimal Profit { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 成本毛利率
|
|||
/// </summary>
|
|||
public decimal ProfitRatio |
|||
{ |
|||
get |
|||
{ |
|||
return TotalCost == 0 ? 0 : Math.Round(Profit / TotalCost * 100, 2); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 采购金额
|
|||
/// </summary>
|
|||
public decimal PurchaseAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 发货快递费
|
|||
/// </summary>
|
|||
public decimal DeliveryExpressFreight { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 是否手动编辑过成本
|
|||
/// </summary>
|
|||
public bool IsManualEdited { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 刷单佣金
|
|||
/// </summary>
|
|||
public decimal SDCommissionAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 刷单号费
|
|||
/// </summary>
|
|||
public decimal SDOrderAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 退款金额
|
|||
/// </summary>
|
|||
public decimal RefundAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 退款采购金额
|
|||
/// </summary>
|
|||
public decimal RefundPurchaseAmount { get; set; } = 0.0M; |
|||
|
|||
/// <summary>
|
|||
/// 售后总成本
|
|||
/// </summary>
|
|||
public decimal AfterTotalCost { get; set; } = 0.0M; |
|||
|
|||
/// <summary>
|
|||
/// 售前成本
|
|||
/// </summary>
|
|||
public decimal BeforeTotalCost |
|||
{ |
|||
get |
|||
{ |
|||
return PurchaseAmount + DeliveryExpressFreight; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 成本总计
|
|||
/// </summary>
|
|||
public decimal TotalCost |
|||
{ |
|||
get |
|||
{ |
|||
return SDCommissionAmount + SDOrderAmount + |
|||
PlatformCommissionAmount + (PurchaseAmount - RefundPurchaseAmount) + |
|||
DeliveryExpressFreight + |
|||
AfterTotalCost; |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,14 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class OrderCouponResponse |
|||
{ |
|||
public long Id { get; set; } |
|||
|
|||
public decimal CouponPrice { get; set; } |
|||
|
|||
public string CouponType { get; set; } |
|||
|
|||
public string OrderId { get; set; } |
|||
public string SkuId { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class OrderDropShippingResponse |
|||
{ |
|||
public long Id { get; set; } |
|||
|
|||
public string OrderId { get; set; } |
|||
|
|||
public string BuyerAccount { get; set; } |
|||
|
|||
public decimal DeliveryFreight { get; set; } |
|||
|
|||
public decimal PurchaseAmount { get; set; } |
|||
|
|||
public string PurchaseOrderId { get; set; } |
|||
|
|||
public string MerchantOrderId { get; set; } |
|||
|
|||
public Platform? PurchasePlatform { get; set; } |
|||
|
|||
public string SellerAccount { get; set; } |
|||
|
|||
public decimal SkuAmount |
|||
{ |
|||
get; set; |
|||
} |
|||
public decimal PurchaseFreight |
|||
{ |
|||
get; set; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,196 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class OrderResponse |
|||
{ |
|||
public string Id { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 商家Id
|
|||
/// </summary>
|
|||
public string VenderId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 下单时间
|
|||
/// </summary>
|
|||
public DateTime OrderStartTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 结单时间
|
|||
/// </summary>
|
|||
public DateTime? OrderEndTime { get; set; } |
|||
|
|||
public DateTime OrderModifyTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 买家账号
|
|||
/// </summary>
|
|||
public string BuyerAccount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单平台
|
|||
/// </summary>
|
|||
public Platform Platform { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单类型
|
|||
/// </summary>
|
|||
public OrderType OrderType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 支付方式
|
|||
/// </summary>
|
|||
public PayType PayType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单状态
|
|||
/// </summary>
|
|||
public OrderState OrderState { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单状态中文说明
|
|||
/// </summary>
|
|||
public string OrderStateText { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单总价
|
|||
/// </summary>
|
|||
public decimal OrderTotalPrice { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单货款金额
|
|||
/// </summary>
|
|||
public decimal OrderSellerPrice { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 用户应付金额
|
|||
/// </summary>
|
|||
public decimal OrderPayment { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 商品运费(用户付)
|
|||
/// </summary>
|
|||
public decimal FreightPrice { get; set; } |
|||
|
|||
public decimal PreferentialAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 买家备注
|
|||
/// </summary>
|
|||
public string BuyerRemark { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 商家备注
|
|||
/// </summary>
|
|||
public string VenderRemark { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购备注
|
|||
/// </summary>
|
|||
public string PurchaseRemark { get; set; } |
|||
|
|||
public StorageType? StorageType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 运单号
|
|||
/// </summary>
|
|||
public string WaybillNo { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 仓库Id
|
|||
/// </summary>
|
|||
public string StoreId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 仓库名称
|
|||
/// </summary>
|
|||
public string StoreName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单旗帜
|
|||
/// </summary>
|
|||
public string Flag { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 刷单类型
|
|||
/// </summary>
|
|||
public SDType? SDType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 刷单关键词
|
|||
/// </summary>
|
|||
public string SDKey { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 刷单支付渠道
|
|||
/// </summary>
|
|||
public PayBillType? SDPayChannel { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 刷单交易账单号
|
|||
/// </summary>
|
|||
public string SDPayBillNo { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 刷单人
|
|||
/// </summary>
|
|||
public string SDOperator { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否包含售后单
|
|||
/// </summary>
|
|||
public bool IsAfterSaleOrder { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 收货人信息
|
|||
/// </summary>
|
|||
public ConsigneeResponse Consignee { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单成本
|
|||
/// </summary>
|
|||
public OrderCostResponse OrderCost { get; set; } |
|||
|
|||
|
|||
public IList<OrderSkuResponse> ItemList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 优惠券列表
|
|||
/// </summary>
|
|||
public IList<OrderCouponResponse> OrderCouponList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单成本明细列表
|
|||
/// </summary>
|
|||
public IList<OrderCostDetailResponse> OrderCostDetailList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 代发信息
|
|||
/// </summary>
|
|||
public IList<OrderDropShippingResponse> OrderDropShippingList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 历史代发信息
|
|||
/// </summary>
|
|||
public IList<OrderDropShippingResponse> HistoryOrderDropShippingList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 售后信息
|
|||
/// </summary>
|
|||
public IList<AfterSaleOrderResponse> AfterSaleOrderList { get; set; } |
|||
} |
|||
|
|||
public class OrderListResponse |
|||
{ |
|||
public int Count { get; set; } |
|||
|
|||
public IList<OrderResponse> Items { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 当前条件汇总利润
|
|||
/// </summary>
|
|||
public decimal CurrentConditionsTotalProfit { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class OrderSkuResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 购买数量
|
|||
/// </summary>
|
|||
public int ItemTotal { get; set; } |
|||
|
|||
public string Id { get; set; } |
|||
|
|||
public string ProductId { get; set; } |
|||
|
|||
public string ProductNo { get; set; } |
|||
|
|||
public double Price { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Sku标题
|
|||
/// </summary>
|
|||
public string Title { get; set; } |
|||
|
|||
public string Logo { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 代发信息Id
|
|||
/// </summary>
|
|||
public long? OrderDropShippingId { get; set; } |
|||
|
|||
public bool IsRefund { get; set; } = false; |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class OrderBelongShopResponse |
|||
{ |
|||
public long ShopId { get; set; } |
|||
|
|||
public string ShopName { get; set; } |
|||
|
|||
public IList<string> OrderIdList { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class ProductListResponse |
|||
{ |
|||
public int Count { get; set; } |
|||
|
|||
public IList<Product> Items { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,25 @@ |
|||
using System; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class AuditPurchaseOrderResponse |
|||
{ |
|||
public long OrderDropShippingId { get; set; } |
|||
|
|||
public string PurchaseOrderId { get; set; } |
|||
|
|||
public string MerchantOrderId { get; set; } |
|||
|
|||
public long ShopId { get; set; } |
|||
|
|||
public decimal PurchaseAmount { get; set; } |
|||
|
|||
public string OrderId { get; set; } |
|||
|
|||
public DateTime? PurchaseTime { get; set; } |
|||
|
|||
public Platform? PurchasePlatform { get; set; } |
|||
|
|||
public DateTime? OrderStartTime { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class OrderTradeTypeResponse |
|||
{ |
|||
public string Code { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,30 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class PreviewOrderResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 总额
|
|||
/// </summary>
|
|||
public decimal TotalAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 货款总额
|
|||
/// </summary>
|
|||
public decimal ProductAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 运费
|
|||
/// </summary>
|
|||
public decimal FreightAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 交易方式
|
|||
/// </summary>
|
|||
public OrderTradeTypeResponse OrderTradeType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 扩展数据
|
|||
/// </summary>
|
|||
public string Extensions { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,83 @@ |
|||
using System; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class PurchaseOrderResponse |
|||
{ |
|||
public long Id { get; set; } |
|||
|
|||
public DateTime? CreateTime { get; set; } |
|||
|
|||
public string ProductId { get; set; } |
|||
|
|||
|
|||
public PurchaseMethod? PurchaseMethod { get; set; } |
|||
|
|||
public string PurchaseOrderId { get; set; } |
|||
|
|||
|
|||
public Platform? PurchasePlatform { get; set; } |
|||
|
|||
|
|||
public int PurchaseQuantity { get; set; } |
|||
|
|||
|
|||
public int RemainingQuantity { get; set; } |
|||
|
|||
public string SkuId { get; set; } |
|||
|
|||
public StorageType? StorageType { get; set; } |
|||
|
|||
public long ShopId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 单件发货运费
|
|||
/// </summary>
|
|||
public decimal SingleDeliveryFreight { get; set; } = 0.00M; |
|||
|
|||
///// <summary>
|
|||
///// 单件操作费
|
|||
///// </summary>
|
|||
//public decimal SingleOperationAmount { get; set; } = 0.00M;
|
|||
|
|||
/// <summary>
|
|||
/// 单件入仓操作费
|
|||
/// </summary>
|
|||
public decimal SingleInStorageAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 单件出仓操作费
|
|||
/// </summary>
|
|||
public decimal SingleOutStorageAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 单件耗材费
|
|||
/// </summary>
|
|||
public decimal SingleConsumableAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 单件仓储费
|
|||
/// </summary>
|
|||
public decimal SingleStorageAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 单件Sku成本
|
|||
/// </summary>
|
|||
public decimal SingleSkuAmount { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 单件采购运费
|
|||
/// </summary>
|
|||
public decimal SingleFreight { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 单件头程运费
|
|||
/// </summary>
|
|||
public decimal SingleFirstFreight { get; set; } = 0.00M; |
|||
|
|||
/// <summary>
|
|||
/// 退货入仓单价
|
|||
/// </summary>
|
|||
public decimal SingleRefundInStorageAmount { get; set; } = 0.00M; |
|||
} |
|||
} |
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public partial class PurchaseSchemeProductResponse |
|||
{ |
|||
public long Id { get; set; } |
|||
public DateTime? CreateTime { get; set; } |
|||
public string ProductId { get; set; } |
|||
public string PurchaseProductId { get; set; } |
|||
public string PurchaseUrl { get; set; } |
|||
public string SkuId { get; set; } |
|||
public long SkuPurchaseSchemeId { get; set; } |
|||
public long UserId { get; set; } |
|||
public List<PurchaseSchemeProductSkuResponse> PurchaseSchemeProductSkuList { get; set; } |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,18 @@ |
|||
using System; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public partial class PurchaseSchemeProductSkuResponse |
|||
{ |
|||
public long Id { get; set; } |
|||
public DateTime? CreateTime { get; set; } |
|||
public string ProductId { get; set; } |
|||
public string PurchaseProductId { get; set; } |
|||
public string PurchaseSkuId { get; set; } |
|||
public string PurchaseSkuSpecId { get; set; } |
|||
public string SkuId { get; set; } |
|||
public long SkuPurchaseSchemeId { get; set; } |
|||
public long UserId { get; set; } |
|||
} |
|||
|
|||
} |
@ -0,0 +1,38 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public partial class PurchaseSchemeResponse |
|||
{ |
|||
public long Id { get; set; } |
|||
public DateTime? CreateTime { get; set; } |
|||
/// <summary>
|
|||
/// 采购默认成本
|
|||
/// </summary>
|
|||
public decimal? DefaultCost { get; set; } |
|||
public string ProductId { get; set; } |
|||
/// <summary>
|
|||
/// 采购商Id
|
|||
/// </summary>
|
|||
public string PurchaserId { get; set; } |
|||
public string PurchaserName { get; set; } |
|||
/// <summary>
|
|||
/// 发货地
|
|||
/// </summary>
|
|||
public string PurchaserLocation { get; set; } |
|||
/// <summary>
|
|||
/// 采购实际成本
|
|||
/// </summary>
|
|||
public decimal? RealCost { get; set; } |
|||
public string SkuId { get; set; } |
|||
public long ShopId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购平台
|
|||
/// </summary>
|
|||
public Platform PurchasePlatform { get; set; } |
|||
|
|||
public List<PurchaseSchemeProductResponse> PurchaseSchemeProductList { get; set; } |
|||
} |
|||
|
|||
} |
@ -0,0 +1,11 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class WaiterResponse |
|||
{ |
|||
public string Id { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public string Level { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class PurchaseAccountResponse |
|||
{ |
|||
public long Id { get; set; } |
|||
|
|||
public string AccountName { get; set; } |
|||
|
|||
public long ShopId { get; set; } |
|||
|
|||
public Platform PurchasePlatformId { get; set; } |
|||
|
|||
public string AppKey { get; set; } |
|||
|
|||
public string AppSecret { get; set; } |
|||
|
|||
public string AppToken { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,18 @@ |
|||
using System; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
|
|||
public class ShopPopularizeResponse |
|||
{ |
|||
public decimal Cost { get; set; } = 0.0M; |
|||
|
|||
//public DateTime? Date { get; set; }
|
|||
|
|||
public string ItemName { get; set; } |
|||
|
|||
public long? ShopId { get; set; } |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,76 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class ShopResponse |
|||
{ |
|||
public string Id { get; set; } |
|||
|
|||
public Platform PlatformId { get; set; } |
|||
|
|||
public long? ShopId { get; set; } |
|||
|
|||
public string ShopName { get; set; } |
|||
|
|||
public string ShopType { get; set; } |
|||
|
|||
public string AppKey { get; set; } |
|||
|
|||
public string AppSecret { get; set; } |
|||
|
|||
public string AppToken { get; set; } |
|||
|
|||
public string AppKey2 { get; set; } |
|||
|
|||
public string AppSecret2 { get; set; } |
|||
|
|||
public string AppToken2 { get; set; } |
|||
|
|||
public IList<PurchaseAccountResponse> PurchaseList { get; set; } |
|||
|
|||
public string ManagePwd { get; set; } |
|||
|
|||
public decimal? PlatformCommissionRatio { get; set; } |
|||
|
|||
public string TeamId { get; set; } |
|||
|
|||
public string TeamName { get; set; } |
|||
|
|||
public string DingDingWebHook { get; set; } |
|||
|
|||
public string DingDingKey { get; set; } |
|||
|
|||
public int SkuSafeTurnoverDays { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 司南策略等级
|
|||
/// </summary>
|
|||
public int SiNanPolicyLevel { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 司南钉钉WebHook地址
|
|||
/// </summary>
|
|||
public string SiNanDingDingWebHook { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 司南钉钉密钥
|
|||
/// </summary>
|
|||
public string SiNanDingDingKey { get; set; } |
|||
} |
|||
|
|||
public class DepartmentResponse |
|||
{ |
|||
public string Id { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public IList<ShopResponse> ShopList { get; set; } |
|||
} |
|||
|
|||
public class DepartmentResponse2 |
|||
{ |
|||
public string DepartmentId { get; set; } |
|||
|
|||
public string DepartmentName { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class OrderCountStatisticsResponse |
|||
{ |
|||
public long WaitPurchaseCount { get; set; } |
|||
|
|||
public long ExceptionCount { get; set; } |
|||
|
|||
public long WaitOutStoreCount { get; set; } |
|||
|
|||
public long AfterSaleOrderUnhandleCount { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class SDGroupPersonStatisticsResponse |
|||
{ |
|||
public int MySDCount { get; set; } |
|||
|
|||
public decimal OrderPayment { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,12 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class SkuRecentSaleResponse |
|||
{ |
|||
public string SkuId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 销量
|
|||
/// </summary>
|
|||
public decimal SaleCount { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,80 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class ToDayOrderAchievementResponse |
|||
{ |
|||
|
|||
/// <summary>
|
|||
/// 销售额(用户实付)
|
|||
/// </summary>
|
|||
public decimal SaleAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 利润
|
|||
/// </summary>
|
|||
public decimal Profit { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 利润率
|
|||
/// </summary>
|
|||
public decimal ProfitRaito { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 订单数量
|
|||
/// </summary>
|
|||
public int OrderCount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购金额
|
|||
/// </summary>
|
|||
public decimal PurchaseAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 销售运费
|
|||
/// </summary>
|
|||
public decimal DeliveryExpressFreight { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 平台扣点
|
|||
/// </summary>
|
|||
public decimal PlatformCommissionAmount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 总成本
|
|||
/// </summary>
|
|||
public decimal TotalCost { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 广告统计(海投,快车,包含SD)
|
|||
/// </summary>
|
|||
public decimal AdvCost { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 人工成本
|
|||
/// </summary>
|
|||
public decimal EmployeeCost { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 税务成本
|
|||
/// </summary>
|
|||
public decimal TaxCost { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// SD成本
|
|||
/// </summary>
|
|||
public decimal SDCost { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 推广花费截至时间
|
|||
/// </summary>
|
|||
public DateTime? PularizeEndDate { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 推广成本明细
|
|||
/// </summary>
|
|||
public IList<ShopPopularizeResponse> ShoppopularizeList { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class MDSUserResponse |
|||
{ |
|||
public long Id { get; set; } |
|||
public string DepartmentName { get; set; } |
|||
public string DepartmentId { get; set; } |
|||
|
|||
public string UserName { get; set; } |
|||
|
|||
public string UserNick { get; set; } |
|||
|
|||
public IList<DepartmentResponse2> SonDepartmentList { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,214 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
/// <summary>
|
|||
/// 电商平台
|
|||
/// </summary>
|
|||
public enum Platform |
|||
{ |
|||
淘宝 = 0, |
|||
京东 = 1, |
|||
阿里巴巴 = 2, |
|||
拼多多 = 3, |
|||
微信 = 4, |
|||
拳探 = 10 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 采购方式
|
|||
/// </summary>
|
|||
public enum PurchaseMethod |
|||
{ |
|||
线上采购 = 0, |
|||
线下采购 = 1 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 采购单模式
|
|||
/// </summary>
|
|||
public enum PurchaseOrderMode |
|||
{ |
|||
批发 = 0, |
|||
代发 = 1 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 采购商品API模式
|
|||
/// </summary>
|
|||
public enum PurchaseProductAPIMode |
|||
{ |
|||
Spider = 0, |
|||
OneBound = 1 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 仓储类型
|
|||
/// </summary>
|
|||
public enum StorageType |
|||
{ |
|||
京仓 = 0, |
|||
云仓 = 1, |
|||
本地自发 = 2, |
|||
代发 = 3, |
|||
SD = 4 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 订单类型
|
|||
/// </summary>
|
|||
public enum OrderType |
|||
{ |
|||
#region JD订单类型
|
|||
SOP = 22, |
|||
LOC = 75, |
|||
FBP = 21 |
|||
#endregion
|
|||
|
|||
#region 拳探订单类型
|
|||
|
|||
#endregion
|
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 支付方式
|
|||
/// </summary>
|
|||
public enum PayType |
|||
{ |
|||
货到付款 = 1, |
|||
邮局汇款 = 2, |
|||
自提 = 3, |
|||
在线支付 = 4, |
|||
公司转账 = 5, |
|||
银行卡转账 = 6 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 订单状态
|
|||
/// </summary>
|
|||
public enum OrderState |
|||
{ |
|||
待付款 = 0, |
|||
等待采购 = 1, |
|||
待出库 = 2, |
|||
待收货 = 3, |
|||
已完成 = 4, |
|||
锁定 = 5, |
|||
已取消 = 6, |
|||
暂停 = 7, |
|||
已退款 = 8 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 刷单类型
|
|||
/// </summary>
|
|||
public enum SDType |
|||
{ |
|||
自刷 = 0, |
|||
其他 = 1, |
|||
京礼金 = 2, |
|||
刷单组 = 3 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 代发方式
|
|||
/// </summary>
|
|||
public enum DFType |
|||
{ |
|||
在线采购 = 0, |
|||
关联订单 = 1 |
|||
} |
|||
|
|||
public enum PayBillType |
|||
{ |
|||
支付宝 = 0, |
|||
微信 = 1, |
|||
银行卡 = 2 |
|||
} |
|||
|
|||
public enum AuditFileType |
|||
{ |
|||
账单 = 0, |
|||
采购单 = 1, |
|||
销售订单 = 2 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 账单矫正类型
|
|||
/// </summary>
|
|||
public enum BillCorrectionType |
|||
{ |
|||
销售运费账单 = 0, |
|||
入仓操作账单 = 1, |
|||
出仓操作账单 = 2 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 资金类型
|
|||
/// </summary>
|
|||
public enum AuditCapitalType |
|||
{ |
|||
当月商品采购 = 0, |
|||
当月商品退款 = 1, |
|||
上月商品采购 = 2, |
|||
上月商品退款 = 3, |
|||
批量采购商品 = 4, |
|||
采购运费 = 5, |
|||
入仓运费 = 6, |
|||
售后成本 = 7, |
|||
发票点数 = 8, |
|||
快递单号 = 9, |
|||
诚e赊还款 = 10, |
|||
空单号 = 11, |
|||
购买刷单号 = 12, |
|||
手机费 = 13, |
|||
质检报告 = 14, |
|||
备用金转入 = 15, |
|||
平台补贴 = 16, |
|||
快递赔付 = 17, |
|||
自定义 = 18, |
|||
备用金充值 = 19 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 服务单处理结果
|
|||
/// </summary>
|
|||
public enum ServiceResult |
|||
{ |
|||
退货 = 0, |
|||
换新 = 1, |
|||
原返 = 2, |
|||
线下换新 = 3, |
|||
维修 = 4, |
|||
商品补发 = 5, |
|||
仅退款 = 6, |
|||
SD退货 = 7 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 商品处理方式
|
|||
/// </summary>
|
|||
public enum ProductResult |
|||
{ |
|||
一件代发_退回厂家 = 0, |
|||
退回齐越仓 = 1, |
|||
退回京仓 = 2, |
|||
退回云仓 = 3, |
|||
客户无退货 = 4 |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 商品情况
|
|||
/// </summary>
|
|||
public enum ProductHealth |
|||
{ |
|||
可二次销售 = 0, |
|||
残次品_无法二次销售 = 1, |
|||
厂家退货退款 = 2, |
|||
客户无退货 = 3, |
|||
破损 = 4 |
|||
} |
|||
|
|||
public enum SiNanPolicyLevel |
|||
{ |
|||
初级策略, 中级策略, 高级策略 |
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class KVModel : NotifyObject |
|||
{ |
|||
public string Key { get; set; } |
|||
|
|||
public string Value { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,35 @@ |
|||
using AutoMapper; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class MappingProfile : Profile |
|||
{ |
|||
public MappingProfile() |
|||
{ |
|||
CreateMap<OrderDropShippingResponse, OrderDropShipping>(); |
|||
CreateMap<OrderCostDetailResponse, OrderCostDetail>(); |
|||
CreateMap<OrderCouponResponse, OrderCoupon>(); |
|||
CreateMap<OrderCostResponse, OrderCost>(); |
|||
CreateMap<ConsigneeResponse, Consignee>(); |
|||
CreateMap<AfterSaleOrderResponse, AfterSaleOrder>(); |
|||
CreateMap<OrderResponse, Order>(); |
|||
CreateMap<OrderSkuResponse, OrderSku>().ForMember(t => t.ProductItemNum, opt => opt.MapFrom(f => f.ProductNo)); |
|||
CreateMap<AuditPayBillResponse, AuditPayBill>(); |
|||
CreateMap<MDSUserResponse, User>().ForMember(t => t.TeamId, opt => opt.MapFrom(f => f.DepartmentId)) |
|||
.ForMember(t => t.TeamName, opt => opt.MapFrom(f => f.DepartmentName)) |
|||
.ForMember(t => t.Name, opt => opt.MapFrom(f => f.UserName)); |
|||
|
|||
CreateMap<ShopResponse, Shop>().ForMember(t => t.VenderType, opt => opt.MapFrom(f => f.ShopType)) |
|||
.ForMember(t => t.Platform, opt => opt.MapFrom(f => f.PlatformId)) |
|||
.ForMember(t => t.PurchaseAccountList, opt => opt.MapFrom(f => f.PurchaseList)); |
|||
|
|||
CreateMap<PurchaseAccountResponse, PurchaseAccount>(); |
|||
CreateMap<DepartmentResponse, Department>(); |
|||
|
|||
CreateMap<PurchaseOrderResponse, PurchaseOrder>(); |
|||
CreateMap<ToDayOrderAchievementResponse, ToDayOrderAchievement>(); |
|||
CreateMap<SDGroupPersonStatisticsResponse, SDGroupPersonStatistics>(); |
|||
CreateMap<BillCorrectionOrderResponse, BillCorrectionOrder>(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
using System.Collections.Generic; |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class MenuModel : NotifyObject |
|||
{ |
|||
private bool isSelected; |
|||
|
|||
|
|||
public bool IsSelected { get => isSelected; set { Set(ref isSelected, value); } } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public string Url { get; set; } |
|||
|
|||
public IList<MenuModel> ChildList { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
using System.ComponentModel; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class NotifyObject : INotifyPropertyChanged |
|||
{ |
|||
public event PropertyChangedEventHandler PropertyChanged; |
|||
protected void OnPropertyChanged([CallerMemberName]string propertyName = "") |
|||
{ |
|||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); |
|||
} |
|||
|
|||
protected bool Set<T>(ref T oldValue, T newValue, [CallerMemberName]string propertyName = "") |
|||
{ |
|||
if (Equals(oldValue, newValue)) |
|||
return false; |
|||
oldValue = newValue; |
|||
OnPropertyChanged(propertyName); |
|||
return true; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,62 @@ |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class Product : NotifyObject |
|||
{ |
|||
public Product() |
|||
{ |
|||
PurchaserList = new ObservableCollection<Purchaser>(); |
|||
PurchasePlatformList = new List<Platform>(); |
|||
} |
|||
|
|||
private Platform selectedPurchasePlatformModel; |
|||
|
|||
/// <summary>
|
|||
/// 商品Id
|
|||
/// </summary>
|
|||
public string Id { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 商品货号
|
|||
/// </summary>
|
|||
public string ProductItemNum { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 商品标题
|
|||
/// </summary>
|
|||
public string Title { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Sku列表
|
|||
/// </summary>
|
|||
public IList<ProductSku> SkuList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购商集合
|
|||
/// </summary>
|
|||
public IList<Purchaser> PurchaserList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购平台集合
|
|||
/// </summary>
|
|||
public IList<Platform> PurchasePlatformList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 选中的采购平台
|
|||
/// </summary>
|
|||
public Platform SelectedPurchasePlatformModel |
|||
{ |
|||
get => selectedPurchasePlatformModel; |
|||
set { Set(ref selectedPurchasePlatformModel, value); } |
|||
} |
|||
|
|||
public void CreatePlatformList() |
|||
{ |
|||
PurchasePlatformList.Add(Platform.阿里巴巴); |
|||
PurchasePlatformList.Add(Platform.拳探); |
|||
SelectedPurchasePlatformModel = PurchasePlatformList[0]; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,61 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Text; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class ProductSku : NotifyObject |
|||
{ |
|||
private PurchaseScheme selectedPurchaseScheme; |
|||
private StorageModel selectedStorageModel; |
|||
public string Id { get; set; } |
|||
|
|||
public string ProductId { get; set; } |
|||
|
|||
public double Price { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Sku标题
|
|||
/// </summary>
|
|||
public string Title { get; set; } |
|||
|
|||
public string Logo { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购方案
|
|||
/// </summary>
|
|||
public IList<PurchaseScheme> PurchaseSchemeList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购订单
|
|||
/// </summary>
|
|||
public IList<PurchaseOrder> PurchaseOrderList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 仓储平台
|
|||
/// </summary>
|
|||
public IList<StorageModel> StorageList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 选中的采购方案
|
|||
/// </summary>
|
|||
public PurchaseScheme SelectedPurchaseScheme |
|||
{ |
|||
get => selectedPurchaseScheme; |
|||
set { Set(ref selectedPurchaseScheme, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 选中的仓储平台
|
|||
/// </summary>
|
|||
public StorageModel SelectedStorageModel { get => selectedStorageModel; set { Set(ref selectedStorageModel, value); } } |
|||
|
|||
public ProductSku() |
|||
{ |
|||
PurchaseSchemeList = new ObservableCollection<PurchaseScheme>(); |
|||
PurchaseOrderList = new ObservableCollection<PurchaseOrder>(); |
|||
StorageList = new ObservableCollection<StorageModel>(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class PurchasePlatformModel |
|||
{ |
|||
public string ProductId { get; set; } |
|||
|
|||
public Platform PurchasePlatform { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,102 @@ |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
/// <summary>
|
|||
/// 采购方案
|
|||
/// </summary>
|
|||
public class PurchaseScheme : NotifyObject |
|||
{ |
|||
private decimal defaultCost; |
|||
private decimal realCost; |
|||
public long Id { get; set; } |
|||
|
|||
public long ShopId { get; set; } |
|||
public string ProductId { get; set; } |
|||
|
|||
public string SkuId { get; set; } |
|||
public decimal DefaultCost { get => defaultCost; set { Set(ref defaultCost, value); } } |
|||
public decimal RealCost { get => realCost; set { Set(ref realCost, value); } } |
|||
|
|||
public string PurchaserId { get; set; } |
|||
public string PurchaserName { get; set; } |
|||
public string PurchaserLocation { get; set; } |
|||
public string PurchaseProductId1 { get; set; } |
|||
public int PurchaseProductSkuCount1 { get; set; } |
|||
public string PurchaseProductId2 { get; set; } |
|||
public int PurchaseProductSkuCount2 { get; set; } |
|||
public string PurchaseProductId3 { get; set; } |
|||
public int PurchaseProductSkuCount3 { get; set; } |
|||
public string PurchaseProductId4 { get; set; } |
|||
public int PurchaseProductSkuCount4 { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购平台
|
|||
/// </summary>
|
|||
public Platform PurchasePlatform { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购方案的商品集合
|
|||
/// </summary>
|
|||
public IList<PurchaseSchemeProduct> PurchaseSchemeProductList { get; set; } |
|||
|
|||
public PurchaseScheme() |
|||
{ |
|||
PurchaseSchemeProductList = new ObservableCollection<PurchaseSchemeProduct>(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 是否转换方案中已选中的sku
|
|||
/// </summary>
|
|||
/// <param name="apiModel"></param>
|
|||
/// <param name="convertSelectedSku"></param>
|
|||
/// <returns></returns>
|
|||
public static PurchaseScheme Convert(PurchaseSchemeResponse apiModel) |
|||
{ |
|||
var model = new PurchaseScheme() |
|||
{ |
|||
Id = apiModel.Id, |
|||
ProductId = apiModel.ProductId, |
|||
SkuId = apiModel.SkuId, |
|||
DefaultCost = apiModel.DefaultCost ?? 0, |
|||
RealCost = apiModel.RealCost ?? 0, |
|||
PurchaserId = apiModel.PurchaserId, |
|||
PurchaserName = apiModel.PurchaserName, |
|||
PurchaserLocation = apiModel.PurchaserLocation, |
|||
PurchasePlatform = apiModel.PurchasePlatform |
|||
}; |
|||
|
|||
foreach (var apiProduct in apiModel.PurchaseSchemeProductList) |
|||
{ |
|||
model.PurchaseSchemeProductList.Add(PurchaseSchemeProduct.Convert(apiProduct)); |
|||
} |
|||
for (var i = 0; i < model.PurchaseSchemeProductList.Count; i++) |
|||
{ |
|||
var purchaseProductId = model.PurchaseSchemeProductList[i].PurchaseProductId; |
|||
var purchaseProductSkuCount = model.PurchaseSchemeProductList[i].PurchaseSkuCount; |
|||
if (i == 0) |
|||
{ |
|||
model.PurchaseProductId1 = purchaseProductId; |
|||
model.PurchaseProductSkuCount1 = purchaseProductSkuCount; |
|||
} |
|||
else if (i == 1) |
|||
{ |
|||
model.PurchaseProductId2 = purchaseProductId; |
|||
model.PurchaseProductSkuCount2 = purchaseProductSkuCount; |
|||
} |
|||
else if (i == 2) |
|||
{ |
|||
model.PurchaseProductId3 = purchaseProductId; |
|||
model.PurchaseProductSkuCount3 = purchaseProductSkuCount; |
|||
} |
|||
else if (i == 3) |
|||
{ |
|||
model.PurchaseProductId4 = purchaseProductId; |
|||
model.PurchaseProductSkuCount4 = purchaseProductSkuCount; |
|||
} |
|||
} |
|||
return model; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,89 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Text; |
|||
using System.Linq; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
/// <summary>
|
|||
/// 采购商品
|
|||
/// </summary>
|
|||
public class PurchaseSchemeProduct : NotifyObject |
|||
{ |
|||
|
|||
private string purchaseUrl; |
|||
private string purchaseProductId; |
|||
private bool isEditing; |
|||
private string searchPurchaseSkuName; |
|||
|
|||
/// <summary>
|
|||
/// 采购商品和采购方案的关系Id
|
|||
/// </summary>
|
|||
public long Id { get; set; } |
|||
|
|||
public string ProductId { get; set; } |
|||
|
|||
public string SkuId { get; set; } |
|||
|
|||
public string PurchaseUrl { get => purchaseUrl; set { Set(ref purchaseUrl, value); } } |
|||
public string PurchaseProductId { get => purchaseProductId; set => purchaseProductId = value; } |
|||
|
|||
public bool IsEditing |
|||
{ |
|||
get => isEditing; |
|||
set |
|||
{ |
|||
SearchPurchaseSkuName = string.Empty; |
|||
Set(ref isEditing, value); |
|||
} |
|||
} |
|||
|
|||
public IList<PurchaseSchemeProductSku> SkuList { get; set; } |
|||
|
|||
public IList<PurchaseSchemeProductSku> SearchSkuList { get; set; } |
|||
|
|||
public IList<PurchaseSchemeProductSku> PurchaseSchemeProductSkuList { get; set; } |
|||
|
|||
public List<string> SelectedSkuIdList { get; set; } |
|||
|
|||
public int PurchaseSkuCount |
|||
{ |
|||
get { return SelectedSkuIdList.Count(); } |
|||
} |
|||
|
|||
public string SearchPurchaseSkuName |
|||
{ |
|||
get => searchPurchaseSkuName; |
|||
set { Set(ref searchPurchaseSkuName, value); } |
|||
} |
|||
|
|||
public PurchaseSchemeProduct() |
|||
{ |
|||
SkuList = new ObservableCollection<PurchaseSchemeProductSku>(); |
|||
SearchSkuList = new ObservableCollection<PurchaseSchemeProductSku>(); |
|||
PurchaseSchemeProductSkuList = new ObservableCollection<PurchaseSchemeProductSku>(); |
|||
SelectedSkuIdList = new List<string>(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
/// <param name="apiModel"></param>
|
|||
/// <param name="convertSelectedSku">是否转换方案中已选的sku</param>
|
|||
/// <returns></returns>
|
|||
public static PurchaseSchemeProduct Convert(PurchaseSchemeProductResponse apiModel) |
|||
{ |
|||
var model = new PurchaseSchemeProduct() |
|||
{ |
|||
Id = apiModel.Id, |
|||
ProductId = apiModel.ProductId, |
|||
SkuId = apiModel.SkuId, |
|||
PurchaseProductId = apiModel.PurchaseProductId, |
|||
PurchaseUrl = apiModel.PurchaseUrl |
|||
}; |
|||
model.SelectedSkuIdList.AddRange(apiModel.PurchaseSchemeProductSkuList.Select(s => s.PurchaseSkuId)); |
|||
return model; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,57 @@ |
|||
using System; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
/// <summary>
|
|||
/// 采购商品的Sku
|
|||
/// </summary>
|
|||
public class PurchaseSchemeProductSku : NotifyObject |
|||
{ |
|||
/// <summary>
|
|||
/// 采购商品的SKU和采购方案的关系Id
|
|||
/// </summary>
|
|||
public long Id { get; set; } |
|||
|
|||
private bool isSelected; |
|||
public bool IsSelected { get => isSelected; set { Set(ref isSelected, value); } } |
|||
|
|||
public decimal Price { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Sku标题
|
|||
/// </summary>
|
|||
public string Title { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Sku图片
|
|||
/// </summary>
|
|||
public string Logo { get; set; } |
|||
|
|||
public string SkuId { get; set; } |
|||
public string ProductId { get; set; } |
|||
public string PurchaseProductId { get; set; } |
|||
public string PurchaseSkuId { get; set; } |
|||
public string PurchaseSkuSpecId { get; set; } |
|||
public long SkuPurchaseSchemeId { get; set; } |
|||
public long UserId { get; set; } |
|||
|
|||
public int ItemTotal |
|||
{ |
|||
get => itemTotal; set |
|||
{ |
|||
if (Set(ref itemTotal, value)) |
|||
{ |
|||
SkuAmount = value * Price; |
|||
OnItemTotalChanged?.Invoke(value); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public decimal SkuAmount { get => skuAmount; set { Set(ref skuAmount, value); } } |
|||
|
|||
private int itemTotal; |
|||
private decimal skuAmount; |
|||
|
|||
public Action<int> OnItemTotalChanged { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,25 @@ |
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
/// <summary>
|
|||
/// 采购商
|
|||
/// </summary>
|
|||
public class Purchaser : NotifyObject |
|||
{ |
|||
private int skuUseCount; |
|||
|
|||
public string Id { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 使用该采购商的SKU数量
|
|||
/// </summary>
|
|||
public int SkuUseCount { get => skuUseCount; set { Set(ref skuUseCount, value); } } |
|||
|
|||
public string ProductId { get; set; } |
|||
|
|||
public string Location { get; set; } |
|||
|
|||
public Platform Platform { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,37 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class Department : NotifyObject |
|||
{ |
|||
private bool isSelected; |
|||
|
|||
public string Id { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public IList<Shop> ShopList { get; set; } |
|||
public bool IsSelected |
|||
{ |
|||
get => isSelected; |
|||
set |
|||
{ |
|||
if (Set(ref isSelected, value)) |
|||
OnIsSelectedChanged?.Invoke(); |
|||
} |
|||
} |
|||
|
|||
public Department() |
|||
{ |
|||
ShopList = new List<Shop>(); |
|||
} |
|||
|
|||
public Action OnIsSelectedChanged { get; set; } |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return this.Name; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
using System; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class PurchaseAccount : NotifyObject,ICloneable |
|||
{ |
|||
private string accountName; |
|||
private Platform purchasePlatformId; |
|||
private string appKey; |
|||
private string appSecret; |
|||
private string appToken; |
|||
|
|||
public long Id { get; set; } |
|||
|
|||
public long ShopId { get; set; } |
|||
public string AccountName { get => accountName; set { Set(ref accountName, value); } } |
|||
public Platform PurchasePlatformId { get => purchasePlatformId; set { Set(ref purchasePlatformId, value); } } |
|||
public string AppKey { get => appKey; set { Set(ref appKey, value); } } |
|||
public string AppSecret { get => appSecret; set { Set(ref appSecret, value); } } |
|||
public string AppToken { get => appToken; set { Set(ref appToken, value); } } |
|||
|
|||
public object Clone() |
|||
{ |
|||
return this.MemberwiseClone(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,78 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class Shop : NotifyObject |
|||
{ |
|||
private bool isSelected; |
|||
private string shopName; |
|||
|
|||
public bool IsSelected { get => isSelected; set { Set(ref isSelected, value); } } |
|||
/// <summary>
|
|||
/// 店铺Id
|
|||
/// </summary>
|
|||
public long ShopId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 商家类型
|
|||
/// </summary>
|
|||
public string VenderType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 店铺平台
|
|||
/// </summary>
|
|||
public Platform Platform { get; set; } |
|||
|
|||
public string AppKey { get; set; } |
|||
|
|||
public string AppSecret { get; set; } |
|||
|
|||
public string AppToken { get; set; } |
|||
|
|||
public string AppKey2 { get; set; } |
|||
|
|||
public string AppSecret2 { get; set; } |
|||
|
|||
public string AppToken2 { get; set; } |
|||
|
|||
public string ShopName { get => shopName; set { Set(ref shopName, value); } } |
|||
|
|||
public IList<PurchaseAccount> PurchaseAccountList { get; set; } |
|||
|
|||
public string ManagePwd { get; set; } |
|||
/// <summary>
|
|||
/// 店铺扣点
|
|||
/// </summary>
|
|||
public decimal? PlatformCommissionRatio { get; set; } |
|||
|
|||
public string TeamId { get; set; } |
|||
|
|||
public string TeamName { get; set; } |
|||
|
|||
public string DingDingWebHook { get; set; } |
|||
|
|||
public string DingDingKey { get; set; } |
|||
|
|||
public int SkuSafeTurnoverDays { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 司南策略等级
|
|||
/// </summary>
|
|||
public int SiNanPolicyLevel { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 司南钉钉WebHook地址
|
|||
/// </summary>
|
|||
public string SiNanDingDingWebHook { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 司南钉钉密钥
|
|||
/// </summary>
|
|||
public string SiNanDingDingKey { get; set; } |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return ShopName; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
|
|||
namespace BBWYB.Client.Models |
|||
{ |
|||
public class User : NotifyObject |
|||
{ |
|||
//private string name;
|
|||
|
|||
private Shop shop; |
|||
|
|||
public long Id { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public string TeamId { get; set; } |
|||
|
|||
public string TeamName { get; set; } |
|||
|
|||
public string SonDepartmentNames { get; set; } |
|||
|
|||
public Shop Shop { get => shop; set { Set(ref shop, value); } } |
|||
|
|||
public IList<Department> DepartmentList { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 店铺列表 (暂时只有刷单组才需要)
|
|||
/// </summary>
|
|||
public IList<Shop> ShopList { get; set; } |
|||
|
|||
} |
|||
} |
After Width: | Height: | Size: 915 B |
After Width: | Height: | Size: 6.4 KiB |
@ -0,0 +1,34 @@ |
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
|||
<!--Generic--> |
|||
<SolidColorBrush x:Key="WindowButtonColor" Color="Black"/> |
|||
<SolidColorBrush x:Key="Item.MouseOver" Color="#E6E6E6"/> |
|||
<SolidColorBrush x:Key="Item.Selected" Color="#E6E6E6"/> |
|||
|
|||
<SolidColorBrush x:Key="ScrollBar.Background" Color="#D8D8D8"/> |
|||
<SolidColorBrush x:Key="ScrollBar.Background.MouseOver" Color="#FFC8C7C7"/> |
|||
|
|||
<SolidColorBrush x:Key="Text.Color" Color="#4A4A4A"/> |
|||
<SolidColorBrush x:Key="TextBox.BorderBrush" Color="#D7D7D7"/> |
|||
<SolidColorBrush x:Key="TextBox.Disable.BgColor" Color="#F2F2F2"/> |
|||
|
|||
<SolidColorBrush x:Key="Text.Link.Color" Color="#02A7F0"/> |
|||
|
|||
<SolidColorBrush x:Key="Border.Brush" Color="#D7D7D7"/> |
|||
|
|||
<SolidColorBrush x:Key="PathColor" Color="#02A7F0"/> |
|||
|
|||
<SolidColorBrush x:Key="LoadingColor" Color="#8080FF"/> |
|||
|
|||
<SolidColorBrush x:Key="Border.Background" Color="#F2F2F2"/> |
|||
|
|||
<SolidColorBrush x:Key="Button.Selected.Background" Color="#8080FF"/> |
|||
<SolidColorBrush x:Key="Button.Normal.Background" Color="#F2F2F2"/> |
|||
|
|||
<!--Main--> |
|||
<SolidColorBrush x:Key="MainMenu.BackGround" Color="#F2F2F2"/> |
|||
<SolidColorBrush x:Key="MainMenu.BorderBrush" Color="#D7D7D7"/> |
|||
|
|||
<SolidColorBrush x:Key="Text.Pink" Color="#EC808D"/> |
|||
|
|||
</ResourceDictionary> |
@ -0,0 +1,4 @@ |
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
|||
|
|||
</ResourceDictionary> |
@ -0,0 +1,417 @@ |
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:c="clr-namespace:SJ.Controls;assembly=SJ.Controls"> |
|||
<Style x:Key="bwstyle" TargetType="c:BWindow"> |
|||
<Setter Property="MaxButtonColor" Value="{StaticResource WindowButtonColor}"/> |
|||
<Setter Property="MinButtonColor" Value="{StaticResource WindowButtonColor}"/> |
|||
<Setter Property="CloseButtonColor" Value="{StaticResource WindowButtonColor}"/> |
|||
<Setter Property="RightButtonGroupMargin" Value="0,5,5,0"/> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type ListBox}"> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/> |
|||
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="auto"/> |
|||
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/> |
|||
<Setter Property="ScrollViewer.PanningMode" Value="Both"/> |
|||
<Setter Property="VerticalContentAlignment" Value="Center"/> |
|||
<Setter Property="UseLayoutRounding" Value="True"/> |
|||
<Setter Property="SnapsToDevicePixels" Value="True"/> |
|||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/> |
|||
<Setter Property="Margin" Value="0,0,0,0"/> |
|||
<Setter Property="Padding" Value="0,0,0,0"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type ListBox}"> |
|||
<Border x:Name="Bd" |
|||
Background="{TemplateBinding Background}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" |
|||
UseLayoutRounding="{TemplateBinding UseLayoutRounding}"> |
|||
<ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}"> |
|||
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> |
|||
</ScrollViewer> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<MultiTrigger> |
|||
<MultiTrigger.Conditions> |
|||
<Condition Property="IsGrouping" Value="true"/> |
|||
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/> |
|||
</MultiTrigger.Conditions> |
|||
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/> |
|||
</MultiTrigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style x:Key="NoScrollViewListBoxStyle" TargetType="{x:Type ListBox}"> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/> |
|||
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="auto"/> |
|||
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/> |
|||
<Setter Property="ScrollViewer.PanningMode" Value="Both"/> |
|||
<Setter Property="VerticalContentAlignment" Value="Center"/> |
|||
<Setter Property="UseLayoutRounding" Value="True"/> |
|||
<Setter Property="SnapsToDevicePixels" Value="True"/> |
|||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/> |
|||
<Setter Property="Margin" Value="0,0,0,0"/> |
|||
<Setter Property="Padding" Value="0,0,0,0"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type ListBox}"> |
|||
<Border x:Name="Bd" |
|||
Background="{TemplateBinding Background}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" |
|||
UseLayoutRounding="{TemplateBinding UseLayoutRounding}" |
|||
Padding="{TemplateBinding Padding}"> |
|||
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<MultiTrigger> |
|||
<MultiTrigger.Conditions> |
|||
<Condition Property="IsGrouping" Value="true"/> |
|||
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/> |
|||
</MultiTrigger.Conditions> |
|||
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/> |
|||
</MultiTrigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style x:Key="NoBgListBoxItemStyle" TargetType="{x:Type ListBoxItem}"> |
|||
<Setter Property="SnapsToDevicePixels" Value="True"/> |
|||
<Setter Property="Padding" Value="0"/> |
|||
<Setter Property="Margin" Value="0"/> |
|||
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ItemsControl}}}"/> |
|||
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ItemsControl}}}"/> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
<Setter Property="BorderBrush" Value="Transparent"/> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type ListBoxItem}"> |
|||
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True"> |
|||
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" |
|||
Content="{TemplateBinding Content}" Margin="{TemplateBinding Margin}" |
|||
ContentStringFormat="{TemplateBinding ContentStringFormat}" |
|||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" |
|||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" |
|||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" |
|||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style x:Key="DefaultListBoxItemStyle" TargetType="{x:Type ListBoxItem}"> |
|||
<Setter Property="SnapsToDevicePixels" Value="True"/> |
|||
<Setter Property="Padding" Value="0"/> |
|||
<Setter Property="Margin" Value="0"/> |
|||
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ItemsControl}}}"/> |
|||
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ItemsControl}}}"/> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
<Setter Property="BorderBrush" Value="Transparent"/> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type ListBoxItem}"> |
|||
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True"> |
|||
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" |
|||
Content="{TemplateBinding Content}" Margin="{TemplateBinding Margin}" |
|||
ContentStringFormat="{TemplateBinding ContentStringFormat}" |
|||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" |
|||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" |
|||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" |
|||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsMouseOver" Value="True"> |
|||
<Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.MouseOver}"/> |
|||
</Trigger> |
|||
<Trigger Property="IsSelected" Value="True"> |
|||
<Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.Selected}"/> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type c:BButton}"> |
|||
<Setter Property="Height" Value="30"/> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="Background" Value="{StaticResource Button.Selected.Background}"/> |
|||
<Setter Property="Foreground" Value="White"/> |
|||
</Style> |
|||
|
|||
<Style x:Key="LinkButton" TargetType="{x:Type c:BButton}"> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
<Setter Property="Foreground" Value="{StaticResource Text.Link.Color}"/> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type c:BTextBox}"> |
|||
<Setter Property="Height" Value="30"/> |
|||
<Setter Property="Background" Value="White"/> |
|||
<Setter Property="BorderBrush" Value="{StaticResource TextBox.BorderBrush}"/> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type c:RoundWaitProgress}"> |
|||
<Setter Property="Color" Value="{StaticResource LoadingColor}"/> |
|||
<Setter Property="Background" Value="#26000000"/> |
|||
<Setter Property="Foreground" Value="{StaticResource LoadingColor}"/> |
|||
</Style> |
|||
|
|||
<!--滚动条颜色、圆角等设置--> |
|||
<Style x:Key="ScrollBarThumb" TargetType="{x:Type Thumb}"> |
|||
<Setter Property="OverridesDefaultStyle" Value="true"/> |
|||
<Setter Property="IsTabStop" Value="false"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type Thumb}"> |
|||
<!--滚动条颜色和圆角设置--> |
|||
<Rectangle Name="thumbRect" Fill="{StaticResource ScrollBar.Background}" RadiusX="3" RadiusY="3"/> |
|||
<!--鼠标拉动滚动条时的颜色--> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsMouseOver" Value="True"> |
|||
<Setter Property="Fill" Value="{StaticResource ScrollBar.Background.MouseOver}" TargetName="thumbRect" /> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style x:Key="VerticalScrollBarStyle" TargetType="{x:Type ScrollBar}"> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/> |
|||
<Setter Property="Stylus.IsFlicksEnabled" Value="false"/> |
|||
<!--滚动条宽度--> |
|||
<Setter Property="Width" Value="6"/> |
|||
<Setter Property="MinWidth" Value="6"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type ScrollBar}"> |
|||
<!--滚动条背景色--> |
|||
<Border x:Name="Bg" Background="{TemplateBinding Background}" SnapsToDevicePixels="true" Width="6" CornerRadius="4"> |
|||
<Track x:Name="PART_Track" IsDirectionReversed="true" IsEnabled="{TemplateBinding IsMouseOver}"> |
|||
<Track.Thumb> |
|||
<Thumb Style="{StaticResource ScrollBarThumb}"/> |
|||
</Track.Thumb> |
|||
</Track> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style x:Key="HorizontalScrollBarStyle" TargetType="{x:Type ScrollBar}"> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/> |
|||
<Setter Property="Stylus.IsFlicksEnabled" Value="false"/> |
|||
<!--滚动条宽度--> |
|||
<Setter Property="Height" Value="6"/> |
|||
<Setter Property="MinHeight" Value="6"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type ScrollBar}"> |
|||
<!--滚动条背景色--> |
|||
<Border x:Name="Bg" Background="{TemplateBinding Background}" SnapsToDevicePixels="true" Height="6" CornerRadius="4"> |
|||
<Track x:Name="PART_Track" IsDirectionReversed="false" IsEnabled="{TemplateBinding IsMouseOver}"> |
|||
<Track.Thumb> |
|||
<Thumb Style="{StaticResource ScrollBarThumb}"/> |
|||
</Track.Thumb> |
|||
</Track> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="ScrollViewer"> |
|||
<Setter Property="VirtualizingPanel.IsVirtualizing" Value="True"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type ScrollViewer}"> |
|||
<Grid x:Name="Grid" Background="{TemplateBinding Background}"> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition Width="*"/> |
|||
<ColumnDefinition Width="Auto"/> |
|||
</Grid.ColumnDefinitions> |
|||
<Grid.RowDefinitions> |
|||
<RowDefinition Height="*"/> |
|||
<RowDefinition Height="Auto"/> |
|||
</Grid.RowDefinitions> |
|||
<Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/> |
|||
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/> |
|||
<ScrollBar Margin="-6 0 0 0" x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}" Opacity="0.5" Style="{StaticResource VerticalScrollBarStyle}"/> |
|||
<ScrollBar Margin="0 -6 0 0" x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}" Opacity="0.5" Style="{StaticResource HorizontalScrollBarStyle}"/> |
|||
</Grid> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsMouseOver" Value="True"> |
|||
<Setter Property="Opacity" TargetName="PART_VerticalScrollBar" Value="1"/> |
|||
<Setter Property="Opacity" TargetName="PART_HorizontalScrollBar" Value="1"/> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="CheckBox"> |
|||
<Setter Property="VerticalContentAlignment" Value="Center"/> |
|||
<Setter Property="Foreground" Value="{StaticResource Text.Color}"/> |
|||
</Style> |
|||
|
|||
<Style x:Key="middleTextBlock" TargetType="TextBlock"> |
|||
<Setter Property="HorizontalAlignment" Value="Center"/> |
|||
<Setter Property="VerticalAlignment" Value="Center"/> |
|||
</Style> |
|||
<Style x:Key="verticalCenterTextBlock" TargetType="TextBlock"> |
|||
<Setter Property="VerticalAlignment" Value="Center"/> |
|||
</Style> |
|||
|
|||
<Style TargetType="DataGrid"> |
|||
<Setter Property="AutoGenerateColumns" Value="False"/> |
|||
<Setter Property="IsReadOnly" Value="True"/> |
|||
<Setter Property="RowHeaderWidth" Value="0"/> |
|||
<Setter Property="ColumnHeaderHeight" Value="30"/> |
|||
<Setter Property="RowHeight" Value="30"/> |
|||
<Setter Property="CanUserAddRows" Value="False"/> |
|||
<Setter Property="CanUserDeleteRows" Value="False"/> |
|||
<Setter Property="CanUserResizeRows" Value="False"/> |
|||
<Setter Property="CanUserSortColumns" Value="False"/> |
|||
<Setter Property="BorderBrush" Value="#E3F3FF"/> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="HorizontalGridLinesBrush" Value="{StaticResource Border.Brush}"/> |
|||
<Setter Property="VerticalGridLinesBrush" Value="{StaticResource Border.Brush}"/> |
|||
</Style> |
|||
|
|||
<Style TargetType="DataGridRow"> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
<Style.Triggers> |
|||
<Trigger Property="IsSelected" Value="True"> |
|||
<Setter Property="Background" Value="{StaticResource Item.Selected}"/> |
|||
<Setter Property="Foreground" Value="{StaticResource Text.Color}"/> |
|||
</Trigger> |
|||
<Trigger Property="IsMouseOver" Value="True"> |
|||
<Setter Property="Background" Value="{StaticResource Item.MouseOver}"/> |
|||
<Setter Property="Foreground" Value="{StaticResource Text.Color}"/> |
|||
</Trigger> |
|||
</Style.Triggers> |
|||
</Style> |
|||
|
|||
<Style TargetType="DataGridCell"> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
<Setter Property="Margin" Value="0"/> |
|||
<Setter Property="Padding" Value="0"/> |
|||
<Style.Triggers> |
|||
<Trigger Property="IsSelected" Value="True"> |
|||
<Setter Property="Background" Value="{StaticResource Item.Selected}"/> |
|||
<Setter Property="Foreground" Value="{StaticResource Text.Color}"/> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
</Trigger> |
|||
<Trigger Property="IsMouseOver" Value="True"> |
|||
<Setter Property="Background" Value="{StaticResource Item.MouseOver}"/> |
|||
<Setter Property="Foreground" Value="{StaticResource Text.Color}"/> |
|||
</Trigger> |
|||
</Style.Triggers> |
|||
</Style> |
|||
|
|||
<Style x:Key="ColumnHeaderStyle_Center" TargetType="DataGridColumnHeader"> |
|||
<Setter Property="SnapsToDevicePixels" Value="True" /> |
|||
<Setter Property="BorderThickness" Value="0,0,1,1"/> |
|||
<Setter Property="BorderBrush" Value="{StaticResource Border.Brush}"/> |
|||
<Setter Property="Background" Value="{StaticResource Border.Background}"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="DataGridColumnHeader"> |
|||
<Border x:Name="BackgroundBorder" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
Background="{TemplateBinding Background}" |
|||
Width="{TemplateBinding Width}"> |
|||
<Grid > |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition Width="*" /> |
|||
</Grid.ColumnDefinitions> |
|||
<ContentPresenter Margin="0" VerticalAlignment="Center" HorizontalAlignment="Center"/> |
|||
<Path x:Name="SortArrow" Visibility="Collapsed" Data="M0,0 L1,0 0.5,1 z" Stretch="Fill" Grid.Column="2" Width="8" Height="6" Fill="White" Margin="0,0,50,0" |
|||
VerticalAlignment="Center" RenderTransformOrigin="1,1" /> |
|||
|
|||
</Grid> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="DataGridColumnHeader"> |
|||
<Setter Property="SnapsToDevicePixels" Value="True" /> |
|||
<Setter Property="BorderThickness" Value="0,0,1,1"/> |
|||
<Setter Property="BorderBrush" Value="{StaticResource Border.Brush}"/> |
|||
<Setter Property="Background" Value="{StaticResource Border.Background}"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="DataGridColumnHeader"> |
|||
<Border x:Name="BackgroundBorder" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
Background="{TemplateBinding Background}" |
|||
Width="{TemplateBinding Width}"> |
|||
<Grid > |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition Width="*" /> |
|||
</Grid.ColumnDefinitions> |
|||
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,0,0,0"/> |
|||
<Path x:Name="SortArrow" Visibility="Collapsed" Data="M0,0 L1,0 0.5,1 z" Stretch="Fill" Grid.Column="2" Width="8" Height="6" Fill="White" Margin="0,0,50,0" |
|||
VerticalAlignment="Center" RenderTransformOrigin="1,1" /> |
|||
|
|||
<Thumb x:Name="PART_RightHeaderGripper" |
|||
Cursor="SizeWE" |
|||
HorizontalAlignment="Right" |
|||
Width="3" |
|||
VerticalAlignment="Stretch" |
|||
Background="#02F5F5F1" |
|||
Margin="0,0,-0.8,0"> |
|||
<Thumb.Style> |
|||
<Style TargetType="Thumb"> |
|||
<Setter Property="OverridesDefaultStyle" Value="true"/> |
|||
<Setter Property="IsTabStop" Value="false"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type Thumb}"> |
|||
<Rectangle Name="thumbRect" Fill="{TemplateBinding Background}"/> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
</Thumb.Style> |
|||
</Thumb> |
|||
</Grid> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style x:Key="OrderCouponToolipStyle" TargetType="{x:Type ToolTip}"> |
|||
<!--<Setter Property="Foreground" Value="White"/>--> |
|||
<Setter Property="HorizontalOffset" Value="10"/> |
|||
<Setter Property="VerticalOffset" Value="10"/> |
|||
<Setter Property="Background" Value="White"/> |
|||
</Style> |
|||
</ResourceDictionary> |
@ -0,0 +1,44 @@ |
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
|||
<Style x:Key="basePath" TargetType="Path"> |
|||
<Setter Property="Stretch" Value="Uniform"/> |
|||
<Setter Property="UseLayoutRounding" Value="True"/> |
|||
<Setter Property="SnapsToDevicePixels" Value="True"/> |
|||
<Setter Property="HorizontalAlignment" Value="Center"/> |
|||
<Setter Property="VerticalAlignment" Value="Center"/> |
|||
<Setter Property="Fill" Value="{StaticResource PathColor}"/> |
|||
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"/> |
|||
<Setter Property="Cursor" Value="Hand"/> |
|||
</Style> |
|||
|
|||
<Style x:Key="path_add" TargetType="Path" BasedOn="{StaticResource basePath}"> |
|||
<Setter Property="Data" Value="M12.126984,0L19.872009,0 19.872009,12.128 32,12.128 32,19.872999 19.872009,19.872999 19.872009,31.999 12.126984,31.999 12.126984,19.872999 0,19.872999 0,12.128 12.126984,12.128z"/> |
|||
</Style> |
|||
|
|||
<Style x:Key="path_question" TargetType="Path" BasedOn="{StaticResource basePath}"> |
|||
<Setter Property="Data" Value="M14.580002,23.394012L14.580002,26.235001 17.18399,26.235001 17.18399,23.394012z M16.117996,5.7660065C14.539993,5.7660065 13.278992,6.2390137 12.332993,7.1880035 10.991989,8.5250092 10.320999,10.223007 10.320999,12.27301L13.043991,12.27301C13.043991,10.695007 13.437988,9.5130005 14.22699,8.7230072 14.697998,8.25 15.289001,8.0130005 16,8.0130005 16.867996,8.0130005 17.537003,8.25 18.009995,8.7230072 18.561996,9.2750092 18.838989,10.106003 18.838989,11.207001 18.838989,12.077011 18.522995,12.827011 17.89299,13.455002 16.789001,14.561005 16.039001,15.429001 15.644989,16.061005 15.090988,16.92601 14.817001,18.228012 14.817001,19.964005L16.947998,19.964005C16.947998,18.545013 17.302002,17.478012 18.009995,16.767014 18.955994,15.824005 19.705994,15.074005 20.259995,14.522003 21.205002,13.574005 21.679001,12.432007 21.679001,11.090012 21.679001,9.5130005 21.166,8.2109985 20.14299,7.1880035 19.194992,6.2390137 17.853989,5.7660065 16.117996,5.7660065z M16,0C24.819992,0 32,7.178009 32,16.001007 32,24.822006 24.819992,32 16,32 7.1759949,32 0,24.822006 0,16.001007 0,7.178009 7.1759949,0 16,0z"/> |
|||
</Style> |
|||
|
|||
<Style x:Key="path_flag" TargetType="Path" BasedOn="{StaticResource basePath}"> |
|||
<Setter Property="Data" Value="M1.9000015,1.4000239L7.6999969,31.300008 5.8000031,31.700002 0,1.8000178z M9.5999985,0C17.300003,1.653807E-07,28.699997,2.1000055,28.699997,2.1000057L26,11.100002 32,20.400018C14.800003,15.999994,6.6999969,18.999993,6.6999969,18.999993L3.1999969,1.2000117C4.1999969,0.30001835,6.5999985,1.653807E-07,9.5999985,0z"/> |
|||
</Style> |
|||
|
|||
<Style x:Key="path_close" TargetType="Path" BasedOn="{StaticResource basePath}"> |
|||
<Setter Property="Data" Value="M814.060 781.227q-67.241-67.241-269.773-269.773 67.241-67.241 269.773-269.773 5.671-6.481 5.671-12.962 0 0-0.81-0.81 0-6.481-4.861-9.722-4.861-4.051-11.342-4.861-0.81 0-0.81 0-5.671 0-11.342 4.861-89.924 89.924-269.773 269.773-67.241-67.241-269.773-269.773-4.861-4.861-12.962-4.861-7.291 0.81-10.532 4.861-5.671 5.671-5.671 11.342 0 6.481 5.671 12.152 89.924 89.924 269.773 269.773-67.241 67.241-269.773 269.773-11.342 11.342 0 23.494 12.152 11.342 23.494 0 89.924-89.924 269.773-269.773 67.241 67.241 269.773 269.773 5.671 5.671 11.342 5.671 5.671 0 12.152-5.671 4.861-5.671 4.861-12.962 0-6.481-4.861-10.532z"/> |
|||
</Style> |
|||
|
|||
<Style x:Key="path_input" TargetType="Path" BasedOn="{StaticResource basePath}"> |
|||
<Setter Property="Data" Value="M4.234565,23.060143L3.3980846,26.498995 5.6062109,28.670895 9.1839902,27.854559z M20.369981,6.6974076L5.4623272,21.465012 10.698205,26.536911 25.463305,11.631243z M24.268012,2.8359963L21.791127,5.2896117 26.870864,10.210285 29.195014,7.8640078z M24.290015,0L32.002999,7.8720034 10.464999,29.613993 0,31.999001 2.5469978,21.53801z"/> |
|||
</Style> |
|||
|
|||
<Style x:Key="path_list" TargetType="Path" BasedOn="{StaticResource basePath}"> |
|||
<Setter Property="Data" Value="M8,23.000008L32,23.000008 32,25.000008 8,25.000008z M0,22L4,22 4,26 0,26z M8,12L32,12 32,14 8,14z M0,11L4,11 4,15 0,15z M8,1L32,1 32,3 8,3z M0,0L4,0 4,4 0,4z"/> |
|||
</Style> |
|||
|
|||
<Style x:Key="path_arrowDown" TargetType="Path" BasedOn="{StaticResource basePath}"> |
|||
<Setter Property="Data" Value="M32,0L32,8.4920026 21.291016,17.120999 21.200989,17.195005 21.247009,17.232999 15.978027,21.478999 10.708008,17.232999 0,8.6020032 0,0.11100769 12.151001,9.904997 15.93103,12.947995 16.020996,12.874997 19.846008,9.7920056z"/> |
|||
</Style> |
|||
<Style x:Key="path_refresh" TargetType="Path" BasedOn="{StaticResource basePath}"> |
|||
<Setter Property="Data" Value="M1.6819987,14.044979L9.8970004,17.370966 6.3769976,19.284967C8.2400037,22.789972 11.896001,25.193962 16.141995,25.193962 20.631998,25.193962 24.487993,22.521967 26.233004,18.687982L29.466995,18.687982C27.558001,24.216972 22.313997,28.208 16.141995,28.208 10.761998,28.208 6.0890032,25.17498 3.7130042,20.731012L0,22.747003z M16.141995,0C21.460993,1.3985937E-07,26.084002,2.9670097,28.485001,7.3259868L32,5.3049912 30.530991,14.044979 22.236994,10.916013 25.860003,8.8339815C23.983004,5.3789963 20.351999,3.0140068 16.141995,3.0140066 11.653997,3.0140068 7.7980023,5.6860031 6.0520006,9.518979L2.8189999,9.518979C4.7280031,3.9899892,9.9719973,1.3985937E-07,16.141995,0z"/> |
|||
</Style> |
|||
</ResourceDictionary> |
@ -0,0 +1,12 @@ |
|||
{ |
|||
"version": 1, |
|||
"isRoot": true, |
|||
"tools": { |
|||
"dotnet-ef": { |
|||
"version": "7.0.3", |
|||
"commands": [ |
|||
"dotnet-ef" |
|||
] |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
using System.Windows; |
|||
|
|||
[assembly: ThemeInfo( |
|||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
|||
//(used if a resource is not found in the page,
|
|||
// or application resource dictionaries)
|
|||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
|||
//(used if a resource is not found in the page,
|
|||
// app, or any theme specific resource dictionaries)
|
|||
)] |
@ -0,0 +1,705 @@ |
|||
using System; |
|||
using System.Collections.Concurrent; |
|||
using System.Collections.Generic; |
|||
using System.Net.Http; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
using System.Text.RegularExpressions; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using System.Threading.Tasks.Schedulers; |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
using System.Windows.Interop; |
|||
using System.Windows.Media; |
|||
using System.Windows.Media.Imaging; |
|||
using System.Windows.Resources; |
|||
using dw = System.Drawing; |
|||
|
|||
namespace SJ.Controls |
|||
{ |
|||
public class BAsyncImage : Control |
|||
{ |
|||
#region DependencyProperty
|
|||
public static readonly DependencyProperty DecodePixelWidthProperty = DependencyProperty.Register("DecodePixelWidth", |
|||
typeof(double), typeof(BAsyncImage), new PropertyMetadata(0.0)); |
|||
|
|||
public static readonly DependencyProperty LoadingTextProperty = |
|||
DependencyProperty.Register("LoadingText", typeof(string), typeof(BAsyncImage), new PropertyMetadata("Loading...")); |
|||
|
|||
public static readonly DependencyProperty IsLoadingProperty = |
|||
DependencyProperty.Register("IsLoading", typeof(bool), typeof(BAsyncImage), new PropertyMetadata(false)); |
|||
|
|||
public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(BAsyncImage)); |
|||
|
|||
public static readonly DependencyProperty DefaultUrlSourceProperty = DependencyProperty.Register("DefaultUrlSource", typeof(string), typeof(BAsyncImage), new PropertyMetadata("")); |
|||
|
|||
public static readonly DependencyProperty UrlSourceProperty = |
|||
DependencyProperty.Register("UrlSource", typeof(string), typeof(BAsyncImage), new PropertyMetadata(string.Empty, new PropertyChangedCallback((s, e) => |
|||
{ |
|||
var asyncImg = s as BAsyncImage; |
|||
if (asyncImg.LoadEventFlag) |
|||
{ |
|||
asyncImg.Load(); |
|||
} |
|||
}))); |
|||
|
|||
public static readonly DependencyProperty FailUrlSourceProperty = |
|||
DependencyProperty.Register("FailUrlSource", typeof(string), typeof(BAsyncImage), new PropertyMetadata(string.Empty)); |
|||
|
|||
public static readonly DependencyProperty IsCacheProperty = DependencyProperty.Register("IsCache", typeof(bool), typeof(BAsyncImage), new PropertyMetadata(true)); |
|||
|
|||
public static readonly DependencyProperty StretchProperty = DependencyProperty.Register("Stretch", typeof(Stretch), typeof(BAsyncImage), new PropertyMetadata(Stretch.Uniform)); |
|||
|
|||
public static readonly DependencyProperty CacheGroupProperty = DependencyProperty.Register("CacheGroup", typeof(string), typeof(BAsyncImage), new PropertyMetadata("QLAsyncImage_Default")); |
|||
#endregion
|
|||
|
|||
#region Property
|
|||
private static readonly HttpClient httpClient = new HttpClient(); |
|||
|
|||
public double StaticImageActualPixelWidth { get; set; } = 0; |
|||
|
|||
public double StaticImageActualPixelHeight { get; set; } = 0; |
|||
|
|||
public const string LocalRegex = @"^([C-J]):\\([^:&]+\\)*([^:&]+).(jpg|jpeg|png|gif)$"; |
|||
public const string HttpRegex = @"^((https|http):\/\/)?([^\\*+@]+)$"; |
|||
|
|||
private Image _image; |
|||
private dw.Bitmap gifBitmap; |
|||
private bool LoadEventFlag = false; |
|||
private static ConcurrentDictionary<string, ImageSource> ImageCacheList; |
|||
private static ConcurrentDictionary<string, byte[]> GifImageCacheList; |
|||
|
|||
private static LimitedConcurrencyLevelTaskScheduler httpTaskScheduler; |
|||
|
|||
public double DecodePixelWidth |
|||
{ |
|||
get { return (double)GetValue(DecodePixelWidthProperty); } |
|||
set { SetValue(DecodePixelWidthProperty, value); } |
|||
} |
|||
public string LoadingText |
|||
{ |
|||
get { return GetValue(LoadingTextProperty) as string; } |
|||
set { SetValue(LoadingTextProperty, value); } |
|||
} |
|||
|
|||
public bool IsLoading |
|||
{ |
|||
get { return (bool)GetValue(IsLoadingProperty); } |
|||
set { SetValue(IsLoadingProperty, value); } |
|||
} |
|||
|
|||
public string UrlSource |
|||
{ |
|||
get { return GetValue(UrlSourceProperty) as string; } |
|||
set { SetValue(UrlSourceProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 仅限Resourcesl路径
|
|||
/// </summary>
|
|||
public string FailUrlSource |
|||
{ |
|||
get { return GetValue(FailUrlSourceProperty) as string; } |
|||
set { SetValue(FailUrlSourceProperty, value); } |
|||
} |
|||
|
|||
public ImageSource ImageSource |
|||
{ |
|||
get { return GetValue(ImageSourceProperty) as ImageSource; } |
|||
set { SetValue(ImageSourceProperty, value); } |
|||
} |
|||
|
|||
public bool IsCache |
|||
{ |
|||
get { return (bool)GetValue(IsCacheProperty); } |
|||
set { SetValue(IsCacheProperty, value); } |
|||
} |
|||
|
|||
public Stretch Stretch |
|||
{ |
|||
get { return (Stretch)GetValue(StretchProperty); } |
|||
set { SetValue(StretchProperty, value); } |
|||
} |
|||
|
|||
public string CacheGroup |
|||
{ |
|||
get { return GetValue(CacheGroupProperty) as string; } |
|||
set { SetValue(CacheGroupProperty, value); } |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region RouteEvent
|
|||
public delegate void QLAsyncImageLoadCompleteHandler(object sender, QLAsyncImageLoadCompleteEventArgs e); |
|||
|
|||
public static readonly RoutedEvent OnLoadCompleteEvent = EventManager.RegisterRoutedEvent("OnLoadComplete", RoutingStrategy.Bubble, typeof(QLAsyncImageLoadCompleteHandler), typeof(BAsyncImage)); |
|||
|
|||
public event QLAsyncImageLoadCompleteHandler OnLoadComplete |
|||
{ |
|||
add { AddHandler(OnLoadCompleteEvent, value); } |
|||
remove { RemoveHandler(OnLoadCompleteEvent, value); } |
|||
} |
|||
#endregion
|
|||
|
|||
#region Method
|
|||
static BAsyncImage() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata(typeof(BAsyncImage), new FrameworkPropertyMetadata(typeof(BAsyncImage))); |
|||
ImageCacheList = new ConcurrentDictionary<string, ImageSource>(); |
|||
GifImageCacheList = new ConcurrentDictionary<string, byte[]>(); |
|||
httpTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10); |
|||
} |
|||
|
|||
public BAsyncImage() |
|||
{ |
|||
Loaded += QLAsyncImage_Loaded; |
|||
Unloaded += QLAsyncImage_Unloaded; |
|||
} |
|||
|
|||
private void QLAsyncImage_Unloaded(object sender, RoutedEventArgs e) |
|||
{ |
|||
Reset(); |
|||
LoadEventFlag = false; |
|||
} |
|||
|
|||
private void QLAsyncImage_Loaded(object sender, RoutedEventArgs e) |
|||
{ |
|||
Init(); |
|||
} |
|||
|
|||
public override void OnApplyTemplate() |
|||
{ |
|||
Init(); |
|||
} |
|||
|
|||
private void Init([CallerMemberName] string eventName = "") |
|||
{ |
|||
if (LoadEventFlag) |
|||
return; |
|||
|
|||
_image = GetTemplateChild("image") as Image; |
|||
|
|||
if (_image == null) |
|||
return; |
|||
|
|||
LoadEventFlag = true; |
|||
Load(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Delete local bitmap resource
|
|||
/// Reference: http://msdn.microsoft.com/en-us/library/dd183539(VS.85).aspx
|
|||
/// </summary>
|
|||
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)] |
|||
[return: MarshalAs(UnmanagedType.Bool)] |
|||
static extern bool DeleteObject(IntPtr hObject); |
|||
|
|||
/// <summary>
|
|||
/// 重置图像
|
|||
/// </summary>
|
|||
private void Reset() |
|||
{ |
|||
//停止播放Gif动画
|
|||
if (gifBitmap != null) |
|||
StopGif(); |
|||
SetSource(null); |
|||
} |
|||
|
|||
private void Load() |
|||
{ |
|||
if (_image == null) |
|||
return; |
|||
|
|||
Reset(); |
|||
|
|||
if (!string.IsNullOrEmpty(UrlSource)) |
|||
{ |
|||
var url = UrlSource; |
|||
var failUrl = FailUrlSource; |
|||
var pixelWidth = (int)DecodePixelWidth; |
|||
var isCache = IsCache; |
|||
var cacheKey = string.Format("{0}_{1}", CacheGroup, url); |
|||
IsLoading = !ImageCacheList.ContainsKey(cacheKey) && !GifImageCacheList.ContainsKey(cacheKey); |
|||
|
|||
#region 读取缓存
|
|||
if (ImageCacheList.ContainsKey(cacheKey)) |
|||
{ |
|||
var source = ImageCacheList[cacheKey]; |
|||
SetSource(source); |
|||
SetStaticImageActualPixelSize(source.Width, source.Height); |
|||
LoadComplete(string.Empty, url); |
|||
return; |
|||
} |
|||
else if (GifImageCacheList.ContainsKey(cacheKey)) |
|||
{ |
|||
PlayGif(GifImageCacheList[cacheKey]); |
|||
LoadComplete(string.Empty, url); |
|||
return; |
|||
} |
|||
#endregion
|
|||
|
|||
this.Load(url, failUrl, cacheKey, isCache, pixelWidth); |
|||
} |
|||
} |
|||
|
|||
private void Load(string url, string failUrl, string cacheKey, bool isCache, int pixelWidth) |
|||
{ |
|||
var errorMessage = string.Empty; |
|||
|
|||
//解析路径类型
|
|||
var pathType = ValidatePathType(url); |
|||
if (pathType == PathType.Invalid) |
|||
{ |
|||
LoadFail(failUrl); |
|||
LoadComplete(errorMessage, url); |
|||
return; |
|||
} |
|||
|
|||
if (pathType == PathType.Http) |
|||
{ |
|||
////先加载默认图
|
|||
//if (!string.IsNullOrEmpty(defaultUrl))
|
|||
// LoadLocal(defaultUrl, failUrl, PathType.Resources, defaultUrl, true, 0, excuteComplete: false); //默认图不触发加载完毕事件
|
|||
LoadHttp(url, failUrl, cacheKey, isCache, pixelWidth); |
|||
} |
|||
else |
|||
LoadLocal(url, failUrl, pathType, cacheKey, isCache, pixelWidth); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 加载失败图像
|
|||
/// </summary>
|
|||
/// <param name="failUrl"></param>
|
|||
private void LoadFail(string failUrl) |
|||
{ |
|||
byte[] imgBytes = null; |
|||
string errorMessage = string.Empty; |
|||
var pathType = ValidatePathType(failUrl); |
|||
if (pathType == PathType.Invalid) |
|||
{ |
|||
Console.ForegroundColor = ConsoleColor.Red; |
|||
Console.WriteLine($"LoadFail 无效的路径 {failUrl}"); |
|||
Console.ResetColor(); |
|||
return; |
|||
} |
|||
if (pathType == PathType.Local) |
|||
imgBytes = LoadBytesFromLocal(failUrl, out errorMessage); |
|||
else if (pathType == PathType.Resources) |
|||
imgBytes = LoadBytesFromApplicationResource(failUrl, out errorMessage); |
|||
|
|||
|
|||
if (string.IsNullOrEmpty(errorMessage) && imgBytes != null) |
|||
AnalysisBytes(imgBytes, failUrl, true, 0, out errorMessage); |
|||
|
|||
if (string.IsNullOrEmpty(errorMessage)) |
|||
return; |
|||
|
|||
Console.ForegroundColor = ConsoleColor.Red; |
|||
Console.WriteLine($"LoadFail {errorMessage} {failUrl}"); |
|||
Console.ResetColor(); |
|||
} |
|||
|
|||
private void LoadLocal(string url, string failUrl, PathType pathType, string cacheKey, bool isCache, int pixelWidth, bool excuteComplete = true) |
|||
{ |
|||
byte[] imgBytes = null; |
|||
var errorMessage = string.Empty; |
|||
if (pathType == PathType.Local) |
|||
imgBytes = LoadBytesFromLocal(url, out errorMessage); |
|||
else if (pathType == PathType.Resources) |
|||
imgBytes = LoadBytesFromApplicationResource(url, out errorMessage); |
|||
|
|||
if (string.IsNullOrEmpty(errorMessage) && imgBytes != null) |
|||
AnalysisBytes(imgBytes, cacheKey, isCache, pixelWidth, out errorMessage); |
|||
|
|||
if (!string.IsNullOrEmpty(errorMessage)) |
|||
{ |
|||
LoadFail(failUrl); |
|||
Console.ForegroundColor = ConsoleColor.Red; |
|||
} |
|||
Console.WriteLine($"LoadLocal {errorMessage} {url}"); |
|||
Console.ResetColor(); |
|||
if (excuteComplete) |
|||
LoadComplete(errorMessage, url); |
|||
return; |
|||
} |
|||
|
|||
private void LoadHttp(string url, string failUrl, string cacheKey, bool isCache, int pixelWidth) |
|||
{ |
|||
Task.Factory.StartNew(() => |
|||
{ |
|||
//Thread.Sleep(2000);
|
|||
Console.WriteLine($"LoadHttp Start {url}"); |
|||
var errorMessage = string.Empty; |
|||
var imgBytes = LoadBytesFromHttp(url, out errorMessage); |
|||
|
|||
if (string.IsNullOrEmpty(errorMessage) && imgBytes != null) |
|||
AnalysisBytes(imgBytes, cacheKey, isCache, pixelWidth, out errorMessage); |
|||
|
|||
if (!string.IsNullOrEmpty(errorMessage)) |
|||
{ |
|||
LoadFail(failUrl); |
|||
Console.ForegroundColor = ConsoleColor.Red; |
|||
} |
|||
Console.WriteLine($"LoadHttp Completed {errorMessage} {url}"); |
|||
Console.ResetColor(); |
|||
LoadComplete(errorMessage, url); |
|||
return; |
|||
}, CancellationToken.None, TaskCreationOptions.None, httpTaskScheduler); |
|||
} |
|||
|
|||
private void AnalysisBytes(byte[] imgBytes, string cacheKey, bool isCache, int pixelWidth, out string errorMessage) |
|||
{ |
|||
errorMessage = string.Empty; |
|||
|
|||
#region 读取文件类型
|
|||
var imgType = GetImageType(imgBytes); |
|||
if (imgType == ImageType.Invalid) |
|||
{ |
|||
imgBytes = null; |
|||
errorMessage = "Invalid ImageFile"; |
|||
return; |
|||
} |
|||
#endregion
|
|||
|
|||
#region 加载图像
|
|||
if (imgType != ImageType.Gif) |
|||
{ |
|||
//加载静态图像
|
|||
var imgSource = LoadStaticImage(cacheKey, imgBytes, pixelWidth, isCache, out errorMessage); |
|||
if (imgSource == null) |
|||
return; |
|||
SetStaticImageActualPixelSize(imgSource.Width, imgSource.Height); |
|||
SetSource(imgSource); |
|||
} |
|||
else |
|||
{ |
|||
var frameCount = 0; |
|||
using (var memoryStream = new System.IO.MemoryStream(imgBytes)) |
|||
{ |
|||
//读取gif帧数
|
|||
var decoder = BitmapDecoder.Create(memoryStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); |
|||
frameCount = decoder.Frames.Count; |
|||
decoder = null; |
|||
} |
|||
if (frameCount > 1) |
|||
{ |
|||
CacheGifBytes(cacheKey, imgBytes, isCache); |
|||
PlayGif(imgBytes); |
|||
} |
|||
else |
|||
{ |
|||
//gif只有1帧,视为静态图处理
|
|||
var imgSource = LoadStaticImage(cacheKey, imgBytes, pixelWidth, isCache, out errorMessage); |
|||
if (imgSource == null) |
|||
return; |
|||
SetStaticImageActualPixelSize(imgSource.Width, imgSource.Height); |
|||
SetSource(imgSource); |
|||
} |
|||
} |
|||
#endregion
|
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 加载静态图像
|
|||
/// </summary>
|
|||
/// <param name="cacheKey"></param>
|
|||
/// <param name="imgBytes"></param>
|
|||
/// <param name="pixelWidth"></param>
|
|||
/// <param name="isCache"></param>
|
|||
/// <returns></returns>
|
|||
private ImageSource LoadStaticImage(string cacheKey, byte[] imgBytes, int pixelWidth, bool isCache, out string errorMessage) |
|||
{ |
|||
errorMessage = string.Empty; |
|||
if (ImageCacheList.ContainsKey(cacheKey)) |
|||
return ImageCacheList[cacheKey]; |
|||
var bit = new BitmapImage() { CacheOption = BitmapCacheOption.OnLoad }; |
|||
try |
|||
{ |
|||
bit.BeginInit(); |
|||
if (pixelWidth != 0) |
|||
{ |
|||
bit.DecodePixelWidth = pixelWidth; |
|||
} |
|||
bit.StreamSource = new System.IO.MemoryStream(imgBytes); |
|||
bit.EndInit(); |
|||
bit.Freeze(); |
|||
if (isCache && !ImageCacheList.ContainsKey(cacheKey)) |
|||
ImageCacheList.TryAdd(cacheKey, bit); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
errorMessage = $"LoadStaticImage Error {ex.Message}"; |
|||
bit = null; |
|||
} |
|||
return bit; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 加载Gif图像动画
|
|||
/// </summary>
|
|||
/// <param name="cacheKey"></param>
|
|||
/// <param name="imgBytes"></param>
|
|||
/// <param name="pixelWidth"></param>
|
|||
/// <param name="isCache"></param>
|
|||
/// <returns></returns>
|
|||
private void CacheGifBytes(string cacheKey, byte[] imgBytes, bool isCache) |
|||
{ |
|||
if (isCache && !GifImageCacheList.ContainsKey(cacheKey)) |
|||
GifImageCacheList.TryAdd(cacheKey, imgBytes); |
|||
} |
|||
|
|||
private byte[] LoadBytesFromHttp(string url, out string errorMessage) |
|||
{ |
|||
errorMessage = string.Empty; |
|||
try |
|||
{ |
|||
return httpClient.GetByteArrayAsync(url).Result; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
errorMessage = $"Dowdload Error {ex.Message}"; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
private byte[] LoadBytesFromLocal(string path, out string errorMessage) |
|||
{ |
|||
errorMessage = string.Empty; |
|||
if (!System.IO.File.Exists(path)) |
|||
{ |
|||
errorMessage = "File No Exists"; |
|||
return null; |
|||
} |
|||
try |
|||
{ |
|||
return System.IO.File.ReadAllBytes(path); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
errorMessage = $"Load Local Error {ex.Message}"; |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
private byte[] LoadBytesFromApplicationResource(string path, out string errorMessage) |
|||
{ |
|||
errorMessage = string.Empty; |
|||
try |
|||
{ |
|||
StreamResourceInfo streamInfo = Application.GetResourceStream(new Uri(path, UriKind.RelativeOrAbsolute)); |
|||
if (streamInfo.Stream.CanRead) |
|||
{ |
|||
using (streamInfo.Stream) |
|||
{ |
|||
var bytes = new byte[streamInfo.Stream.Length]; |
|||
streamInfo.Stream.Read(bytes, 0, bytes.Length); |
|||
return bytes; |
|||
} |
|||
} |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
errorMessage = $"Load Resource Error {ex.Message}"; |
|||
return null; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
private void SetSource(ImageSource source) |
|||
{ |
|||
Dispatcher.BeginInvoke((Action)delegate |
|||
{ |
|||
if (_image != null) |
|||
_image.Source = source; |
|||
}); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 更新图像实际像素
|
|||
/// </summary>
|
|||
/// <param name="pixelWidth"></param>
|
|||
private void SetStaticImageActualPixelSize(double pixelWidth, double pixelHeight) |
|||
{ |
|||
Dispatcher.Invoke(() => |
|||
{ |
|||
StaticImageActualPixelWidth = pixelWidth; |
|||
StaticImageActualPixelHeight = pixelHeight; |
|||
}); |
|||
} |
|||
|
|||
private void PlayGif(byte[] imgBytes) |
|||
{ |
|||
gifBitmap = new dw.Bitmap(new System.IO.MemoryStream(imgBytes)); |
|||
if (dw.ImageAnimator.CanAnimate(gifBitmap)) |
|||
{ |
|||
SetStaticImageActualPixelSize(gifBitmap.Width, gifBitmap.Height); |
|||
dw.ImageAnimator.Animate(gifBitmap, OnGifFrameChanged); |
|||
} |
|||
else |
|||
{ |
|||
gifBitmap.Dispose(); |
|||
} |
|||
} |
|||
|
|||
private void StopGif() |
|||
{ |
|||
dw.ImageAnimator.StopAnimate(gifBitmap, OnGifFrameChanged); |
|||
gifBitmap.Dispose(); |
|||
} |
|||
|
|||
private void OnGifFrameChanged(object sender, EventArgs e) |
|||
{ |
|||
dw.ImageAnimator.UpdateFrames(); |
|||
var currentFrameImageSource = GetBitmapSource(); |
|||
if (currentFrameImageSource != null) |
|||
currentFrameImageSource.Freeze(); |
|||
SetSource(currentFrameImageSource); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 加载完成
|
|||
/// </summary>
|
|||
/// <param name="errorMessage"></param>
|
|||
/// <param name="url"></param>
|
|||
private void LoadComplete(string errorMessage, string url) |
|||
{ |
|||
this.Dispatcher.BeginInvoke((Action)delegate |
|||
{ |
|||
IsLoading = false; |
|||
var args = new QLAsyncImageLoadCompleteEventArgs(OnLoadCompleteEvent, this) |
|||
{ |
|||
IsSuccess = string.IsNullOrEmpty(errorMessage), |
|||
UrlSource = url, |
|||
ErrorMessage = errorMessage, |
|||
StaticImageActualPixelWidth = StaticImageActualPixelWidth, |
|||
StaticImageActualPixelHeight = StaticImageActualPixelHeight |
|||
}; |
|||
this.RaiseEvent(args); |
|||
}); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 从System.Drawing.Bitmap中获得当前帧图像的BitmapSource
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
private ImageSource GetBitmapSource() |
|||
{ |
|||
IntPtr handle = IntPtr.Zero; |
|||
try |
|||
{ |
|||
handle = gifBitmap.GetHbitmap(); |
|||
return Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); |
|||
} |
|||
catch |
|||
{ |
|||
return null; |
|||
} |
|||
finally |
|||
{ |
|||
if (handle != IntPtr.Zero) |
|||
{ |
|||
DeleteObject(handle); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void Refresh() |
|||
{ |
|||
Load(); |
|||
} |
|||
|
|||
private PathType ValidatePathType(string path) |
|||
{ |
|||
if (path.StartsWith("pack://")) |
|||
return PathType.Resources; |
|||
else if (Regex.IsMatch(path, BAsyncImage.LocalRegex, RegexOptions.IgnoreCase)) |
|||
return PathType.Local; |
|||
else if (Regex.IsMatch(path, BAsyncImage.HttpRegex, RegexOptions.IgnoreCase)) |
|||
return PathType.Http; |
|||
else |
|||
return PathType.Invalid; |
|||
} |
|||
|
|||
private ImageType GetImageType(byte[] bytes) |
|||
{ |
|||
var type = ImageType.Invalid; |
|||
try |
|||
{ |
|||
var fileHead = Convert.ToInt32($"{bytes[0]}{bytes[1]}"); |
|||
if (!Enum.IsDefined(typeof(ImageType), fileHead)) |
|||
{ |
|||
type = ImageType.Invalid; |
|||
} |
|||
else |
|||
{ |
|||
type = (ImageType)fileHead; |
|||
} |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
type = ImageType.Invalid; |
|||
Console.WriteLine($"获取图片类型失败 {ex.Message}"); |
|||
} |
|||
return type; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 清楚缓存
|
|||
/// </summary>
|
|||
/// <param name="cacheKey">缓存Key,格式: CacheGroup_UrlSource</param>
|
|||
public static void ClearCache(string cacheKey = "") |
|||
{ |
|||
if (string.IsNullOrEmpty(cacheKey)) |
|||
{ |
|||
ImageCacheList.Clear(); |
|||
GifImageCacheList.Clear(); |
|||
return; |
|||
} |
|||
|
|||
ImageCacheList.Remove(cacheKey, out _); |
|||
GifImageCacheList.Remove(cacheKey, out _); |
|||
} |
|||
|
|||
public static ImageSource GetImageCache(string cacheKey) |
|||
{ |
|||
if (ImageCacheList.ContainsKey(cacheKey)) |
|||
return ImageCacheList[cacheKey]; |
|||
return null; |
|||
} |
|||
#endregion
|
|||
} |
|||
|
|||
|
|||
public enum PathType |
|||
{ |
|||
Invalid = 0, Local = 1, Http = 2, Resources = 3 |
|||
} |
|||
|
|||
public enum ImageType |
|||
{ |
|||
Invalid = 0, Gif = 7173, Jpg = 255216, Png = 13780, Bmp = 6677 |
|||
} |
|||
|
|||
public class QLAsyncImageLoadCompleteEventArgs : RoutedEventArgs |
|||
{ |
|||
public QLAsyncImageLoadCompleteEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source) { } |
|||
|
|||
public bool IsSuccess { get; set; } |
|||
|
|||
public string UrlSource { get; set; } |
|||
|
|||
public string ErrorMessage { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 当加载静态图时的实际像素宽度
|
|||
/// </summary>
|
|||
public double StaticImageActualPixelWidth { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 当加载静态图时的实际像素高度
|
|||
/// </summary>
|
|||
public double StaticImageActualPixelHeight { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,72 @@ |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
using System.Windows.Media; |
|||
|
|||
namespace SJ.Controls |
|||
{ |
|||
[StyleTypedProperty(Property = "Style", StyleTargetType = typeof(BButton))] |
|||
public class BButton : Button |
|||
{ |
|||
static BButton() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata(typeof(BButton), new FrameworkPropertyMetadata(typeof(BButton))); |
|||
} |
|||
|
|||
public static readonly DependencyProperty BorderCornerRadiusProperty = DependencyProperty.Register("BorderCornerRadius", typeof(CornerRadius), typeof(BButton)); |
|||
public static readonly DependencyProperty MouseOverBgColorProperty = DependencyProperty.Register("MouseOverBgColor", typeof(Brush), typeof(BButton)); |
|||
public static readonly DependencyProperty MouseOverFontColorProperty = DependencyProperty.Register("MouseOverFontColor", typeof(Brush), typeof(BButton)); |
|||
public static readonly DependencyProperty PressedBgColorProperty = DependencyProperty.Register("PressedBgColor", typeof(Brush), typeof(BButton)); |
|||
public static readonly DependencyProperty PressedFontColorProperty = DependencyProperty.Register("PressedFontColor", typeof(Brush), typeof(BButton)); |
|||
public static readonly DependencyProperty DisableBgColorProperty = DependencyProperty.Register("DisableBgColor", typeof(Brush), typeof(BButton)); |
|||
public static readonly DependencyProperty DisableTextProperty = DependencyProperty.Register("DisableText", typeof(string), typeof(BButton)); |
|||
public static readonly DependencyProperty PressedScaleProperty = DependencyProperty.Register("PressedScale", typeof(bool), typeof(BButton), new PropertyMetadata(true)); |
|||
|
|||
public CornerRadius BorderCornerRadius |
|||
{ |
|||
get { return (CornerRadius)GetValue(BorderCornerRadiusProperty); } |
|||
set { SetValue(BorderCornerRadiusProperty, value); } |
|||
} |
|||
|
|||
public Brush MouseOverBgColor |
|||
{ |
|||
get { return GetValue(MouseOverBgColorProperty) as Brush; } |
|||
set { SetValue(MouseOverBgColorProperty, value); } |
|||
} |
|||
|
|||
public Brush MouseOverFontColor |
|||
{ |
|||
get { return GetValue(MouseOverFontColorProperty) as Brush; } |
|||
set { SetValue(MouseOverFontColorProperty, value); } |
|||
} |
|||
|
|||
public Brush PressedBgColor |
|||
{ |
|||
get { return GetValue(PressedBgColorProperty) as Brush; } |
|||
set { SetValue(PressedBgColorProperty, value); } |
|||
} |
|||
|
|||
public Brush PressedFontColor |
|||
{ |
|||
get { return GetValue(PressedFontColorProperty) as Brush; } |
|||
set { SetValue(PressedFontColorProperty, value); } |
|||
} |
|||
|
|||
public Brush DisableBgColor |
|||
{ |
|||
get { return GetValue(DisableBgColorProperty) as System.Windows.Media.Brush; } |
|||
set { SetValue(DisableBgColorProperty, value); } |
|||
} |
|||
|
|||
public string DisableText |
|||
{ |
|||
get { return GetValue(DisableTextProperty).ToString(); } |
|||
set { SetValue(DisableTextProperty, value); } |
|||
} |
|||
|
|||
public bool PressedScale |
|||
{ |
|||
get { return (bool)GetValue(PressedScaleProperty); } |
|||
set { SetValue(PressedScaleProperty, value); } |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,210 @@ |
|||
using System.Text; |
|||
using System.Text.RegularExpressions; |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
using System.Windows.Input; |
|||
using System.Windows.Media; |
|||
|
|||
namespace SJ.Controls |
|||
{ |
|||
[StyleTypedProperty(Property = "Style", StyleTargetType = typeof(BTextBox))] |
|||
public class BTextBox : TextBox |
|||
{ |
|||
#region Property
|
|||
|
|||
private bool IsResponseChange; |
|||
private StringBuilder PasswordBuilder; |
|||
private int lastOffset; |
|||
|
|||
#endregion
|
|||
|
|||
#region DependencyProperty
|
|||
|
|||
public static readonly DependencyProperty WaterRemarkProperty = DependencyProperty.Register("WaterRemark", typeof(string), typeof(BTextBox)); |
|||
public static readonly DependencyProperty WaterRemarkFontColorProperty = DependencyProperty.Register("WaterRemarkFontColor", typeof(Brush), typeof(BTextBox)); |
|||
public static readonly DependencyProperty BorderCornerRadiusProperty = DependencyProperty.Register("BorderCornerRadius", typeof(CornerRadius), typeof(BTextBox)); |
|||
public static readonly DependencyProperty IsPasswordBoxProperty = DependencyProperty.Register("IsPasswordBox", typeof(bool), typeof(BTextBox), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsPasswordBoxChnage))); |
|||
public static readonly DependencyProperty IsNumberBoxProperty = DependencyProperty.Register("IsNumberBox", typeof(bool), typeof(BTextBox), new PropertyMetadata(false, new PropertyChangedCallback(OnIsNumberBoxChnage))); |
|||
public static readonly DependencyProperty DisableBgColorProperty = DependencyProperty.Register("DisableBgColor", typeof(Brush), typeof(BTextBox)); |
|||
public static readonly DependencyProperty PasswordCharProperty = DependencyProperty.Register("PasswordChar", typeof(char), typeof(BTextBox), new FrameworkPropertyMetadata('●')); |
|||
public static readonly DependencyProperty PasswordStrProperty = DependencyProperty.Register("PasswordStr", typeof(string), typeof(BTextBox), new FrameworkPropertyMetadata(string.Empty, new PropertyChangedCallback(OnPasswordStrChanged))); |
|||
|
|||
/// <summary>
|
|||
/// 水印文字
|
|||
/// </summary>
|
|||
public string WaterRemark |
|||
{ |
|||
get { return GetValue(WaterRemarkProperty).ToString(); } |
|||
set { SetValue(WaterRemarkProperty, value); } |
|||
} |
|||
|
|||
public Brush WaterRemarkFontColor |
|||
{ |
|||
get { return GetValue(WaterRemarkFontColorProperty) as Brush; } |
|||
set { SetValue(WaterRemarkFontColorProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 边框角度
|
|||
/// </summary>
|
|||
public CornerRadius BorderCornerRadius |
|||
{ |
|||
get { return (CornerRadius)GetValue(BorderCornerRadiusProperty); } |
|||
set { SetValue(BorderCornerRadiusProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 是否为密码框
|
|||
/// </summary>
|
|||
public bool IsPasswordBox |
|||
{ |
|||
get { return (bool)GetValue(IsPasswordBoxProperty); } |
|||
set { SetValue(IsPasswordBoxProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 是否为数字框
|
|||
/// </summary>
|
|||
public bool IsNumberBox |
|||
{ |
|||
get { return (bool)GetValue(IsNumberBoxProperty); } |
|||
set { SetValue(IsNumberBoxProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 替换明文的密码字符
|
|||
/// </summary>
|
|||
public char PasswordChar |
|||
{ |
|||
get { return (char)GetValue(PasswordCharProperty); } |
|||
set { SetValue(PasswordCharProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 密码字符串
|
|||
/// </summary>
|
|||
public string PasswordStr |
|||
{ |
|||
get |
|||
{ |
|||
var value = GetValue(PasswordStrProperty); |
|||
return value == null ? string.Empty : value.ToString(); |
|||
} |
|||
set { SetValue(PasswordStrProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 按钮被禁用时的背景颜色
|
|||
/// </summary>
|
|||
public Brush DisableBgColor |
|||
{ |
|||
get { return GetValue(DisableBgColorProperty) as Brush; } |
|||
set { SetValue(DisableBgColorProperty, value); } |
|||
} |
|||
#endregion
|
|||
|
|||
|
|||
static BTextBox() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata(typeof(BTextBox), new FrameworkPropertyMetadata(typeof(BTextBox))); |
|||
} |
|||
|
|||
public BTextBox() |
|||
{ |
|||
IsResponseChange = true; |
|||
PasswordBuilder = new StringBuilder(); |
|||
this.Loaded += QLTextBox_Loaded; |
|||
} |
|||
|
|||
private void QLTextBox_Loaded(object sender, RoutedEventArgs e) |
|||
{ |
|||
if (IsPasswordBox && !string.IsNullOrEmpty(PasswordStr) && PasswordStr.Length > 0) |
|||
{ |
|||
OnPasswordStrChanged(); |
|||
} |
|||
} |
|||
|
|||
private static void OnPasswordStrChanged(DependencyObject d, DependencyPropertyChangedEventArgs args) |
|||
{ |
|||
(d as BTextBox).OnPasswordStrChanged(); |
|||
} |
|||
|
|||
private void OnPasswordStrChanged() |
|||
{ |
|||
if (!IsResponseChange) |
|||
return; |
|||
IsResponseChange = false; |
|||
this.Text = ConvertToPasswordChar(PasswordStr.Length); |
|||
IsResponseChange = true; |
|||
} |
|||
|
|||
private static void OnIsPasswordBoxChnage(DependencyObject sender, DependencyPropertyChangedEventArgs e) |
|||
{ |
|||
(sender as BTextBox).SetPwdEvent(); |
|||
} |
|||
|
|||
private static void OnIsNumberBoxChnage(DependencyObject sender, DependencyPropertyChangedEventArgs e) |
|||
{ |
|||
(sender as BTextBox).SetValidationNumberEvent(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 定义TextChange事件
|
|||
/// </summary>
|
|||
private void SetPwdEvent() |
|||
{ |
|||
if (IsPasswordBox) |
|||
this.TextChanged += QLTextBox_TextChanged; |
|||
else |
|||
this.TextChanged -= QLTextBox_TextChanged; |
|||
} |
|||
|
|||
private void SetValidationNumberEvent() |
|||
{ |
|||
if (IsNumberBox) |
|||
this.PreviewTextInput += QLTextBox_PreviewTextInput; |
|||
else |
|||
this.PreviewTextInput -= QLTextBox_PreviewTextInput; |
|||
} |
|||
|
|||
private void QLTextBox_TextChanged(object sender, TextChangedEventArgs e) |
|||
{ |
|||
if (!IsResponseChange) |
|||
return; |
|||
IsResponseChange = false; |
|||
foreach (TextChange c in e.Changes) |
|||
{ |
|||
PasswordStr = PasswordStr.Remove(c.Offset, c.RemovedLength); |
|||
PasswordStr = PasswordStr.Insert(c.Offset, Text.Substring(c.Offset, c.AddedLength)); |
|||
lastOffset = c.Offset; |
|||
} |
|||
/*将文本转换为密码字符*/ |
|||
this.Text = ConvertToPasswordChar(Text.Length); |
|||
IsResponseChange = true; |
|||
this.SelectionStart = lastOffset + 1; |
|||
} |
|||
|
|||
private void QLTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) |
|||
{ |
|||
Regex re = new Regex("[^0-9.]+"); |
|||
e.Handled = re.IsMatch(e.Text); |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 按照指定的长度生成密码字符
|
|||
/// </summary>
|
|||
/// <param name="length"></param>
|
|||
/// <returns></returns>
|
|||
private string ConvertToPasswordChar(int length) |
|||
{ |
|||
if (PasswordBuilder != null) |
|||
PasswordBuilder.Clear(); |
|||
else |
|||
PasswordBuilder = new StringBuilder(); |
|||
for (var i = 0; i < length; i++) |
|||
PasswordBuilder.Append(PasswordChar); |
|||
return PasswordBuilder.ToString(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,109 @@ |
|||
using System; |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
using System.Windows.Media; |
|||
using System.Windows.Media.Animation; |
|||
|
|||
namespace SJ.Controls |
|||
{ |
|||
[StyleTypedProperty(Property = "Style", StyleTargetType = typeof(BTextBoxAnimation))] |
|||
public class BTextBoxAnimation : BTextBox |
|||
{ |
|||
public static readonly DependencyProperty WaterRemarkTopStateColorProperty = DependencyProperty.Register("WaterRemarkTopStateColor", typeof(Brush), typeof(BTextBoxAnimation)); |
|||
public static readonly DependencyProperty WaterRemarkStateProperty = DependencyProperty.Register("WaterRemarkState", typeof(WaterRemarkState), typeof(BTextBoxAnimation), new PropertyMetadata(WaterRemarkState.Normal, new PropertyChangedCallback((d, e) => |
|||
{ |
|||
if (e.OldValue != e.NewValue) |
|||
{ |
|||
(d as BTextBoxAnimation).PlayWaterRemarkAnimation(); |
|||
} |
|||
}))); |
|||
|
|||
private TextBlock txtRemark; |
|||
private TimeSpan animationTimeSpan = new TimeSpan(0, 0, 0, 0, 200); |
|||
private IEasingFunction animationEasingFunction = new PowerEase() { EasingMode = EasingMode.EaseInOut }; |
|||
|
|||
|
|||
public Brush WaterRemarkTopStateColor |
|||
{ |
|||
get { return GetValue(WaterRemarkTopStateColorProperty) as Brush; } |
|||
set { SetValue(WaterRemarkTopStateColorProperty, value); } |
|||
} |
|||
|
|||
public WaterRemarkState WaterRemarkState |
|||
{ |
|||
get { return (WaterRemarkState)Convert.ToInt32(GetValue(WaterRemarkStateProperty)); } |
|||
set { SetValue(WaterRemarkStateProperty, value); } |
|||
} |
|||
|
|||
|
|||
static BTextBoxAnimation() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata(typeof(BTextBoxAnimation), new FrameworkPropertyMetadata(typeof(BTextBoxAnimation))); |
|||
} |
|||
public BTextBoxAnimation() |
|||
{ |
|||
this.Loaded += QLTextBoxAnimation_Loaded; |
|||
} |
|||
|
|||
public override void OnApplyTemplate() |
|||
{ |
|||
txtRemark = GetTemplateChild("txtRemark") as TextBlock; |
|||
base.OnApplyTemplate(); |
|||
} |
|||
|
|||
private void QLTextBoxAnimation_Loaded(object sender, RoutedEventArgs e) |
|||
{ |
|||
if (!string.IsNullOrEmpty(Text)) |
|||
WaterRemarkState = WaterRemarkState.Top; |
|||
} |
|||
|
|||
protected override void OnTextChanged(TextChangedEventArgs e) |
|||
{ |
|||
base.OnTextChanged(e); |
|||
if (!this.IsLoaded) |
|||
return; |
|||
if (string.IsNullOrEmpty(Text)) |
|||
WaterRemarkState = WaterRemarkState.Normal; |
|||
else |
|||
WaterRemarkState = WaterRemarkState.Top; |
|||
} |
|||
|
|||
protected override void OnGotFocus(RoutedEventArgs e) |
|||
{ |
|||
base.OnGotFocus(e); |
|||
WaterRemarkState = WaterRemarkState.Top; |
|||
} |
|||
|
|||
protected override void OnLostFocus(RoutedEventArgs e) |
|||
{ |
|||
base.OnLostFocus(e); |
|||
if (string.IsNullOrEmpty(Text)) |
|||
WaterRemarkState = WaterRemarkState.Normal; |
|||
} |
|||
|
|||
private void PlayWaterRemarkAnimation() |
|||
{ |
|||
var fontsize = WaterRemarkState == WaterRemarkState.Normal ? FontSize : 10.5; |
|||
var row = WaterRemarkState == WaterRemarkState.Normal ? 1 : 0; |
|||
|
|||
var storyboard = new Storyboard(); |
|||
var daukf_Remark_FontSize = new DoubleAnimationUsingKeyFrames(); |
|||
daukf_Remark_FontSize.KeyFrames.Add(new EasingDoubleKeyFrame(fontsize, animationTimeSpan, animationEasingFunction)); |
|||
Storyboard.SetTargetProperty(daukf_Remark_FontSize, new PropertyPath("(TextBlock.FontSize)")); |
|||
Storyboard.SetTarget(daukf_Remark_FontSize, txtRemark); |
|||
storyboard.Children.Add(daukf_Remark_FontSize); |
|||
|
|||
var i32aukf_Remark_Row = new Int32AnimationUsingKeyFrames(); |
|||
i32aukf_Remark_Row.KeyFrames.Add(new EasingInt32KeyFrame(row, animationTimeSpan, animationEasingFunction)); |
|||
Storyboard.SetTargetProperty(i32aukf_Remark_Row, new PropertyPath("(Grid.Row)")); |
|||
Storyboard.SetTarget(i32aukf_Remark_Row, txtRemark); |
|||
storyboard.Children.Add(i32aukf_Remark_Row); |
|||
storyboard.Begin(); |
|||
} |
|||
} |
|||
|
|||
public enum WaterRemarkState |
|||
{ |
|||
Normal, Top |
|||
} |
|||
} |
@ -0,0 +1,178 @@ |
|||
using System.ComponentModel; |
|||
using System.Reflection; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
using System.Windows.Input; |
|||
using System.Windows.Media; |
|||
using System.Windows.Shell; |
|||
|
|||
namespace SJ.Controls |
|||
{ |
|||
[StyleTypedProperty(Property = "Style", StyleTargetType = typeof(BWindow))] |
|||
public class BWindow : Window, INotifyPropertyChanged |
|||
{ |
|||
public static readonly DependencyProperty CornerRadiusProperty = |
|||
DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(BWindow), new PropertyMetadata(new CornerRadius(0))); |
|||
|
|||
public static readonly DependencyProperty RightButtonGroupMarginProperty = |
|||
DependencyProperty.Register("RightButtonGroupMargin", typeof(Thickness), typeof(BWindow), new PropertyMetadata(new Thickness(0, 16, 16, 0))); |
|||
|
|||
public static readonly DependencyProperty CloseButtonVisibilityProperty = |
|||
DependencyProperty.Register("CloseButtonVisibility", typeof(Visibility), typeof(BWindow), new PropertyMetadata(Visibility.Visible)); |
|||
|
|||
public static readonly DependencyProperty MinButtonVisibilityProperty = |
|||
DependencyProperty.Register("MinButtonVisibility", typeof(Visibility), typeof(BWindow), new PropertyMetadata(Visibility.Visible)); |
|||
|
|||
public static readonly DependencyProperty MaxButtonVisibilityProperty = |
|||
DependencyProperty.Register("MaxButtonVisibility", typeof(Visibility), typeof(BWindow), new PropertyMetadata(Visibility.Visible)); |
|||
|
|||
public static readonly DependencyProperty CloseButtonColorProperty = |
|||
DependencyProperty.Register("CloseButtonColor", typeof(Brush), typeof(BWindow), new PropertyMetadata(new SolidColorBrush(Colors.White))); |
|||
|
|||
public static readonly DependencyProperty MinButtonColorProperty = |
|||
DependencyProperty.Register("MinButtonColor", typeof(Brush), typeof(BWindow), new PropertyMetadata(new SolidColorBrush(Colors.White))); |
|||
|
|||
public static readonly DependencyProperty MaxButtonColorProperty = |
|||
DependencyProperty.Register("MaxButtonColor", typeof(Brush), typeof(BWindow), new PropertyMetadata(new SolidColorBrush(Colors.White))); |
|||
|
|||
public CornerRadius CornerRadius |
|||
{ |
|||
get { return (CornerRadius)GetValue(CornerRadiusProperty); } |
|||
set { SetValue(CornerRadiusProperty, value); } |
|||
} |
|||
|
|||
public Thickness RightButtonGroupMargin |
|||
{ |
|||
get { return (Thickness)GetValue(RightButtonGroupMarginProperty); } |
|||
set { SetValue(RightButtonGroupMarginProperty, value); } |
|||
} |
|||
|
|||
public Visibility CloseButtonVisibility |
|||
{ |
|||
get { return (Visibility)GetValue(CloseButtonVisibilityProperty); } |
|||
set { SetValue(CloseButtonVisibilityProperty, value); } |
|||
} |
|||
|
|||
public Visibility MinButtonVisibility |
|||
{ |
|||
get { return (Visibility)GetValue(MinButtonVisibilityProperty); } |
|||
set { SetValue(MinButtonVisibilityProperty, value); } |
|||
} |
|||
|
|||
public Visibility MaxButtonVisibility |
|||
{ |
|||
get { return (Visibility)GetValue(MaxButtonVisibilityProperty); } |
|||
set { SetValue(MaxButtonVisibilityProperty, value); } |
|||
} |
|||
|
|||
public Brush CloseButtonColor |
|||
{ |
|||
get { return (Brush)GetValue(CloseButtonColorProperty); } |
|||
set { SetValue(CloseButtonColorProperty, value); } |
|||
} |
|||
|
|||
public Brush MinButtonColor |
|||
{ |
|||
get { return (Brush)GetValue(MinButtonColorProperty); } |
|||
set { SetValue(MinButtonColorProperty, value); } |
|||
} |
|||
|
|||
public Brush MaxButtonColor |
|||
{ |
|||
get { return (Brush)GetValue(MaxButtonColorProperty); } |
|||
set { SetValue(MaxButtonColorProperty, value); } |
|||
} |
|||
|
|||
static BWindow() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata(typeof(BWindow), new FrameworkPropertyMetadata(typeof(BWindow))); |
|||
} |
|||
|
|||
public BWindow() |
|||
{ |
|||
WindowStartupLocation = WindowStartupLocation.CenterScreen; |
|||
var chrome = new WindowChrome |
|||
{ |
|||
CornerRadius = new CornerRadius(), |
|||
GlassFrameThickness = new Thickness(1), |
|||
UseAeroCaptionButtons = false, |
|||
NonClientFrameEdges = NonClientFrameEdges.None, |
|||
ResizeBorderThickness = new Thickness(2), |
|||
CaptionHeight = 30 |
|||
}; |
|||
WindowChrome.SetWindowChrome(this, chrome); |
|||
} |
|||
|
|||
public override void OnApplyTemplate() |
|||
{ |
|||
Button PART_MIN = null; |
|||
Button PART_MAX = null; |
|||
Button PART_RESTORE = null; |
|||
Button PART_CLOSE = null; |
|||
|
|||
PART_MIN = GetTemplateChild("PART_MIN") as Button; |
|||
PART_MAX = GetTemplateChild("PART_MAX") as Button; |
|||
PART_RESTORE = GetTemplateChild("PART_RESTORE") as Button; |
|||
PART_CLOSE = GetTemplateChild("PART_CLOSE") as Button; |
|||
|
|||
if (PART_RESTORE != null) |
|||
PART_RESTORE.Click += PART_RESTORE_Click; |
|||
if (PART_MAX != null) |
|||
PART_MAX.Click += PART_MAX_Click; |
|||
if (PART_MIN != null) |
|||
PART_MIN.Click += PART_MIN_Click; |
|||
if (PART_CLOSE != null) |
|||
PART_CLOSE.Click += PART_CLOSE_Click; |
|||
|
|||
base.OnApplyTemplate(); |
|||
} |
|||
|
|||
private void PART_CLOSE_Click(object sender, RoutedEventArgs e) |
|||
{ |
|||
this.Close(); |
|||
} |
|||
|
|||
private void PART_MIN_Click(object sender, RoutedEventArgs e) |
|||
{ |
|||
WindowState = WindowState.Minimized; |
|||
} |
|||
|
|||
private void PART_MAX_Click(object sender, RoutedEventArgs e) |
|||
{ |
|||
WindowState = WindowState.Maximized; |
|||
} |
|||
|
|||
private void PART_RESTORE_Click(object sender, RoutedEventArgs e) |
|||
{ |
|||
WindowState = WindowState.Normal; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 判断是否为模态窗口
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
public bool IsModal() |
|||
{ |
|||
var filedInfo = typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic); |
|||
return filedInfo != null && (bool)filedInfo.GetValue(this); |
|||
} |
|||
|
|||
|
|||
#region PropertyNotify
|
|||
public event PropertyChangedEventHandler PropertyChanged; |
|||
protected void OnPropertyChanged([CallerMemberName] string propertyName = "") |
|||
{ |
|||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); |
|||
} |
|||
protected bool Set<T>(ref T oldValue, T newValue, [CallerMemberName] string propertyName = "") |
|||
{ |
|||
if (Equals(oldValue, newValue)) |
|||
return false; |
|||
oldValue = newValue; |
|||
OnPropertyChanged(propertyName); |
|||
return true; |
|||
} |
|||
#endregion
|
|||
} |
|||
} |
@ -0,0 +1,71 @@ |
|||
using System.Collections.Generic; |
|||
using System.Windows; |
|||
using System.Windows.Input; |
|||
using System.Windows.Media; |
|||
|
|||
namespace BBGWY.Controls.Extensions |
|||
{ |
|||
public static class VisualTreeExtension |
|||
{ |
|||
public static T HitTest<T>(this FrameworkElement fe, Point? point) where T : FrameworkElement |
|||
{ |
|||
if (point == null) |
|||
point = Mouse.GetPosition(fe); |
|||
var result = VisualTreeHelper.HitTest(fe, point.Value); |
|||
if (result == null) |
|||
return null; |
|||
if (result.VisualHit != null) |
|||
{ |
|||
var r = FindParentOfType<T>(result.VisualHit); |
|||
return r; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 查找父控件
|
|||
/// </summary>
|
|||
/// <typeparam name="T">父控件类型</typeparam>
|
|||
/// <param name="obj">子控件实例</param>
|
|||
/// <returns></returns>
|
|||
public static T FindParentOfType<T>(this DependencyObject obj) where T : FrameworkElement |
|||
{ |
|||
DependencyObject parent = VisualTreeHelper.GetParent(obj); |
|||
while (parent != null) |
|||
{ |
|||
if (parent is T) |
|||
{ |
|||
return (T)parent; |
|||
} |
|||
parent = VisualTreeHelper.GetParent(parent); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 查找子控件
|
|||
/// </summary>
|
|||
/// <typeparam name="T">需要查找的控件类型</typeparam>
|
|||
/// <param name="obj">父控件实例</param>
|
|||
/// <returns></returns>
|
|||
public static T FindFirstVisualChild<T>(this DependencyObject obj) where T : FrameworkElement |
|||
{ |
|||
var queue = new Queue<DependencyObject>(); |
|||
queue.Enqueue(obj); |
|||
while (queue.Count > 0) |
|||
{ |
|||
DependencyObject current = queue.Dequeue(); |
|||
for (int i = VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--) |
|||
{ |
|||
DependencyObject child = VisualTreeHelper.GetChild(current, i); |
|||
if (child != null && child is T) |
|||
{ |
|||
return (T)child; |
|||
} |
|||
queue.Enqueue(child); |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,188 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Windows; |
|||
using System.Windows.Media.Animation; |
|||
|
|||
namespace SJ.Controls.Helpers |
|||
{ |
|||
public class StoryboardHelper |
|||
{ |
|||
/// <summary>
|
|||
/// 播放动画
|
|||
/// </summary>
|
|||
/// <param name="fe">控件源</param>
|
|||
/// <param name="from">开始值</param>
|
|||
/// <param name="to">结束值</param>
|
|||
/// <param name="duration">时间间隔</param>
|
|||
/// <param name="IsAutoReverse">是否反向播放</param>
|
|||
/// <param name="RepeatPlay">是否重复播放</param>
|
|||
/// <param name="ef">动画类型</param>
|
|||
/// <param name="Callback">回调函数</param>
|
|||
/// <param name="PropertyPath">动画属性</param>
|
|||
public static void _PlayDoubleAnimation(FrameworkElement fe, double from, double to, TimeSpan duration, bool IsAutoReverse, bool RepeatPlay, IEasingFunction ef, Action Callback, string PropertyPath) |
|||
{ |
|||
Storyboard _sb = new Storyboard(); |
|||
_sb.Completed += new EventHandler((s, e) => |
|||
{ |
|||
if (Callback != null) |
|||
Callback(); |
|||
_sb.Stop(); |
|||
_sb.Children.Clear(); |
|||
_sb = null; |
|||
}); |
|||
DoubleAnimation daRotation = new DoubleAnimation(); |
|||
daRotation.From = from; |
|||
daRotation.To = to; |
|||
daRotation.EasingFunction = ef; |
|||
daRotation.Duration = duration; |
|||
Storyboard.SetTargetProperty(daRotation, new PropertyPath(PropertyPath)); |
|||
Storyboard.SetTarget(daRotation, fe); |
|||
_sb.Children.Add(daRotation); |
|||
_sb.AutoReverse = IsAutoReverse; |
|||
if (RepeatPlay) |
|||
_sb.RepeatBehavior = RepeatBehavior.Forever; |
|||
_sb.Begin(); |
|||
} |
|||
|
|||
public static void _PlayAnimationUsingKeyFrames(IList<AnimationModel> AnimationUsingKeyFrameList, bool IsAutoReverse, bool IsRepeayPlay, Action Callback) |
|||
{ |
|||
if (AnimationUsingKeyFrameList == null || AnimationUsingKeyFrameList.Count == 0) |
|||
return; |
|||
Storyboard _sb = new Storyboard(); |
|||
_sb.Completed += new EventHandler((s, e) => |
|||
{ |
|||
if (Callback != null) |
|||
Callback(); |
|||
_sb.Stop(); |
|||
_sb.Children.Clear(); |
|||
_sb = null; |
|||
}); |
|||
_sb.AutoReverse = IsAutoReverse; |
|||
if (IsRepeayPlay) |
|||
_sb.RepeatBehavior = RepeatBehavior.Forever; |
|||
foreach (AnimationModel am in AnimationUsingKeyFrameList) |
|||
{ |
|||
AnimationTimeline animationTimeLine = null; |
|||
switch (am._KeyFrameType) |
|||
{ |
|||
case KeyFrameType.DoubleKeyFrame: |
|||
animationTimeLine = CreateDoubleAnimationUsingKeyFrames(am); |
|||
break; |
|||
case KeyFrameType.ColorKeyFrame: |
|||
animationTimeLine = CreateColorAnimationUsingKeyFrames(am); |
|||
break; |
|||
case KeyFrameType.ObjectKeyFrame: |
|||
animationTimeLine = CreateObjectAnimationUsingKeyFrames(am); |
|||
break; |
|||
} |
|||
_sb.Children.Add(animationTimeLine); |
|||
} |
|||
_sb.Begin(); |
|||
} |
|||
|
|||
private static AnimationTimeline CreateDoubleAnimationUsingKeyFrames(AnimationModel am) |
|||
{ |
|||
DoubleAnimationUsingKeyFrames animationTimeline = new DoubleAnimationUsingKeyFrames(); |
|||
Storyboard.SetTargetProperty(animationTimeline, new PropertyPath(am.PropertyPath)); |
|||
Storyboard.SetTarget(animationTimeline, am.Element); |
|||
foreach (BaseKeyFrame baseKeyFrame in am.KeyFrames) |
|||
{ |
|||
animationTimeline.KeyFrames.Add( |
|||
new EasingDoubleKeyFrame( |
|||
Convert.ToInt32(baseKeyFrame.Value), |
|||
baseKeyFrame._KeyTime, |
|||
baseKeyFrame.EasingFunction) |
|||
); |
|||
} |
|||
return animationTimeline; |
|||
} |
|||
|
|||
private static AnimationTimeline CreateColorAnimationUsingKeyFrames(AnimationModel am) |
|||
{ |
|||
ColorAnimationUsingKeyFrames animationTimeline = new ColorAnimationUsingKeyFrames(); |
|||
Storyboard.SetTargetProperty(animationTimeline, new PropertyPath(am.PropertyPath)); |
|||
Storyboard.SetTarget(animationTimeline, am.Element); |
|||
foreach (BaseKeyFrame baseKeyFrame in am.KeyFrames) |
|||
{ |
|||
animationTimeline.KeyFrames.Add( |
|||
new EasingColorKeyFrame( |
|||
(System.Windows.Media.Color)baseKeyFrame.Value, |
|||
baseKeyFrame._KeyTime, |
|||
baseKeyFrame.EasingFunction) |
|||
); |
|||
} |
|||
return animationTimeline; |
|||
} |
|||
|
|||
private static AnimationTimeline CreateObjectAnimationUsingKeyFrames(AnimationModel am) |
|||
{ |
|||
ObjectAnimationUsingKeyFrames animationTimeline = new ObjectAnimationUsingKeyFrames(); |
|||
Storyboard.SetTargetProperty(animationTimeline, new PropertyPath(am.PropertyPath)); |
|||
Storyboard.SetTarget(animationTimeline, am.Element); |
|||
foreach (BaseKeyFrame baseKeyFrame in am.KeyFrames) |
|||
{ |
|||
animationTimeline.KeyFrames.Add( |
|||
new DiscreteObjectKeyFrame( |
|||
baseKeyFrame.Value, |
|||
baseKeyFrame._KeyTime) |
|||
); |
|||
} |
|||
return animationTimeline; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 关键帧动画类型
|
|||
/// </summary>
|
|||
public enum KeyFrameType |
|||
{ |
|||
DoubleKeyFrame = 1, |
|||
ColorKeyFrame = 2, |
|||
ObjectKeyFrame = 3 |
|||
} |
|||
|
|||
public class AnimationModel |
|||
{ |
|||
public AnimationModel() |
|||
{ |
|||
this.KeyFrames = new List<BaseKeyFrame>(); |
|||
} |
|||
/// <summary>
|
|||
/// 执行动画的对象
|
|||
/// </summary>
|
|||
public FrameworkElement Element; |
|||
|
|||
/// <summary>
|
|||
/// 作用于动画的属性
|
|||
/// </summary>
|
|||
public string PropertyPath; |
|||
|
|||
/// <summary>
|
|||
/// 动画类型枚举
|
|||
/// </summary>
|
|||
public KeyFrameType _KeyFrameType; |
|||
|
|||
/// <summary>
|
|||
/// 关键帧动画帧集合
|
|||
/// </summary>
|
|||
public IList<BaseKeyFrame> KeyFrames; |
|||
} |
|||
|
|||
public class BaseKeyFrame |
|||
{ |
|||
/// <summary>
|
|||
/// 动画触发时间
|
|||
/// </summary>
|
|||
public TimeSpan _KeyTime; |
|||
|
|||
/// <summary>
|
|||
/// 值
|
|||
/// </summary>
|
|||
public object Value; |
|||
|
|||
/// <summary>
|
|||
/// 缓动函数类型
|
|||
/// </summary>
|
|||
public IEasingFunction EasingFunction; |
|||
} |
|||
} |
@ -0,0 +1,24 @@ |
|||
<UserControl x:Class="SJ.Controls.PageControl" |
|||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|||
xmlns:c="clr-namespace:SJ.Controls" |
|||
mc:Ignorable="d" |
|||
d:DesignHeight="30" d:DesignWidth="500"> |
|||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center"> |
|||
<TextBlock Text="{Binding PageSize,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type c:PageControl}},StringFormat=每页\{0\}条}" VerticalAlignment="Center"/> |
|||
<TextBlock Text="{Binding PageIndex,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type c:PageControl}},StringFormat=当前显示第\{0\}}" VerticalAlignment="Center" Margin="15,0,0,0"/> |
|||
<TextBlock Text="{Binding PageCount,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type c:PageControl}},StringFormat=/\{0\}页}" VerticalAlignment="Center"/> |
|||
<TextBlock Text="{Binding RecordCount,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type c:PageControl}},StringFormat=共\{0\}条记录}" VerticalAlignment="Center" Margin="15,0,0,0"/> |
|||
<c:BButton x:Name="btn_first" Content="首页" Margin="15,0,0,0" VerticalAlignment="Center" Click="btn_first_Click" |
|||
Style="{StaticResource LinkButton}"/> |
|||
<c:BButton x:Name="btn_up" Margin="15,0,0,0" VerticalAlignment="Center" Click="btn_up_Click" Content="上一页" |
|||
Style="{StaticResource LinkButton}"/> |
|||
<!--<StackPanel x:Name="sp_pagenumber" Orientation="Horizontal" VerticalAlignment="Center"/>--> |
|||
<c:BButton x:Name="btn_next" Margin="15,0,0,0" VerticalAlignment="Center" Click="btn_next_Click" Content="下一页" |
|||
Style="{StaticResource LinkButton}"/> |
|||
<c:BButton x:Name="btn_last" Content="尾页" Margin="15,0,0,0" VerticalAlignment="Center" Click="btn_last_Click" |
|||
Style="{StaticResource LinkButton}"/> |
|||
</StackPanel> |
|||
</UserControl> |
@ -0,0 +1,137 @@ |
|||
using System; |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
|
|||
namespace SJ.Controls |
|||
{ |
|||
/// <summary>
|
|||
/// PageControl.xaml 的交互逻辑
|
|||
/// </summary>
|
|||
public partial class PageControl : UserControl |
|||
{ |
|||
public PageControl() |
|||
{ |
|||
InitializeComponent(); |
|||
this.Loaded += PageControl_Loaded; |
|||
} |
|||
|
|||
private void PageControl_Loaded(object sender, RoutedEventArgs e) |
|||
{ |
|||
this.PageIndex = 1; |
|||
pageArgs.PageIndex = this.PageIndex; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 分页事件
|
|||
/// </summary>
|
|||
public event RoutedEventHandler OnPageIndexChanged; |
|||
|
|||
/// <summary>
|
|||
/// 分页参数
|
|||
/// </summary>
|
|||
private PageArgs pageArgs = new PageArgs(); |
|||
|
|||
public static readonly DependencyProperty PageIndexProperty = DependencyProperty.Register("PageIndex", typeof(int), typeof(PageControl), new PropertyMetadata(1, new PropertyChangedCallback((s, e) => |
|||
{ |
|||
var pageControl = s as PageControl; |
|||
pageControl?.OnIndexChanged(); |
|||
}))); |
|||
|
|||
/// <summary>
|
|||
/// 当前页数
|
|||
/// </summary>
|
|||
public int PageIndex |
|||
{ |
|||
get { return (int)GetValue(PageIndexProperty); } |
|||
set { SetValue(PageIndexProperty, value); } |
|||
} |
|||
|
|||
public static readonly DependencyProperty PageSizeProperty = DependencyProperty.Register("PageSize", typeof(int), typeof(PageControl), new PropertyMetadata(1)); |
|||
|
|||
/// <summary>
|
|||
/// 每页记录数
|
|||
/// </summary>
|
|||
public int PageSize |
|||
{ |
|||
get { return (int)GetValue(PageSizeProperty); } |
|||
set { SetValue(PageSizeProperty, value); } |
|||
} |
|||
|
|||
public static readonly DependencyProperty PageCountProperty = DependencyProperty.Register("PageCount", typeof(int), typeof(PageControl), new PropertyMetadata(1)); |
|||
|
|||
/// <summary>
|
|||
/// 总页数
|
|||
/// </summary>
|
|||
public int PageCount |
|||
{ |
|||
get { return (int)GetValue(PageCountProperty); } |
|||
set { SetValue(PageCountProperty, value); } |
|||
} |
|||
|
|||
public static readonly DependencyProperty RecordCountProperty = DependencyProperty.Register("RecordCount", typeof(int), typeof(PageControl), new PropertyMetadata(0, new PropertyChangedCallback((s, e) => |
|||
{ |
|||
var pageControl = s as PageControl; |
|||
pageControl?.OnRecordChanged(); |
|||
}))); |
|||
|
|||
/// <summary>
|
|||
/// 总记录数
|
|||
/// </summary>
|
|||
public int RecordCount |
|||
{ |
|||
get { return (int)GetValue(RecordCountProperty); } |
|||
set { SetValue(RecordCountProperty, value); } |
|||
} |
|||
|
|||
private void OnRecordChanged() |
|||
{ |
|||
PageCount = (RecordCount - 1) / PageSize + 1; |
|||
} |
|||
|
|||
private void OnIndexChanged() |
|||
{ |
|||
pageArgs.PageIndex = this.PageIndex; |
|||
OnPageIndexChanged?.Invoke(this, pageArgs); |
|||
} |
|||
|
|||
private void Btn_Click(object sender, RoutedEventArgs e) |
|||
{ |
|||
var btn = sender as BButton; |
|||
var newPageIndex = Convert.ToInt32(btn.Content); |
|||
if (newPageIndex != PageIndex) |
|||
PageIndex = newPageIndex; |
|||
else |
|||
OnIndexChanged(); |
|||
} |
|||
|
|||
private void btn_first_Click(object sender, RoutedEventArgs e) |
|||
{ |
|||
if (PageIndex > 1) |
|||
PageIndex = 1; |
|||
} |
|||
|
|||
private void btn_up_Click(object sender, RoutedEventArgs e) |
|||
{ |
|||
if (PageIndex > 1) |
|||
PageIndex--; |
|||
} |
|||
|
|||
private void btn_next_Click(object sender, RoutedEventArgs e) |
|||
{ |
|||
if (PageIndex < PageCount) |
|||
PageIndex++; |
|||
} |
|||
|
|||
private void btn_last_Click(object sender, RoutedEventArgs e) |
|||
{ |
|||
if (PageIndex < PageCount) |
|||
PageIndex = PageCount; |
|||
} |
|||
} |
|||
|
|||
public class PageArgs : RoutedEventArgs |
|||
{ |
|||
public int PageIndex; |
|||
//其余自行扩展
|
|||
} |
|||
} |
@ -0,0 +1,56 @@ |
|||
<UserControl x:Class="SJ.Controls.RoundWaitProgress" |
|||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|||
xmlns:local="clr-namespace:SJ.Controls" |
|||
mc:Ignorable="d" |
|||
d:DesignHeight="300" d:DesignWidth="300"> |
|||
<Grid> |
|||
<Grid VerticalAlignment="Center" HorizontalAlignment="Center"> |
|||
<Grid.RowDefinitions> |
|||
<RowDefinition Height="auto"/> |
|||
<RowDefinition Height="auto"/> |
|||
</Grid.RowDefinitions> |
|||
<Grid Width="{Binding AnimationSize,Mode=OneWay,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:RoundWaitProgress}}}" Height="{Binding Width,RelativeSource={RelativeSource Self}}"> |
|||
<Grid x:Name="g1" RenderTransformOrigin="0.5,0.5" Opacity="0"> |
|||
<Grid.RenderTransform> |
|||
<RotateTransform Angle="0"/> |
|||
</Grid.RenderTransform> |
|||
<Border Width="8" Height="8" Background="{Binding Color,Mode=OneWay,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:RoundWaitProgress}}}" CornerRadius="5" VerticalAlignment="Bottom" HorizontalAlignment="Center"/> |
|||
</Grid> |
|||
|
|||
<Grid x:Name="g2" RenderTransformOrigin="0.5,0.5" Opacity="0"> |
|||
<Grid.RenderTransform> |
|||
<RotateTransform Angle="0"/> |
|||
</Grid.RenderTransform> |
|||
<Border Width="8" Height="8" Background="{Binding Color,Mode=OneWay,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:RoundWaitProgress}}}" CornerRadius="5" VerticalAlignment="Bottom" HorizontalAlignment="Center"/> |
|||
</Grid> |
|||
|
|||
<Grid x:Name="g3" RenderTransformOrigin="0.5,0.5" Opacity="0"> |
|||
<Grid.RenderTransform> |
|||
<RotateTransform Angle="0"/> |
|||
</Grid.RenderTransform> |
|||
<Border Width="8" Height="8" Background="{Binding Color,Mode=OneWay,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:RoundWaitProgress}}}" CornerRadius="5" VerticalAlignment="Bottom" HorizontalAlignment="Center" /> |
|||
</Grid> |
|||
|
|||
<Grid x:Name="g4" RenderTransformOrigin="0.5,0.5" Opacity="0"> |
|||
<Grid.RenderTransform> |
|||
<RotateTransform Angle="0"/> |
|||
</Grid.RenderTransform> |
|||
<Border Width="8" Height="8" Background="{Binding Color,Mode=OneWay,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:RoundWaitProgress}}}" CornerRadius="5" VerticalAlignment="Bottom" HorizontalAlignment="Center"/> |
|||
</Grid> |
|||
|
|||
<Grid x:Name="g5" RenderTransformOrigin="0.5,0.5" Opacity="0"> |
|||
<Grid.RenderTransform> |
|||
<RotateTransform Angle="0"/> |
|||
</Grid.RenderTransform> |
|||
<Border Width="8" Height="8" Background="{Binding Color,Mode=OneWay,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:RoundWaitProgress}}}" CornerRadius="5" VerticalAlignment="Bottom" HorizontalAlignment="Center"/> |
|||
</Grid> |
|||
</Grid> |
|||
<TextBlock Text="{Binding WaitText,Mode=OneWay,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:RoundWaitProgress}}}" |
|||
Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" |
|||
Margin="0,15,0,0"/> |
|||
</Grid> |
|||
</Grid> |
|||
</UserControl> |
@ -0,0 +1,180 @@ |
|||
using SJ.Controls.Helpers; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
using System.Windows.Media; |
|||
using System.Windows.Media.Animation; |
|||
|
|||
namespace SJ.Controls |
|||
{ |
|||
/// <summary>
|
|||
/// RoundWaitProgress.xaml 的交互逻辑
|
|||
/// </summary>
|
|||
public partial class RoundWaitProgress : UserControl |
|||
{ |
|||
public RoundWaitProgress() |
|||
{ |
|||
InitializeComponent(); |
|||
this.Loaded += RoundWaitProgress_Loaded; |
|||
InitAnimationData(); |
|||
} |
|||
|
|||
private void RoundWaitProgress_Loaded(object sender, RoutedEventArgs e) |
|||
{ |
|||
if (!IsPlaying) |
|||
this.Visibility = Visibility.Collapsed; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 初始化动画数据
|
|||
/// </summary>
|
|||
private void InitAnimationData() |
|||
{ |
|||
if (ControlList == null) |
|||
ControlList = new List<FrameworkElement>() { g1, g2, g3, g4, g5 }; |
|||
|
|||
if (AngleAnimationParamList == null) |
|||
AngleAnimationParamList = new List<BaseKeyFrame>(); |
|||
if (BeginOpacityAnimationParamList == null) |
|||
BeginOpacityAnimationParamList = new List<BaseKeyFrame>(); |
|||
if (EndOpacityAnimationParamList == null) |
|||
EndOpacityAnimationParamList = new List<BaseKeyFrame>(); |
|||
|
|||
AngleAnimationParamList.Clear(); |
|||
BeginOpacityAnimationParamList.Clear(); |
|||
EndOpacityAnimationParamList.Clear(); |
|||
|
|||
AngleAnimationParamList.Add(new BaseKeyFrame() { Value = 0, _KeyTime = new TimeSpan(0, 0, 0, 0, 0) }); |
|||
AngleAnimationParamList.Add(new BaseKeyFrame() { Value = 112, _KeyTime = new TimeSpan(0, 0, 0, 0, 400) }); |
|||
AngleAnimationParamList.Add(new BaseKeyFrame() { Value = 202, _KeyTime = new TimeSpan(0, 0, 0, 0, 1500) }); |
|||
AngleAnimationParamList.Add(new BaseKeyFrame() { Value = 472, _KeyTime = new TimeSpan(0, 0, 0, 0, 2200) }); |
|||
AngleAnimationParamList.Add(new BaseKeyFrame() { _KeyTime = new TimeSpan(0, 0, 0, 0, 3100), Value = 562 }); |
|||
AngleAnimationParamList.Add(new BaseKeyFrame() { _KeyTime = new TimeSpan(0, 0, 0, 0, 3500), Value = 720 }); |
|||
|
|||
BeginOpacityAnimationParamList.Add(new BaseKeyFrame() { _KeyTime = new TimeSpan(0, 0, 0, 0, 0), Value = 0 }); |
|||
BeginOpacityAnimationParamList.Add(new BaseKeyFrame() { _KeyTime = new TimeSpan(0, 0, 0, 0, 1), Value = 1 }); |
|||
|
|||
EndOpacityAnimationParamList.Add(new BaseKeyFrame() { _KeyTime = new TimeSpan(0, 0, 0, 0, 3499), Value = 1 }); |
|||
EndOpacityAnimationParamList.Add(new BaseKeyFrame() { _KeyTime = new TimeSpan(0, 0, 0, 0, 3500), Value = 0 }); |
|||
EndOpacityAnimationParamList.Add(new BaseKeyFrame() { _KeyTime = new TimeSpan(0, 0, 0, 0, 4500), Value = 0 }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 动画属性
|
|||
/// </summary>
|
|||
public static readonly string AnglePropertyPath = "(UIElement.RenderTransform).(RotateTransform.Angle)"; |
|||
public static readonly string OpacityPropertyPath = "(UIElement.Opacity)"; |
|||
private IList<BaseKeyFrame> AngleAnimationParamList; |
|||
private IList<BaseKeyFrame> BeginOpacityAnimationParamList; |
|||
private IList<BaseKeyFrame> EndOpacityAnimationParamList; |
|||
private IList<FrameworkElement> ControlList; |
|||
private Storyboard _Storyboard; |
|||
private bool IsPlaying; |
|||
|
|||
/// <summary>
|
|||
/// 间隔时间
|
|||
/// </summary>
|
|||
public static readonly TimeSpan IntervalTimeSpan = new TimeSpan(0, 0, 0, 0, 200); |
|||
|
|||
public static readonly DependencyProperty WaitTextProperty = DependencyProperty.Register("WaitText", typeof(string), typeof(RoundWaitProgress), new PropertyMetadata("正在加载数据")); |
|||
|
|||
public string WaitText |
|||
{ |
|||
get { return GetValue(WaitTextProperty).ToString(); } |
|||
set { SetValue(WaitTextProperty, value); } |
|||
} |
|||
|
|||
public static readonly DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Brush), typeof(RoundWaitProgress), new PropertyMetadata(new SolidColorBrush(Colors.Black))); |
|||
|
|||
public Brush Color |
|||
{ |
|||
get { return GetValue(ColorProperty) as Brush; } |
|||
set { SetValue(ColorProperty, value); } |
|||
} |
|||
|
|||
public static readonly DependencyProperty AnimationSizeProperty = DependencyProperty.Register("AnimationSize", typeof(double), typeof(RoundWaitProgress), new PropertyMetadata(80.0)); |
|||
|
|||
public double AnimationSize |
|||
{ |
|||
get { return Convert.ToDouble(GetValue(AnimationSizeProperty)); } |
|||
set { SetValue(AnimationSizeProperty, value); } |
|||
} |
|||
|
|||
public static readonly DependencyProperty PlayProperty = DependencyProperty.Register("Play", typeof(bool), typeof(RoundWaitProgress), new PropertyMetadata(false, (s, e) => |
|||
{ |
|||
var waitControl = s as RoundWaitProgress; |
|||
if (waitControl.Play) |
|||
waitControl.Start(); |
|||
else |
|||
waitControl.Stop(); |
|||
})); |
|||
|
|||
public bool Play |
|||
{ |
|||
get { return (bool)GetValue(PlayProperty); } |
|||
set { SetValue(PlayProperty, value); } |
|||
} |
|||
|
|||
private void Start() |
|||
{ |
|||
this.IsPlaying = true; |
|||
this.Visibility = Visibility.Visible; |
|||
this._Storyboard = new Storyboard(); |
|||
foreach (var frameElement in ControlList) |
|||
{ |
|||
(frameElement.RenderTransform as RotateTransform).Angle = 0; |
|||
DoubleAnimationUsingKeyFrames daukf = new DoubleAnimationUsingKeyFrames(); |
|||
foreach (var item in AngleAnimationParamList) |
|||
{ |
|||
daukf.KeyFrames.Add(new EasingDoubleKeyFrame(Convert.ToDouble(item.Value), item._KeyTime)); |
|||
} |
|||
Storyboard.SetTargetProperty(daukf, new PropertyPath(AnglePropertyPath)); |
|||
Storyboard.SetTarget(daukf, frameElement); |
|||
this._Storyboard.Children.Add(daukf); |
|||
|
|||
DoubleAnimationUsingKeyFrames daukf1 = new DoubleAnimationUsingKeyFrames(); |
|||
foreach (var item in BeginOpacityAnimationParamList) |
|||
{ |
|||
daukf1.KeyFrames.Add(new EasingDoubleKeyFrame(Convert.ToDouble(item.Value), item._KeyTime)); |
|||
} |
|||
foreach (var item in EndOpacityAnimationParamList) |
|||
{ |
|||
daukf1.KeyFrames.Add(new EasingDoubleKeyFrame(Convert.ToDouble(item.Value), item._KeyTime)); |
|||
} |
|||
Storyboard.SetTargetProperty(daukf1, new PropertyPath(OpacityPropertyPath)); |
|||
Storyboard.SetTarget(daukf1, frameElement); |
|||
this._Storyboard.Children.Add(daukf1); |
|||
|
|||
for (var i = 0; i < AngleAnimationParamList.Count; i++) |
|||
{ |
|||
var item = AngleAnimationParamList[i]; |
|||
item._KeyTime = item._KeyTime.Add(IntervalTimeSpan); |
|||
} |
|||
|
|||
foreach (var item in BeginOpacityAnimationParamList) |
|||
{ |
|||
item._KeyTime = item._KeyTime.Add(IntervalTimeSpan); |
|||
} |
|||
|
|||
foreach (var item in EndOpacityAnimationParamList) |
|||
{ |
|||
item._KeyTime = item._KeyTime.Add(IntervalTimeSpan); |
|||
} |
|||
|
|||
this._Storyboard.RepeatBehavior = RepeatBehavior.Forever; |
|||
} |
|||
this._Storyboard.Begin(); |
|||
} |
|||
|
|||
private void Stop() |
|||
{ |
|||
this._Storyboard.Stop(); |
|||
this._Storyboard.Children.Clear(); |
|||
this._Storyboard = null; |
|||
this.IsPlaying = false; |
|||
InitAnimationData(); |
|||
this.Visibility = Visibility.Collapsed; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0-windows</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
<UseWPF>true</UseWPF> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="System.Drawing.Common" Version="6.0.2-mauipre.1.22102.15" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\BBWYB.Common\BBWYB.Common.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,377 @@ |
|||
<ResourceDictionary |
|||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:local="clr-namespace:SJ.Controls"> |
|||
<Style x:Key="BWin_MIN" |
|||
TargetType="{x:Type Button}"> |
|||
<Setter Property="HorizontalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="VerticalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="Foreground" Value="White"/> |
|||
<Setter Property="Cursor" Value="Hand"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type Button}"> |
|||
<Border x:Name="border" Background="Transparent" |
|||
BorderThickness="0"> |
|||
<Path x:Name="p" Stretch="Uniform" SnapsToDevicePixels="True" |
|||
HorizontalAlignment="Center" VerticalAlignment="Center" |
|||
Width="12" Height="2" Data="M0,0 12,0 12,1 0,1z" Fill="{TemplateBinding Foreground}"/> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsEnabled" Value="false"> |
|||
<Setter Property="Opacity" Value="0.5" /> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
<Style x:Key="BWin_MAX" |
|||
TargetType="{x:Type Button}"> |
|||
<Setter Property="HorizontalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="VerticalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="Foreground" Value="White"/> |
|||
<Setter Property="Cursor" Value="Hand"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type Button}"> |
|||
<Border x:Name="border" |
|||
Background="#00FFFFFF" |
|||
BorderThickness="0"> |
|||
<Path x:Name="p" Stretch="Uniform" Width="12" Height="12" Data="M1,0 10,0 11,1 11,10 10,11 1,11 0,10 0,1z" Stroke="{TemplateBinding Foreground}"/> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsEnabled" Value="false"> |
|||
<Setter Property="Opacity" Value="0.5" /> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
<Style x:Key="BWin_RESTORE" |
|||
TargetType="{x:Type Button}"> |
|||
<Setter Property="HorizontalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="VerticalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="Foreground" Value="White"/> |
|||
<Setter Property="Cursor" Value="Hand"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type Button}"> |
|||
<Border x:Name="border" |
|||
Background="#00FFFFFF" |
|||
BorderThickness="0"> |
|||
<Path x:Name="p" Stretch="Uniform" SnapsToDevicePixels="True" UseLayoutRounding="True" Data="M9,9 L9,9 9,12 L8,13 1,13 L0,12 0,5 L1,4 4,4 L4,3 4,1 L5,0 12,0 L13,1 13,8 L12,9 10,9 L9,9 9,5 L8,4 4,4" Width="14" Height="14" Stroke="{TemplateBinding Foreground}"/> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsEnabled" Value="false"> |
|||
<Setter Property="Opacity" Value="0.5" /> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
<Style x:Key="BWin_CLOSE" |
|||
TargetType="{x:Type Button}"> |
|||
<Setter Property="HorizontalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="VerticalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="Foreground" Value="White"/> |
|||
<Setter Property="Cursor" Value="Hand"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type Button}"> |
|||
<Border x:Name="border" |
|||
Background="#00FFFFFF" |
|||
BorderThickness="0"> |
|||
<Path x:Name="p" Stretch="Uniform" Width="12" Height="12" |
|||
Data="M814.060 781.227q-67.241-67.241-269.773-269.773 67.241-67.241 269.773-269.773 5.671-6.481 5.671-12.962 0 0-0.81-0.81 0-6.481-4.861-9.722-4.861-4.051-11.342-4.861-0.81 0-0.81 0-5.671 0-11.342 4.861-89.924 89.924-269.773 269.773-67.241-67.241-269.773-269.773-4.861-4.861-12.962-4.861-7.291 0.81-10.532 4.861-5.671 5.671-5.671 11.342 0 6.481 5.671 12.152 89.924 89.924 269.773 269.773-67.241 67.241-269.773 269.773-11.342 11.342 0 23.494 12.152 11.342 23.494 0 89.924-89.924 269.773-269.773 67.241 67.241 269.773 269.773 5.671 5.671 11.342 5.671 5.671 0 12.152-5.671 4.861-5.671 4.861-12.962 0-6.481-4.861-10.532z" |
|||
Fill="{TemplateBinding Foreground}"/> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsEnabled" Value="false"> |
|||
<Setter Property="Opacity" Value="0.5" /> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type local:BWindow}"> |
|||
<Setter Property="Background" Value="White"/> |
|||
<Setter Property="UseLayoutRounding" Value="True"/> |
|||
<Setter Property="SnapsToDevicePixels" Value="True"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type local:BWindow}"> |
|||
<Border SnapsToDevicePixels="True" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
Background="{TemplateBinding Background}" |
|||
Padding="{TemplateBinding Padding}"> |
|||
<Grid x:Name="win_content"> |
|||
<AdornerDecorator> |
|||
<ContentPresenter/> |
|||
</AdornerDecorator> |
|||
<StackPanel Panel.ZIndex="99" Orientation="Horizontal" |
|||
Margin="{Binding Path=RightButtonGroupMargin,RelativeSource={RelativeSource Mode=TemplatedParent}}" |
|||
VerticalAlignment="Top" Height="22" |
|||
HorizontalAlignment="Right" |
|||
WindowChrome.IsHitTestVisibleInChrome="True"> |
|||
<Button WindowChrome.IsHitTestVisibleInChrome="True" |
|||
x:Name="PART_MIN" |
|||
Width="24" Height="22" |
|||
Style="{StaticResource BWin_MIN}" |
|||
Foreground="{Binding MinButtonColor,RelativeSource={RelativeSource Mode=TemplatedParent}}" |
|||
Visibility="{Binding Path=MinButtonVisibility, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"/> |
|||
<Grid Visibility="{Binding Path=MaxButtonVisibility, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"> |
|||
<Button WindowChrome.IsHitTestVisibleInChrome="True" x:Name="PART_MAX" Width="22" Height="22" Style="{StaticResource BWin_MAX}" |
|||
Foreground="{Binding MaxButtonColor,RelativeSource={RelativeSource Mode=TemplatedParent}}"/> |
|||
<Button WindowChrome.IsHitTestVisibleInChrome="True" x:Name="PART_RESTORE" Width="22" Height="22" Style="{StaticResource BWin_RESTORE}" |
|||
Foreground="{Binding MaxButtonColor,RelativeSource={RelativeSource Mode=TemplatedParent}}"/> |
|||
</Grid> |
|||
<Button WindowChrome.IsHitTestVisibleInChrome="True" |
|||
x:Name="PART_CLOSE" |
|||
Width="24" Height="22" |
|||
Style="{StaticResource BWin_CLOSE}" |
|||
Foreground="{Binding CloseButtonColor,RelativeSource={RelativeSource Mode=TemplatedParent}}" |
|||
Visibility="{Binding Path=CloseButtonVisibility, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"></Button> |
|||
</StackPanel> |
|||
</Grid> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="WindowState" Value="Maximized"> |
|||
<Setter Property="Visibility" Value="Collapsed" TargetName="PART_MAX"/> |
|||
<Setter Property="Visibility" Value="Visible" TargetName="PART_RESTORE"/> |
|||
<Setter Property="Margin" Value="8" TargetName="win_content"/> |
|||
</Trigger> |
|||
<Trigger Property="WindowState" Value="Normal"> |
|||
<Setter Property="Visibility" Value="Visible" TargetName="PART_MAX"/> |
|||
<Setter Property="Visibility" Value="Collapsed" TargetName="PART_RESTORE"/> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type local:BButton}"> |
|||
<Setter Property="BorderThickness" Value="1" /> |
|||
<Setter Property="BorderBrush" Value="Black"/> |
|||
<Setter Property="HorizontalContentAlignment" Value="Center" /> |
|||
<Setter Property="HorizontalAlignment" Value="Center"/> |
|||
<Setter Property="VerticalAlignment" Value="Center" /> |
|||
<Setter Property="VerticalContentAlignment" Value="Center" /> |
|||
<!--<Setter Property="FontFamily" Value="Comic Sans MS" />--> |
|||
<Setter Property="BorderCornerRadius" Value="0" /> |
|||
<Setter Property="Background" Value="#02FFFFFF"/> |
|||
<Setter Property="DisableBgColor" Value="{Binding Background,RelativeSource={RelativeSource Self}}"/> |
|||
<Setter Property="MouseOverBgColor" Value="{Binding Background,RelativeSource={RelativeSource Self}}" /> |
|||
<Setter Property="MouseOverFontColor" Value="{Binding Foreground,RelativeSource={RelativeSource Self}}" /> |
|||
<Setter Property="PressedBgColor" Value="{Binding MouseOverBgColor,RelativeSource={RelativeSource Self}}" /> |
|||
<Setter Property="PressedFontColor" Value="{Binding MouseOverFontColor,RelativeSource={RelativeSource Self}}" /> |
|||
<Setter Property="SnapsToDevicePixels" Value="True"/> |
|||
<Setter Property="UseLayoutRounding" Value="True"/> |
|||
<Setter Property="Cursor" Value="Hand" /> |
|||
<Setter Property="FocusVisualStyle" Value="{x:Null}" /> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type local:BButton}"> |
|||
<Border x:Name="Bd" RenderTransformOrigin="0.5,0.5" |
|||
Background="{TemplateBinding Background}" |
|||
CornerRadius="{TemplateBinding BorderCornerRadius}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
SnapsToDevicePixels="True"> |
|||
<Border.RenderTransform> |
|||
<ScaleTransform ScaleX="1" ScaleY="1"/> |
|||
</Border.RenderTransform> |
|||
<ContentPresenter x:Name="btnContent" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsMouseOver" Value="True"> |
|||
<Setter Property="Background" Value="{Binding MouseOverBgColor,RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="Bd" /> |
|||
<Setter Property="TextBlock.Foreground" Value="{Binding MouseOverFontColor,RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="Bd" /> |
|||
</Trigger> |
|||
<Trigger Property="IsPressed" Value="True"> |
|||
<Setter Property="Background" Value="{Binding PressedBgColor,RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="Bd" /> |
|||
<Setter Property="TextBlock.Foreground" Value="{Binding PressedFontColor,RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="Bd" /> |
|||
</Trigger> |
|||
<MultiTrigger> |
|||
<MultiTrigger.Conditions> |
|||
<Condition Property="IsPressed" Value="True"/> |
|||
<Condition Property="PressedScale" Value="True"/> |
|||
</MultiTrigger.Conditions> |
|||
<Setter Property="RenderTransform" TargetName="Bd"> |
|||
<Setter.Value> |
|||
<ScaleTransform ScaleX="0.93" ScaleY="0.93"/> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</MultiTrigger> |
|||
<Trigger Property="IsEnabled" Value="False"> |
|||
<Setter Property="Opacity" Value="0.5" /> |
|||
<Setter Property="Background" Value="{Binding DisableBgColor,RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="Bd" /> |
|||
<Setter Property="Content" Value="{Binding DisableText,RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="btnContent" /> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type local:BTextBox}"> |
|||
<Setter Property="VerticalAlignment" Value="Center"/> |
|||
<Setter Property="VerticalContentAlignment" Value="Center"/> |
|||
<Setter Property="BorderThickness" Value="1"/> |
|||
<Setter Property="BorderBrush" Value="Black"/> |
|||
<Setter Property="FontSize" Value="12"/> |
|||
<Setter Property="Cursor" Value="IBeam"/> |
|||
<Setter Property="Padding" Value="5,0,0,0"/> |
|||
<Setter Property="FocusVisualStyle" Value="{x:Null}" /> |
|||
<Setter Property="WaterRemarkFontColor" Value="Gray"/> |
|||
<Setter Property="DisableBgColor" Value="Gray"/> |
|||
<Setter Property="Height" Value="30"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type local:BTextBox}"> |
|||
<Border x:Name="border" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
Background="{TemplateBinding Background}" |
|||
CornerRadius="{TemplateBinding BorderCornerRadius}" |
|||
SnapsToDevicePixels="True"> |
|||
<Grid> |
|||
<ScrollViewer x:Name="PART_ContentHost" Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/> |
|||
<TextBlock x:Name="txtRemark" Text="{TemplateBinding WaterRemark}" |
|||
Foreground="{TemplateBinding WaterRemarkFontColor}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" |
|||
Margin="{TemplateBinding Padding}" |
|||
Visibility="Collapsed"/> |
|||
</Grid> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="Text" Value=""> |
|||
<Setter Property="Visibility" Value="Visible" TargetName="txtRemark"/> |
|||
</Trigger> |
|||
<Trigger Property="IsEnabled" Value="False"> |
|||
<Setter Property="Background" Value="{Binding DisableBgColor,RelativeSource={RelativeSource Mode=TemplatedParent}}" |
|||
TargetName="border"/> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type local:BTextBoxAnimation}"> |
|||
<Setter Property="VerticalAlignment" Value="Center"/> |
|||
<Setter Property="VerticalContentAlignment" Value="Center"/> |
|||
<Setter Property="BorderThickness" Value="0,0,0,1"/> |
|||
<Setter Property="BorderBrush" Value="Gray"/> |
|||
<Setter Property="Cursor" Value="IBeam"/> |
|||
<Setter Property="FontSize" Value="12"/> |
|||
<Setter Property="Padding" Value="5,0,0,0"/> |
|||
<Setter Property="FocusVisualStyle" Value="{x:Null}" /> |
|||
<Setter Property="Focusable" Value="True"/> |
|||
<Setter Property="WaterRemarkFontColor" Value="Gray"/> |
|||
<Setter Property="WaterRemarkTopStateColor" Value="Gray"/> |
|||
<Setter Property="DisableBgColor" Value="Gray"/> |
|||
<Setter Property="MinHeight" Value="40"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type local:BTextBoxAnimation}"> |
|||
<Border x:Name="border" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
Background="{TemplateBinding Background}" |
|||
CornerRadius="{TemplateBinding BorderCornerRadius}" |
|||
SnapsToDevicePixels="True"> |
|||
<Grid> |
|||
<Grid.RowDefinitions> |
|||
<RowDefinition Height="20"/> |
|||
<RowDefinition Height="*"/> |
|||
</Grid.RowDefinitions> |
|||
<ScrollViewer x:Name="PART_ContentHost" Focusable="False" IsTabStop="False" |
|||
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" |
|||
Grid.Row="1"/> |
|||
<TextBlock x:Name="txtRemark" |
|||
Text="{TemplateBinding WaterRemark}" |
|||
Foreground="{TemplateBinding WaterRemarkFontColor}" |
|||
VerticalAlignment="Center" |
|||
Margin="{TemplateBinding Padding}" |
|||
Grid.Row="1" |
|||
Panel.ZIndex="2"/> |
|||
</Grid> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsEnabled" Value="False"> |
|||
<Setter Property="Background" Value="{Binding DisableBgColor,RelativeSource={RelativeSource Mode=TemplatedParent}}" |
|||
TargetName="border"/> |
|||
</Trigger> |
|||
<Trigger Property="WaterRemarkState" |
|||
Value="Top"> |
|||
<Setter TargetName="txtRemark" Property="Foreground" Value="{Binding WaterRemarkTopStateColor,RelativeSource={RelativeSource Mode=TemplatedParent}}"/> |
|||
<Setter TargetName="border" Property="BorderBrush" Value="{Binding WaterRemarkTopStateColor,RelativeSource={RelativeSource Mode=TemplatedParent}}"/> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type local:BAsyncImage}"> |
|||
<Setter Property="HorizontalAlignment" Value="Center"/> |
|||
<Setter Property="VerticalAlignment" Value="Center"/> |
|||
<Setter Property="UseLayoutRounding" Value="True"/> |
|||
<Setter Property="SnapsToDevicePixels" Value="True"/> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type local:BAsyncImage}"> |
|||
<Border Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" |
|||
VerticalAlignment="{TemplateBinding VerticalAlignment}"> |
|||
<Grid> |
|||
<!-- Source="{TemplateBinding ImageSource}"--> |
|||
<Image x:Name="image" |
|||
Stretch="{TemplateBinding Stretch}" |
|||
UseLayoutRounding="{TemplateBinding UseLayoutRounding}" |
|||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" |
|||
RenderOptions.BitmapScalingMode="HighQuality"/> |
|||
<TextBlock Text="{TemplateBinding LoadingText}" |
|||
FontSize="{TemplateBinding FontSize}" |
|||
FontFamily="{TemplateBinding FontFamily}" |
|||
FontWeight="{TemplateBinding FontWeight}" |
|||
Foreground="{TemplateBinding Foreground}" |
|||
HorizontalAlignment="Center" |
|||
VerticalAlignment="Center" |
|||
x:Name="txtLoading"/> |
|||
</Grid> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsLoading" Value="False"> |
|||
<Setter Property="Visibility" |
|||
Value="Collapsed" |
|||
TargetName="txtLoading"/> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style x:Key="middleTextBlock" TargetType="TextBlock"> |
|||
<Setter Property="HorizontalAlignment" Value="Center"/> |
|||
<Setter Property="VerticalAlignment" Value="Center"/> |
|||
</Style> |
|||
|
|||
</ResourceDictionary> |
Loading…
Reference in new issue