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