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
{
///
/// 消费
///
public partial class UserService
{
///
/// 店铺续费手续费 15
///
private const int ShopRenewFee = 15;
///
/// 结算OEM流水
///
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()
.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;
}
///
/// 结算用户流水
///
///
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;
}
///
/// 1. 查询支付流水
/// 2. 计算OEM结算金额
/// 3. 查询续费流水
/// 4. 标记流水为已结算
///
/// 当前事务ORM
/// 需要结算的用户
///
private long SettleFlowsInternal(IFreeSql tr_freeSql, ICollection 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 UserPaymentTypeFiltert = [16, 20, 23, 26, 31, 34];
var paymentQuery = tr_freeSql.Select()
.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 ids = userPayments.Select(a => a.Id).ToList();
var userPaymentUnique = userPayments.GroupBy(a => //去重
new
{
a.Type,
a.OrderId
}).Select(a => a.First()).ToList();
//经过计算过滤后的列表
List userPaymentCalculated = new List();
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()
.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()
.Where(a => userNames.Contains(a.UserName))
.Where(a => a.OptionType == "续费")
.Where(a => a.Settlement == false)
.ToList();
if (userPoints.Count > 0)
{
List 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()
.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;
}
///
/// 获取用户金额统计
///
///
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 types = new List { 16, 20, 23, 24, 26, 31 };
var data = _freeSql.Select()
.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
{
///
/// 充值总额
///
public long RechargeTotal { get; set; }
///
/// 消费总额
///
public long ConsumeTotal { get; set; }
///
/// 剩余余额
///
public long Balance { get; set; }
}
}