288 lines
8.2 KiB
C#
288 lines
8.2 KiB
C#
using KJD_Web.Entitys;
|
||
using KJD_Web.Model.WxModel;
|
||
using MySqlX.XDevAPI;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data.Common;
|
||
using System.Diagnostics;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Web;
|
||
using static FreeSql.Internal.GlobalFilter;
|
||
|
||
namespace KJD_Web.Services.Users
|
||
{
|
||
/// <summary>
|
||
/// 消费
|
||
/// </summary>
|
||
public partial class UserService
|
||
{
|
||
/// <summary>
|
||
/// 店铺续费手续费 15
|
||
/// </summary>
|
||
private const int ShopRenewFee = 15;
|
||
|
||
/// <summary>
|
||
/// 结算OEM流水
|
||
/// </summary>
|
||
public OEMEntity SettleOemFlows(string userName, DbTransaction tarn = null)
|
||
{
|
||
throw new Exception("结算失败");
|
||
var oem = GetOEMByUserName(userName);
|
||
|
||
if (oem == null)
|
||
{
|
||
throw new Exception("错误的账号");
|
||
}
|
||
using var work = tarn != null ? _freeSql.CreateUnitOfWork(tarn) : _freeSql.CreateUnitOfWork();
|
||
var trFreeSql = work.Orm;
|
||
// 获取OEM下面的所有用户
|
||
var users = GetOEMUsers(oem.OemId, true);
|
||
|
||
var userNames = users
|
||
.Select(a => a.UserName)
|
||
.Where(a => !string.IsNullOrEmpty(a))
|
||
.Distinct()
|
||
.ToList();
|
||
|
||
if (userNames.Count == 0)
|
||
{//todo
|
||
throw new Exception("没有用户");
|
||
}
|
||
|
||
/*
|
||
* OEM结算规则:
|
||
*
|
||
* 只结算OEM创建之后产生的流水。
|
||
*
|
||
* CreateTime > oem.AddTime
|
||
*/
|
||
long totalFen = SettleFlowsInternal(
|
||
trFreeSql,
|
||
userNames,
|
||
oem.AddTime);
|
||
|
||
long rebateFen = totalFen;
|
||
|
||
|
||
if (totalFen != 0 || rebateFen != 0)
|
||
{
|
||
var affrows = trFreeSql
|
||
.Update<OEMEntity>()
|
||
.Set(a => new
|
||
{
|
||
AvailableBalance =
|
||
a.AvailableBalance + totalFen,
|
||
|
||
TotalRebateAmount =
|
||
a.TotalRebateAmount + rebateFen
|
||
})
|
||
.Where(a => a.OemId == oem.OemId)
|
||
.ExecuteAffrows();
|
||
|
||
if (affrows != 1)
|
||
{
|
||
throw new Exception("OEM余额更新失败");
|
||
}
|
||
}
|
||
|
||
work.Commit();
|
||
oem = GetOEMByUserName(userName, false);
|
||
return oem;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 结算用户流水
|
||
/// </summary>
|
||
/// <param name="userName"></param>
|
||
public long SettleUserFlows(string userName, DbTransaction tarn = null)
|
||
{
|
||
var user = GetUserAndSubUser(userName);
|
||
if (user == null)
|
||
{
|
||
throw new Exception("错误的账号");
|
||
}
|
||
using var work = tarn != null ? _freeSql.CreateUnitOfWork(tarn) : _freeSql.CreateUnitOfWork();
|
||
var trFreeSql = work.Orm;
|
||
var userNames = user.Select(a => a.UserName).ToList();
|
||
/* * 普通用户没有OEM创建时间限制。 * * 所以这里传null。 */
|
||
long totalAmount = SettleFlowsInternal(trFreeSql, userNames, null);
|
||
/* * 普通用户没有余额, * 所以不做任何金额更新。 */
|
||
Debug.WriteLine($"用户流水结算:{totalAmount}");
|
||
work.Commit();
|
||
return totalAmount;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 1. 查询支付流水
|
||
/// 2. 计算OEM结算金额
|
||
/// 3. 查询续费流水
|
||
/// 4. 标记流水为已结算
|
||
/// </summary>
|
||
/// <param name="orm">当前事务ORM</param>
|
||
/// <param name="userNames">需要结算的用户</param>
|
||
/// <param name="oemAddTime">
|
||
private long SettleFlowsInternal(IFreeSql tr_freeSql, ICollection<string> userNames, DateTime? oemAddTime)
|
||
{
|
||
if (userNames == null || userNames.Count == 0) { throw new Exception("没有用户"); }
|
||
decimal total_amount = 0m; // 总金额(元)
|
||
decimal rebate_amount = 0m; // 正数部分(累计返利)
|
||
DateTime now = DateTime.Now;
|
||
|
||
List<int> UserPaymentTypeFiltert = [16, 20, 23, 26, 31, 34];
|
||
var paymentQuery = tr_freeSql.Select<UserPaymentRecordEntity>()
|
||
.Where(a => userNames.Contains(a.UserName))
|
||
.Where(a => UserPaymentTypeFiltert.Contains(a.Type))
|
||
.Where(a => a.Settlement == 0)
|
||
.Where(a => a.IsDeleted == 0);
|
||
//只有OEM结算才限制OEM创建时间。
|
||
if (oemAddTime.HasValue)
|
||
{
|
||
paymentQuery = paymentQuery.Where(a => a.CreateTime > oemAddTime.Value);
|
||
}
|
||
paymentQuery.OrderBy(a => a.Id);
|
||
var userPayments = paymentQuery.ToList();
|
||
if (userPayments.Count > 0)
|
||
{
|
||
Debug.WriteLine(userPayments.Where(a => a.Type == 20).Sum(a => a.OemAmount));
|
||
///原始流水ID。
|
||
List<long> ids = userPayments.Select(a => a.Id).ToList();
|
||
|
||
var userPaymentUnique = userPayments.GroupBy(a => //去重
|
||
new
|
||
{
|
||
a.Type,
|
||
a.OrderId
|
||
}).Select(a => a.First()).ToList();
|
||
|
||
//经过计算过滤后的列表
|
||
List<UserPaymentRecordEntity> userPaymentCalculated = new List<UserPaymentRecordEntity>();
|
||
|
||
foreach (var item in userPaymentUnique)
|
||
{
|
||
if (item.Type == 20)
|
||
{
|
||
//item.OemAmount = item.Amount - 2.2m;
|
||
item.OemAmount = item.OemAmount;
|
||
}
|
||
else if (item.Type == 26)
|
||
{
|
||
//item.OemAmount = item.Amount - 2.5m;
|
||
item.OemAmount = item.OemAmount;
|
||
}
|
||
if (item.Type == 23)
|
||
{
|
||
var temp = userPaymentCalculated.FirstOrDefault(a => a.Type == 20 && a.OrderId == item.OrderId);
|
||
if (temp != null)
|
||
{
|
||
userPaymentCalculated.Remove(temp);//23 移除 20
|
||
}
|
||
continue;
|
||
}
|
||
else if (item.Type == 34)
|
||
{
|
||
item.OemAmount = item.OemAmount * -1;
|
||
}
|
||
userPaymentCalculated.Add(item);
|
||
}
|
||
decimal userPaymentAmount = userPaymentCalculated.Sum(x => x.OemAmount ?? 0);//累计返利
|
||
//StringBuilder sb = new StringBuilder();
|
||
//sb.AppendLine("id,order_id,type,amount,oem_amount,time");
|
||
//foreach (var item in userPayments)
|
||
//{
|
||
// sb.AppendLine($"{item.Id},{item.OrderId},{item.Type},{item.Amount},{item.OemAmount},{item.CreateTime}");
|
||
//}
|
||
total_amount += userPaymentAmount;
|
||
rebate_amount += userPaymentAmount;
|
||
|
||
Debug.WriteLine($"运费流水返利:{userPaymentAmount}");
|
||
var settlementCount = tr_freeSql.Update<UserPaymentRecordEntity>()
|
||
.Set(a => a.Settlement, (byte)1)
|
||
.Set(a => a.SettlementTime, now)
|
||
.Where(a => ids.Contains(a.Id))
|
||
.ExecuteAffrows();
|
||
if (settlementCount != ids.Count)
|
||
throw new Exception("运费流水结算失败");
|
||
|
||
}
|
||
|
||
|
||
|
||
var userPoints = tr_freeSql.Select<UserPointsRecordEntity>()
|
||
.Where(a => userNames.Contains(a.UserName))
|
||
.Where(a => a.OptionType == "续费")
|
||
.Where(a => a.Settlement == false)
|
||
.ToList();
|
||
if (userPoints.Count > 0)
|
||
{
|
||
List<long> ids = userPoints.Select(a => a.Id).ToList();
|
||
|
||
decimal userPointsAmount = userPoints.Sum(x =>
|
||
{
|
||
return x.DeltaPoints * 1 - ShopRenewFee; //比例1:1 减去固定收取费用
|
||
});//累计返利
|
||
|
||
|
||
total_amount += userPointsAmount;
|
||
rebate_amount += userPointsAmount;
|
||
|
||
Debug.WriteLine($"商铺月费返利:{userPointsAmount}");
|
||
var settlementCount = tr_freeSql.Update<UserPointsRecordEntity>()
|
||
.Set(a => a.Settlement, true)
|
||
.Set(a => a.SettlementTime, now)
|
||
.Where(a => ids.Contains(a.Id))
|
||
.ExecuteAffrows();
|
||
if (settlementCount != ids.Count)
|
||
throw new Exception("积分流水结算失败");
|
||
}
|
||
|
||
long total_fen = (long)Math.Round(total_amount * 100m);
|
||
//long rebate_fen = (long)Math.Round(rebate_amount * 100m);
|
||
|
||
return total_fen;
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 获取用户金额统计
|
||
/// </summary>
|
||
/// <param name="userName"></param>
|
||
|
||
public UserAmountSummary GetUserAmountSummary(string userName)
|
||
{
|
||
UserAmountSummary summary = new UserAmountSummary();
|
||
var user = GetUserByUserName(userName);
|
||
if (user == null) throw new Exception("错误的用户");
|
||
summary.RechargeTotal = (long)Math.Round((user.RechargeAmountTotal ?? 0) * 100m);
|
||
summary.Balance = (long)Math.Round((user.Balance ?? 0) * 100m);
|
||
List<int> types = new List<int> { 16, 20, 23, 24, 26, 31 };
|
||
|
||
|
||
var data = _freeSql.Select<UserPaymentRecordEntity>()
|
||
.Where(a => types.Contains(a.Type))
|
||
.Where(a => a.UserName == userName)
|
||
.ToList();
|
||
decimal sum = data.Sum(r => r.Type == 23 ? -(r.Amount ?? 0) : r.Amount ?? 0);
|
||
summary.ConsumeTotal = (long)Math.Round(sum * 100m);
|
||
return summary;
|
||
}
|
||
}
|
||
|
||
public class UserAmountSummary
|
||
{
|
||
/// <summary>
|
||
/// 充值总额
|
||
/// </summary>
|
||
public long RechargeTotal { get; set; }
|
||
/// <summary>
|
||
/// 消费总额
|
||
/// </summary>
|
||
public long ConsumeTotal { get; set; }
|
||
/// <summary>
|
||
/// 剩余余额
|
||
/// </summary>
|
||
public long Balance { get; set; }
|
||
}
|
||
} |