diff --git a/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalAuditRequest.cs b/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalAuditRequest.cs index a89d64e..5ef8100 100644 --- a/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalAuditRequest.cs +++ b/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalAuditRequest.cs @@ -1,3 +1,4 @@ +using KJD_Web.Requests; using System; using System.Collections.Generic; using System.Linq; diff --git a/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalQueryRequest.cs b/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalQueryRequest.cs index ff78222..7243ef8 100644 --- a/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalQueryRequest.cs +++ b/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalQueryRequest.cs @@ -1,3 +1,4 @@ +using KJD_Web.Requests; using System; using System.Collections.Generic; using System.Linq; diff --git a/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalRequest.cs b/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalRequest.cs index cd69832..440a711 100644 --- a/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalRequest.cs +++ b/KJD_WebService/BLL/WXXD/Requests/OemWithdrawalRequest.cs @@ -1,3 +1,4 @@ +using KJD_Web.Requests; using System; using System.Collections.Generic; using System.Linq; diff --git a/KJD_WebService/BLL/WXXD/Requests/SignRequestBase.cs b/KJD_WebService/BLL/WXXD/Requests/SignRequestBase.cs deleted file mode 100644 index acacb12..0000000 --- a/KJD_WebService/BLL/WXXD/Requests/SignRequestBase.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace KJD_Web.BLL.WXXD.Requests -{ - /// - /// 卡名请求 - /// - public class SignRequestBase - { - public string time { get; set; } - public string code { get; set; } - public string code_version { get; set; } - public string version { get; set; } - public string user_name { get; set; } - public string path { get; set; } - } -} diff --git a/KJD_WebService/BLL/WXXD/WXOemManage.cs b/KJD_WebService/BLL/WXXD/WXOemManage.cs index df19a4c..e77a09e 100644 --- a/KJD_WebService/BLL/WXXD/WXOemManage.cs +++ b/KJD_WebService/BLL/WXXD/WXOemManage.cs @@ -2,6 +2,7 @@ using KJD_Web.BLL.WXXD.Dtos; using KJD_Web.BLL.WXXD.Requests; using KJD_Web.Model; using KJD_Web.Model.WxModel; +using KJD_Web.Requests; using KJD_Web.Utils; using NaiBa.Util.Extension; using NaiBa.Util.Helper; @@ -165,14 +166,14 @@ namespace KJD_Web.BLL.WXXD try { - if (request == null || request.user_name.IsNullOrEmpty()) + if (request == null || request.UserName.IsNullOrEmpty()) throw new Exception("参数错误:缺少用户名"); List oemIdLst = new List(); - var user = new WXUserManage().GetUserByUserName(request.user_name); + var user = new WXUserManage().GetUserByUserName(request.UserName); if (user.sa_level != 1)//非管理员 判断 是否Oem 管理员 { - var oems = GetOems(new List { request.user_name }); + var oems = GetOems(new List { request.UserName }); if (oems == null || oems.Any() == false) { throw new Exception("错误的账号"); @@ -239,11 +240,17 @@ namespace KJD_Web.BLL.WXXD // total_rebate_amount = x.total_rebate_amount, // total_withdraw_amount = x.total_withdraw_amount, //}).ToList(); - ret = new PageResult(); + + var pageData = new ApiPageResult + { + PageIndex = page, + PageSize = page_size, + List = list, + Total = count, + }; ret.Code = 200; ret.Msg = "success"; - ret.Data = list; - (ret as PageResult).Total = count; + ret.Data = pageData; } catch (Exception ex) { @@ -264,11 +271,11 @@ namespace KJD_Web.BLL.WXXD try { - if (request == null || request.user_name.IsNullOrEmpty()) + if (request == null || request.UserName.IsNullOrEmpty()) throw new Exception("参数错误:缺少用户名"); - var oems = GetOems(new List { request.user_name }); + var oems = GetOems(new List { request.UserName }); if (oems == null || oems.Any() == false) { throw new Exception("错误的账号"); @@ -291,7 +298,7 @@ namespace KJD_Web.BLL.WXXD { mySql.Close(); } - oems = GetOems(new List { request.user_name }); + oems = GetOems(new List { request.UserName }); if (oems == null || oems.Any() == false) { throw new Exception("错误的账号"); @@ -330,7 +337,7 @@ namespace KJD_Web.BLL.WXXD string client_ip = ""; try { - if (request == null || request.user_name.IsNullOrEmpty()) + if (request == null || request.UserName.IsNullOrEmpty()) throw new Exception("参数错误:缺少用户名"); if (request.amount <= 0) throw new Exception("提现金额必须大于0"); @@ -346,7 +353,7 @@ namespace KJD_Web.BLL.WXXD if (request.account_no.IsNullOrEmpty()) throw new Exception("收款账号不能为空"); - var oems = GetOems(new List { request.user_name }); + var oems = GetOems(new List { request.UserName }); if (oems == null || oems.Any() == false) { throw new Exception("错误的账号"); @@ -426,7 +433,7 @@ namespace KJD_Web.BLL.WXXD "(withdrawal_no,oem_id,apply_user_name,amount,fee,actual_amount,balance_before,balance_after," + "withdrawal_type,account_name,account_no,bank_name,bank_branch," + "status,audit_by,audit_time,audit_remark,remark,client_ip,version,is_deleted,created_at,updated_at) VALUES (" + - "'" + withdrawal_no + "','" + oemInfo.oem_id + "','" + MysqlUtils.ReplaceSqlSpecial(request.user_name) + "'," + + "'" + withdrawal_no + "','" + oemInfo.oem_id + "','" + MysqlUtils.ReplaceSqlSpecial(request.UserName) + "'," + amount_fen + "," + fee_fen + "," + actual_fen + "," + available_fen + "," + balance_after_fen + "," + (int)request.withdrawal_type + ",'" + MysqlUtils.ReplaceSqlSpecial(request.account_name) + "','" + MysqlUtils.ReplaceSqlSpecial(request.account_no) + "'," + "'" + MysqlUtils.ReplaceSqlSpecial(request.bank_name) + "','" + MysqlUtils.ReplaceSqlSpecial(request.bank_branch) + "'," + @@ -479,9 +486,9 @@ namespace KJD_Web.BLL.WXXD throw new Exception("参数错误:缺少提现单号"); if (request.audit_result != (int)OemWithdrawalStatus.Approved && request.audit_result != (int)OemWithdrawalStatus.Rejected) throw new Exception("审核结果不合法:1审核通过 2审核拒绝"); - if (request.user_name.IsNullOrEmpty()) + if (request.UserName.IsNullOrEmpty()) throw new Exception("审核人不能为空"); - var user = new WXUserManage().GetUserByUserName(request.user_name); + var user = new WXUserManage().GetUserByUserName(request.UserName); if (user.sa_level != 1) { throw new Exception("无权限审核"); @@ -534,7 +541,7 @@ namespace KJD_Web.BLL.WXXD throw new Exception("更新账户余额失败"); if (request.audit_result == 1) request.audit_result = (int)OemWithdrawalStatus.Paid; //已付款 sql = "UPDATE wxxd.oem_withdrawal SET status=" + request.audit_result + - ",audit_by='" + MysqlUtils.ReplaceSqlSpecial(request.user_name) + + ",audit_by='" + MysqlUtils.ReplaceSqlSpecial(request.UserName) + "',audit_time='" + now + "',audit_remark='" + MysqlUtils.ReplaceSqlSpecial(audit_remark) + "',updated_at='" + now + diff --git a/KJD_WebService/Controllers/ApiControllerBase.cs b/KJD_WebService/Controllers/ApiControllerBase.cs new file mode 100644 index 0000000..efcf700 --- /dev/null +++ b/KJD_WebService/Controllers/ApiControllerBase.cs @@ -0,0 +1,60 @@ +using KJD_Web.Model; +using KJD_Web.Requests; +using KJD_Web.Utils; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using System.Web; +using System.Web.Http; +using System.Web.Http.Controllers; + +namespace KJD_Web.Controllers; + +public abstract class ApiControllerBase : ApiController +{ + + protected bool ValidateSign(SignRequestBase request, bool isUserLogin = false) + { + if (request == null || string.IsNullOrEmpty(request.time) || string.IsNullOrEmpty(request.code)) + { + return false; + } + + int time; + if (!int.TryParse(request.time, out time)) + { + return false; + } + if (request.code != EncrypUtil.Encryption(time)) + { + return false; + } + if (!isUserLogin && string.IsNullOrWhiteSpace(request.UserName)) + { + return false; + } + + return true; + } + private bool IsAllowAnonymous(HttpActionContext context) + { + // Action 上 + if (context.ActionDescriptor.GetCustomAttributes().Any()) + return true; + // Controller 上 + if (context.ControllerContext.ControllerDescriptor.ControllerType + .GetCustomAttributes(typeof(AllowAnonymousAttribute), true).Any()) + return true; + return false; + } + private async Task OkResponseAsync(object content) + { + IHttpActionResult result = Ok(content); + return await result.ExecuteAsync(CancellationToken.None); + } +} \ No newline at end of file diff --git a/KJD_WebService/Controllers/AsmxApiController.cs b/KJD_WebService/Controllers/AsmxApiController.cs index ecd8520..62faf5f 100644 --- a/KJD_WebService/Controllers/AsmxApiController.cs +++ b/KJD_WebService/Controllers/AsmxApiController.cs @@ -1,8 +1,9 @@ using KJD_Web.BLL.WXXD; -using KJD_Web.BLL.WXXD.Requests; +using KJD_Web.Requests; using KJD_Web.Utils; using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.IO; using System.Linq; using System.Net; @@ -14,7 +15,7 @@ using System.Web.Http.Controllers; namespace KJD_Web.Controllers { - public class AsmxApiController : ApiController + public class AsmxApiController : ApiControllerBase { //public override System.Threading.Tasks.Task ExecuteAsync( //HttpControllerContext controllerContext, @@ -28,56 +29,64 @@ namespace KJD_Web.Controllers // return base.ExecuteAsync(controllerContext, cancellationToken); //} - protected bool ValidateSign(SignRequestBase request, bool isUserLogin = false) - { - if (request == null || string.IsNullOrEmpty(request.time) || string.IsNullOrEmpty(request.code)) - { - return false; - } - - int time; - if (!int.TryParse(request.time, out time)) - { - return false; - } - if (request.code != EncrypUtil.Encryption(time)) - { - return false; - } - if (!isUserLogin && string.IsNullOrWhiteSpace(request.user_name)) - { - return false; - } - - return true; - } + protected string GetRequestJsonString() { //Context.Response.ContentType = "text/html;charset=utf-8"; //Context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8"); - - using (Stream s = HttpContext.Current.Request.InputStream) // 获得json 字符流 + object raw; + if (Request.Properties.TryGetValue("RawBody", out raw)) { - // 还原数据流 - byte[] b = new byte[s.Length]; - s.Read(b, 0, (int)s.Length); - string jsonText = Encoding.UTF8.GetString(b); // JSON字符串 - if (string.IsNullOrEmpty(jsonText)) - { - var qs = HttpContext.Current.Request.QueryString; - if (qs != null && qs.Keys.Count > 0) - { - jsonText = "{"; - foreach (var key in qs.Keys) - { - jsonText += "\"" + key + "\":" + "\"" + qs[key.ToString()] + "\";"; - } - jsonText = jsonText.TrimEnd(';') + "}"; - } - } - return jsonText; + return raw as string; } + //using (Stream s = HttpContext.Current.Request.InputStream) // 获得json 字符流 + //{ + // // 还原数据流 + // byte[] b = new byte[s.Length]; + // s.Read(b, 0, (int)s.Length); + // string jsonText = Encoding.UTF8.GetString(b); // JSON字符串 + // if (string.IsNullOrEmpty(jsonText)) + // { + // var qs = HttpContext.Current.Request.QueryString; + // if (qs != null && qs.Keys.Count > 0) + // { + // jsonText = "{"; + // foreach (var key in qs.Keys) + // { + // jsonText += "\"" + key + "\":" + "\"" + qs[key.ToString()] + "\";"; + // } + // jsonText = jsonText.TrimEnd(';') + "}"; + // } + // } + // return jsonText; + //} + + var request = HttpContext.Current.Request; + + // 优先用 Web API 的 Content + var content = System.Web.HttpContext.Current?.Items["MS_HttpRequestMessage"] + as System.Net.Http.HttpRequestMessage; + + string jsonText = null; + if (content?.Content != null) + { + jsonText = content.Content.ReadAsStringAsync().Result; + } + + if (string.IsNullOrEmpty(jsonText)) + { + var qs = request.QueryString; + if (qs != null && qs.Keys.Count > 0) + { + var sb = new StringBuilder("{"); + foreach (string key in qs.Keys) + sb.Append($"\"{key}\":\"{qs[key]}\","); + jsonText = sb.ToString().TrimEnd(',') + "}"; + } + } + return jsonText; + } protected IHttpActionResult JsonString(string result) { diff --git a/KJD_WebService/Controllers/WX/OEMController.cs b/KJD_WebService/Controllers/WX/OEMController.cs new file mode 100644 index 0000000..65a4cc5 --- /dev/null +++ b/KJD_WebService/Controllers/WX/OEMController.cs @@ -0,0 +1,55 @@ +using KJD_Web.Model; +using KJD_Web.Requests.Users; +using KJD_Web.Responses.Users; +using KJD_Web.Services.Users; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Http; +using Ubiety.Dns.Core; + +namespace KJD_Web.Controllers; + +[RoutePrefix("wxxd_oem")] +[Route("{action}")] +public class OEMController : ApiControllerBase +{ + private readonly UserService _userService; + + public OEMController(UserService userService) + { + _userService = userService; + } + [HttpPost] + public IHttpActionResult GetRebateRecords(RebateRecordRequest request) + { + //if (!ValidateSign(request)) + //{ + // return Ok(ApiResult.Fail("校验失败", 999)); + //} + try + { + var ret = _userService.GetRebateRecords(request); + return Ok(ApiResult.Success(new ApiPageResult + { + PageIndex = request.PageIndex, + PageSize = request.PageSize, + List = ret.List, + Total = ret.Total + }, "续费成功")); + } + catch (ArgumentException ex) + { + return Ok(ApiResult.Fail(ex.Message, ResultCode.ValidationError)); + } + catch (InvalidOperationException ex) + { + return Ok(ApiResult.Fail(ex.Message, ResultCode.BusinessError)); + } + catch + { + return Ok(ApiResult.Fail("查询失败", ResultCode.ServerError)); + } + } +} \ No newline at end of file diff --git a/KJD_WebService/Controllers/WX/WXUserController.cs b/KJD_WebService/Controllers/WX/WXUserController.cs index 2988125..f42970f 100644 --- a/KJD_WebService/Controllers/WX/WXUserController.cs +++ b/KJD_WebService/Controllers/WX/WXUserController.cs @@ -1,4 +1,5 @@ using KJD_Web.BLL.WXXD; +using KJD_Web.Requests; using NaiBa.Util.Extension; using System; using System.Collections.Generic; @@ -31,7 +32,7 @@ namespace KJD_Web.Controllers return JsonString(result); } - + [AllowAnonymous] public IHttpActionResult user_login() { string jsontext = GetRequestJsonString(); @@ -285,7 +286,7 @@ namespace KJD_Web.Controllers string jsontext = GetRequestJsonString(); var result = jsontext; - var request = jsontext.ParseToObject(); + var request = jsontext.ParseToObject(); result = new WXOemManage().SettleOemFlows(request); return JsonString(result); diff --git a/KJD_WebService/Entitys/OEMEntity.cs b/KJD_WebService/Entitys/OEMEntity.cs new file mode 100644 index 0000000..c60672c --- /dev/null +++ b/KJD_WebService/Entitys/OEMEntity.cs @@ -0,0 +1,93 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace KJD_Web.Entitys; + + +/// +/// OEM贴牌表 +/// +[Table(Name = "wxxd.oem")] +public class OEMEntity +{ + /// + /// id + /// + [Column(Name = "id", IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } + + /// + /// oem_id + /// + [Column(Name = "oem_id")] + public string OemId { get; set; } + + /// + /// 贴牌名称 + /// + [Column(Name = "oem_name")] + public string OemName { get; set; } + + /// + /// 贴牌管理人主账户 + /// + [Column(Name = "oem_owner")] + public string OemOwner { get; set; } + + /// + /// 图标 + /// + [Column(Name = "oem_icon")] + public string OemIcon { get; set; } + + /// + /// 题图 + /// + [Column(Name = "oem_img")] + public string OemImg { get; set; } + + /// + /// add_time + /// + [Column(Name = "add_time")] + public DateTime AddTime { get; set; } + + /// + /// mdy_time + /// + [Column(Name = "mdy_time")] + public DateTime MdyTime { get; set; } + + /// + /// is_del + /// + [Column(Name = "is_del")] + public byte IsDel { get; set; } + + /// + /// 可提现余额,单位分 + /// + [Column(Name = "available_balance")] + public long AvailableBalance { get; set; } + + /// + /// 冻结余额,单位分 + /// + [Column(Name = "frozen_balance")] + public long FrozenBalance { get; set; } + + /// + /// 累计返利金额,单位分 + /// + [Column(Name = "total_rebate_amount")] + public long TotalRebateAmount { get; set; } + + /// + /// 累计提现金额,单位分 + /// + [Column(Name = "total_withdraw_amount")] + public long TotalWithdrawAmount { get; set; } +} diff --git a/KJD_WebService/Entitys/UserPaymentRecordEntity.cs b/KJD_WebService/Entitys/UserPaymentRecordEntity.cs new file mode 100644 index 0000000..4854617 --- /dev/null +++ b/KJD_WebService/Entitys/UserPaymentRecordEntity.cs @@ -0,0 +1,125 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace KJD_Web.Entitys; + +[Table(Name = "wxxd.user_payment_record")] +public class UserPaymentRecordEntity +{ + /// + /// id + /// + [Column(Name = "id", IsPrimary = true, IsIdentity = true)] + public long Id { get; set; } + + /// + /// 变动类型,1:充值,2:采购花费,3:产品退款到账,4:运费退款到账,5:采购收款,6:产品退款扣除,7:运费退款扣除, 16:礼物单话费,20:中转仓扣费支出,23:中转仓退款收入 + /// + [Column(Name = "type")] + public int Type { get; set; } + + /// + /// 金额(元) + /// + [Column(Name = "amount")] + public decimal? Amount { get; set; } + + /// + /// 归属oem用户的金额 + /// + [Column(Name = "oem_amount")] + public decimal? OemAmount { get; set; } + + /// + /// 余额(元) + /// + [Column(Name = "balance")] + public decimal? Balance { get; set; } + + /// + /// 账户名 + /// + [Column(Name = "user_name")] + public string UserName { get; set; } + + /// + /// 平台编码 + /// + [Column(Name = "platform_code")] + public string PlatformCode { get; set; } + + /// + /// 订单id + /// + [Column(Name = "order_id")] + public string OrderId { get; set; } + + /// + /// 售后单id + /// + [Column(Name = "after_sale_id")] + public long AfterSaleId { get; set; } + + /// + /// 创建人 + /// + [Column(Name = "create_by")] + public string CreateBy { get; set; } + + /// + /// 创建时间 + /// + [Column(Name = "create_time")] + public DateTime CreateTime { get; set; } + + /// + /// 修改人 + /// + [Column(Name = "update_by")] + public string UpdateBy { get; set; } + + /// + /// 修改时间 + /// + [Column(Name = "update_time")] + public DateTime? UpdateTime { get; set; } + + /// + /// 是否已删除 + /// + [Column(Name = "is_deleted")] + public int? IsDeleted { get; set; } + + /// + /// 备注 + /// + [Column(Name = "remark")] + public string Remark { get; set; } + + /// + /// 扣款的对方账户名称 + /// + [Column(Name = "counterparty_account_name")] + public string CounterpartyAccountName { get; set; } + + /// + /// OEM是否结算 0未结算 1已结算 + /// + [Column(Name = "settlement")] + public byte? Settlement { get; set; } + + /// + /// 退款流水号 外采&订单号 + /// + [Column(Name = "refund_flow_no")] + public string RefundFlowNo { get; set; } + + /// + /// 结算时间 + /// + [Column(Name = "settlement_time")] + public DateTime? SettlementTime { get; set; } +} \ No newline at end of file diff --git a/KJD_WebService/KJD_WebService.csproj b/KJD_WebService/KJD_WebService.csproj index 654cf08..0f0a2bb 100644 --- a/KJD_WebService/KJD_WebService.csproj +++ b/KJD_WebService/KJD_WebService.csproj @@ -182,7 +182,6 @@ - @@ -190,8 +189,10 @@ + + @@ -218,6 +219,11 @@ + + + + + @@ -265,7 +271,9 @@ + + diff --git a/KJD_WebService/Model/ApiResult.cs b/KJD_WebService/Model/ApiResult.cs index 0e11e13..b8d40cb 100644 --- a/KJD_WebService/Model/ApiResult.cs +++ b/KJD_WebService/Model/ApiResult.cs @@ -1,4 +1,7 @@ +using System; +using System.Collections.Generic; + namespace KJD_Web.Model { public static class ResultCode @@ -64,5 +67,23 @@ namespace KJD_Web.Model => new ApiResult { Code = code, Msg = msg }; } - + public class ApiPageResult: ApiResult + { + public long Total { get; set; } + public int PageIndex { get; set; } + public int PageSize { get; set; } + public int TotalPages => PageSize > 0 ? (int)Math.Ceiling((double)Total / PageSize) : 0; + public List List { get; set; } = new(); + public ApiPageResult() { } + + public ApiPageResult(List list, long total, int pageIndex, int pageSize) + { + List = list; + Total = total; + PageIndex = pageIndex; + PageSize = pageSize; + } + } + + } diff --git a/KJD_WebService/Model/Result.cs b/KJD_WebService/Model/Result.cs index 9ac1e2d..0d25775 100644 --- a/KJD_WebService/Model/Result.cs +++ b/KJD_WebService/Model/Result.cs @@ -44,10 +44,4 @@ namespace KJD_Web.Model } } - - public class PageResult : Result - { - public int Page { get; set; } - public int Total { get; set; } - } } diff --git a/KJD_WebService/Requests/RequestBase.cs b/KJD_WebService/Requests/RequestBase.cs new file mode 100644 index 0000000..77cc3f2 --- /dev/null +++ b/KJD_WebService/Requests/RequestBase.cs @@ -0,0 +1,41 @@ +using Newtonsoft.Json; +using System; + +namespace KJD_Web.Requests; + +/// +/// 卡名请求 +/// +public class SignRequestBase +{ + public string time { get; set; } + public string code { get; set; } + public string code_version { get; set; } + public string version { get; set; } + [JsonProperty("user_name")] + public string UserName { get; set; } + public string path { get; set; } +} + + + +public class SearchRequest : SignRequestBase +{ + private int _pageIndex = 1; + private int _pageSize = 20; + + public int PageIndex + { + get => _pageIndex; + set => _pageIndex = value < 1 ? 1 : (value > 1000 ? 1000 : value); + } + + public int PageSize + { + get => _pageSize; + set => _pageSize = value < 20 ? 20 : (value > 2000 ? 2000 : value); + } + public DateTime? StartTime { get; set; } + public DateTime? EndTime { get; set; } + +} \ No newline at end of file diff --git a/KJD_WebService/Requests/Users/RebateRecordRequest.cs b/KJD_WebService/Requests/Users/RebateRecordRequest.cs new file mode 100644 index 0000000..46288c2 --- /dev/null +++ b/KJD_WebService/Requests/Users/RebateRecordRequest.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace KJD_Web.Requests.Users; + +public class RebateRecordRequest : SearchRequest +{ + /// + /// 0 运费消费 + /// 1 积分消费 + /// + public int Type { get; set; } +} \ No newline at end of file diff --git a/KJD_WebService/Requests/Users/ShopRenewRequest.cs b/KJD_WebService/Requests/Users/ShopRenewRequest.cs index 194ace6..0a2b49a 100644 --- a/KJD_WebService/Requests/Users/ShopRenewRequest.cs +++ b/KJD_WebService/Requests/Users/ShopRenewRequest.cs @@ -1,5 +1,4 @@ -using KJD_Web.BLL.WXXD.Requests; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Web; @@ -11,11 +10,6 @@ namespace KJD_Web.Requests.Users /// public class ShopRenewRequest : SignRequestBase { - public string UserName - { - get { return user_name; } - set { user_name = value; } - } /// /// 店铺ID /// diff --git a/KJD_WebService/Responses/Users/RebateRecordResponse.cs b/KJD_WebService/Responses/Users/RebateRecordResponse.cs new file mode 100644 index 0000000..7e1715a --- /dev/null +++ b/KJD_WebService/Responses/Users/RebateRecordResponse.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace KJD_Web.Responses.Users; + +/// +/// 返现记录返回 +/// +public class RebateRecordResponse +{ + public string UserName { get; set; } + public long Amount { get; set; } + public long Rebate { get; set; } + public DateTime CreateTime { get; set; } +} \ No newline at end of file diff --git a/KJD_WebService/Services/Users/UserService.OEM.cs b/KJD_WebService/Services/Users/UserService.OEM.cs new file mode 100644 index 0000000..8387f4e --- /dev/null +++ b/KJD_WebService/Services/Users/UserService.OEM.cs @@ -0,0 +1,124 @@ +using FreeSql.Internal.Model; +using KJD_Web.Entitys; +using KJD_Web.Requests.Users; +using KJD_Web.Responses.Users; +using MAX.Core.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace KJD_Web.Services.Users; + +public partial class UserService +{ + private static List OEMData = null; + + public OEMEntity GetOEMByUserName(string userName) + { + if (string.IsNullOrEmpty(userName)) return null; + + if (OEMData == null) + { + OEMData = _freeSql.Select().ToList(); + + } + return OEMData.FirstOrDefault(a => a.OemOwner == userName); + } + /// + /// 获取所有OEM用户包含子用户 + /// + /// + /// + public List GetOEMUsers(string oemId, bool includeSu = true) + { + // 1. 该 oem 下的主账号 + string s = _freeSql.Select().Where(u => u.OemId == oemId).ToSql(); + var mainUsers = _freeSql.Select() + .Where(u => u.OemId == oemId) + .ToList(); + var allUsers = mainUsers; + + if (includeSu) + { + // 2. 主账号的 UserName + var mainUserNames = mainUsers.Select(u => u.UserName).ToList(); + // 3. 这些主账号对应的子账号 + var subUsers = mainUserNames.Count == 0 + ? new List() + : _freeSql.Select() + .Where(u => mainUserNames.Contains(u.ParentUserName)) + .ToList(); + + // 4. 合并,去重 + allUsers = mainUsers + .Concat(subUsers) + .Distinct() + .ToList(); + } + return allUsers; + } + /// + /// 获取返利记录 + /// + public (List List, long Total) GetRebateRecords(RebateRecordRequest request) + { + long total = 0; + List list = new List(); + var oem = GetOEMByUserName(request.UserName); + if (oem == null) + throw new Exception("无权限"); + + if (request.Type == 0) //运费流水 + { + var users = GetOEMUsers(oem.OemId); + var userNames = users.Select(u => u.UserName).ToList(); + List types = [20, 23, 26, 16, 31, 34]; + + var query = _freeSql.Select() + .Where(a => types.Contains(a.Type)) + .Where(a => userNames.Contains(a.UserName)) + .Where(a => a.CreateTime >= request.StartTime && a.CreateTime <= request.EndTime) + .OrderByDescending(a => a.CreateTime) + .Count(out total) + .Page(request.PageIndex, request.PageSize); + string sq = query.ToSql(); + var data = query.ToList(); + foreach (var item in data) + { + list.Add(new RebateRecordResponse + { + UserName = item.UserName, + Amount = (long)Math.Round((item.Amount ?? 0) * 100m), + Rebate = (long)Math.Round((item.OemAmount ?? 0) * 100m), + CreateTime = item.CreateTime + }); + } + } + else + { + var users = GetOEMUsers(oem.OemId, false); + var userNames = users.Select(u => u.UserName).ToList(); + var data = _freeSql.Select() + .Where(a => a.OptionType == "续费") + .Where(a => userNames.Contains(a.UserName)) + .Where(a => a.AddTime >= request.StartTime && a.AddTime <= request.EndTime) + .OrderByDescending(a => a.AddTime) + .Count(out total) + .Page(request.PageIndex, request.PageSize) + .ToList(); + foreach (var item in data) + { + list.Add(new RebateRecordResponse + { + UserName = item.UserName, + Amount = (long)Math.Round(item.DeltaPoints * 100m), + Rebate = (long)Math.Round((item.DeltaPoints - 15m) * 100m), + CreateTime = item.AddTime + }); + + } + } + return (list, total); + } +} \ No newline at end of file diff --git a/KJD_WebService/Services/Users/UserService.cs b/KJD_WebService/Services/Users/UserService.cs index f4c167f..fe65dc7 100644 --- a/KJD_WebService/Services/Users/UserService.cs +++ b/KJD_WebService/Services/Users/UserService.cs @@ -11,8 +11,11 @@ using YourNamespace; namespace KJD_Web.Services.Users { - public class UserService : ITransientDependency + public partial class UserService : ITransientDependency { + /// + /// 商铺续费每月30 + /// private const int MinShopPointsPerMonth = 30; private const int UserNameMaxLength = 20; private const int ShopIdMaxLength = 50; @@ -26,6 +29,16 @@ namespace KJD_Web.Services.Users _freeSql = freeSql ?? throw new ArgumentNullException(nameof(freeSql)); } + public bool IsOem(string userName) + { + return GetOEMByUserName(userName) != null; + } + + public UserEntity GetUserByUserName(string userName) + { + if (string.IsNullOrEmpty(userName)) return null; + return _freeSql.Select().Where(a => a.UserName == userName).First(); + } /// /// 商铺续费 /// diff --git a/KJD_WebService/SignValidateFilterAttribute.cs b/KJD_WebService/SignValidateFilterAttribute.cs new file mode 100644 index 0000000..8af3efc --- /dev/null +++ b/KJD_WebService/SignValidateFilterAttribute.cs @@ -0,0 +1,153 @@ +using KJD_Web.Model; +using KJD_Web.Requests; +using KJD_Web.Utils; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using System.Web; +using System.Web.Http; +using System.Web.Http.Controllers; +using System.Web.Http.Filters; + +namespace KJD_Web; + +public class SignValidateFilterAttribute: Attribute, IAuthorizationFilter +{ + public bool AllowMultiple => false; + + public async Task ExecuteAuthorizationFilterAsync( + HttpActionContext actionContext, + CancellationToken cancellationToken, + Func> continuation) + { + if (IsAllowAnonymous(actionContext)) + { + return await continuation(); + } + + var request = actionContext.Request; + + string rawBody = null; + string contentType = null; + if (request.Content != null) + { + contentType = request.Content.Headers.ContentType?.MediaType?.ToLower(); + rawBody = await request.Content.ReadAsStringAsync(); // 此时 Model Binding 还没跑,body 是干净的 + } + + var signRequest = ParseRequest(rawBody, contentType, request); + if (signRequest == null) + { + return request.CreateResponse(HttpStatusCode.OK, + ApiResult.Fail("校验失败", 999)); + } + + if (!ValidateSign(signRequest)) + { + return request.CreateResponse(HttpStatusCode.OK, + ApiResult.Fail("校验失败", 999)); + } + + // 回填,供后续 Model Binding 读取 + RefillBody(request, rawBody, contentType); + + // 放行,继续走后面的管道(Model Binding → Action Filter → Action) + return await continuation(); + } + + private bool IsAllowAnonymous(HttpActionContext context) + { + // Action 上 + if (context.ActionDescriptor.GetCustomAttributes().Any()) + return true; + // Controller 上 + if (context.ControllerContext.ControllerDescriptor.ControllerType + .GetCustomAttributes(typeof(AllowAnonymousAttribute), true).Any()) + return true; + return false; + } + private SignRequestBase ParseRequest(string rawBody, string contentType, HttpRequestMessage request) + { + if (contentType != null && contentType.Contains("json")) + { + if (!string.IsNullOrWhiteSpace(rawBody)) + { + try { return JsonConvert.DeserializeObject(rawBody); } + catch { } + } + } + else if (contentType != null && contentType.Contains("x-www-form-urlencoded")) + { + if (!string.IsNullOrWhiteSpace(rawBody)) + { + var form = System.Web.HttpUtility.ParseQueryString(rawBody); + return FromNameValue(form); + } + } + + var query = request.RequestUri.ParseQueryString(); + if (query.Count > 0) return FromNameValue(query); + + return null; + } + private SignRequestBase FromNameValue(NameValueCollection data) + { + var obj = new SignRequestBase(); + foreach (var prop in typeof(SignRequestBase).GetProperties()) + { + if (!prop.CanWrite) continue; + var val = data[prop.Name]; + if (string.IsNullOrEmpty(val)) continue; + try + { + var targetType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType; + prop.SetValue(obj, Convert.ChangeType(val, targetType)); + } + catch { } + } + return obj; + } + + + private void RefillBody(HttpRequestMessage request, string rawBody, string contentType) + { + if (string.IsNullOrEmpty(rawBody) || contentType == null) return; + if (!contentType.Contains("json") && !contentType.Contains("x-www-form-urlencoded")) return; + + var newContent = new StringContent(rawBody); + newContent.Headers.ContentType = + System.Net.Http.Headers.MediaTypeHeaderValue.Parse(contentType); + request.Content = newContent; + } + + + private bool ValidateSign(SignRequestBase request, bool isUserLogin = false) + { + if (request == null || string.IsNullOrEmpty(request.time) || string.IsNullOrEmpty(request.code)) + { + return false; + } + + int time; + if (!int.TryParse(request.time, out time)) + { + return false; + } + if (request.code != EncrypUtil.Encryption(time)) + { + return false; + } + if (!isUserLogin && string.IsNullOrWhiteSpace(request.UserName)) + { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/KJD_WebService/WebApiConfig.cs b/KJD_WebService/WebApiConfig.cs index c57fb86..e5d6a7a 100644 --- a/KJD_WebService/WebApiConfig.cs +++ b/KJD_WebService/WebApiConfig.cs @@ -29,6 +29,8 @@ namespace KJD_Web jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); + + //config.Filters.Add(new SignValidateFilterAttribute()); config.Formatters.Remove(config.Formatters.XmlFormatter); config.Filters.Add(new NotFoundMessageFilter()); config.MessageHandlers.Add(new NotFoundMessageHandler()); diff --git a/test/WebServiceTest/UnitTest1.cs b/test/WebServiceTest/UnitTest1.cs index e42cbce..b391069 100644 --- a/test/WebServiceTest/UnitTest1.cs +++ b/test/WebServiceTest/UnitTest1.cs @@ -21,7 +21,7 @@ namespace WebServiceTest WXOemManage manage = new WXOemManage(); string ret = manage.OemWithdrawals(new KJD_Web.BLL.WXXD.Requests.OemWithdrawalQueryRequest { - user_name = "18990991234", + UserName = "18990991234", }); Console.WriteLine(ret); } @@ -38,7 +38,7 @@ namespace WebServiceTest WXOemManage manage = new WXOemManage(); var ret = manage.SettleOemFlows(new KJD_Web.BLL.WXXD.Requests.OemWithdrawalRequest { - user_name = "13388889999", + UserName = "13388889999", }); Console.WriteLine(ret); @@ -69,7 +69,7 @@ namespace WebServiceTest WXOemManage manage = new WXOemManage(); var ret = manage.ApplyOemWithdrawal(new KJD_Web.BLL.WXXD.Requests.OemWithdrawalRequest { - user_name = name, + UserName = name, amount = 10, withdrawal_type = KJD_Web.BLL.WXXD.Requests.WithdrawalType.Alipay, account_name = UserName,