using System.Data; using System.Threading.Tasks; using System; using JiaZhiQuan.Common.Config; using Wicture.DbRESTFul; using Wicture.DbRESTFul.Infrastructure.Repository; namespace JiaZhiQuan.Common { public static partial class RepositoryExtension { /// /// C2C确认收货,不包含分账 /// /// 订单号 /// 买家编号,如果为0,表示系统自动确认收货 /// 是否执行成功 public static async Task MallOrderConfirmReceipt(this DbRESTFulRepository repository, ConfigFromDb config, long orderId, long userId) { var count = 0; var ratingExpireAt = DateTime.Now.AddHours(config.MallOrderRatingTimeoutHours); using (var conn = repository.ConnectionManager.GetConnection(false)) { conn.Open(); var trans = conn.BeginTransaction(); try { count = await repository.QuerySingleOrDefaultAsync(@$"update mall_order set orderState={(int)MallOrderState.交易成功}, userRatingState={(int)MallOrderRatingState.待评}, sellerRatingState={(int)MallOrderRatingState.待评}, userRatingExpireAt='{ratingExpireAt:yyyy-MM-dd HH:mm:ss}', sellerRatingExpireAt='{ratingExpireAt:yyyy-MM-dd HH:mm:ss}' where orderId={orderId} and orderState={(int)MallOrderState.待收货}; select row_count() as count;", null, conn, trans); if (count > 0) { await repository.QueryAsync( $@"insert into mall_order_change_events(orderId, eventName, eventDesc, operatorId, operatorType, createAt) values ( @orderId, @eventName, @eventDesc, {userId}, @operatorType, now())", new { orderId, eventName = userId > 0 ? "【交易成功】买家主动确认收货" : "【交易成功】买家超时未确认收货,系统自动确认收货", eventDesc = "", operatorType = (int)(userId > 0 ? MallOrderChangeOperatorType.买家 : MallOrderChangeOperatorType.平台) }, conn, trans); } trans.Commit(); } catch { trans.Rollback(); throw; } } return count > 0; } /// /// 卖家分账 /// /// 订单号 /// 流水编号(提前生成) /// 打款任务编号(提前生成) /// 商家到手金额(分) public static async Task MallOrderSellerSettlement(this DbRESTFulRepository repository, long orderId, long billId, long cashoutTaskId) { // 确认分账信息,卖家所得 = (订单金额-订单退款金额)— [(服务费 / 订单金额)* (订单金额-订单退款金额)] using (var conn = repository.ConnectionManager.GetConnection(false)) { conn.Open(); var totalAfterAmount = await repository.QuerySingleOrDefaultAsync( $"select sum(refundOrderAmount - lossAmount) as amount from mall_after_sale where orderId={orderId} and state=5", null, conn) ?? 0; var orderInfo = await repository.QuerySingleOrDefaultAsync( $"select orderAmount, serviceAmount, sellerId from mall_order where orderId={orderId}", null, conn); var orderDetailInfo = await repository.QuerySingleOrDefaultAsync( $"select goodsName, goodsDesc from mall_order_detail where orderId={orderId} limit 1", null, conn); var title = string.IsNullOrEmpty(orderDetailInfo.goodsName) ? (string)orderDetailInfo.goodsDesc : (string)orderDetailInfo.goodsName; if (title.Length > 100) title = title.Substring(0, 97) + "..."; var sellerId = (long)orderInfo.sellerId; var orderAmount = (int)orderInfo.orderAmount; var serviceAmount = (int)Math.Floor((orderAmount - totalAfterAmount) * ((int)orderInfo.serviceAmount * 1d / orderAmount)); var sellerFinalAmount = orderAmount - totalAfterAmount - serviceAmount; // 如果最终分账金额小于0.1,则不收取服务费 if (sellerFinalAmount < 10) { serviceAmount = 0; sellerFinalAmount = orderAmount - totalAfterAmount; } // 记录流水并添加卖家打款任务 var trans = conn.BeginTransaction(); try { // 如果存在,则忽略 var existBillId = await repository.QuerySingleOrDefaultAsync( $"select billId from mall_bill_record where orderId={orderId} and billType={(int)MallBillRecordBillType.分账流水}", null, conn, trans); if (existBillId == 0) { var cashoutAccount = await repository.QuerySingleOrDefaultAsync( $"select uName, loginName, platform from n_balance_cashout_user_platform where userId={sellerId} and platform='ALIPAY'", null, conn, trans); if (sellerFinalAmount > 0) { // 同一订单,只会生成一条分账打款记录 var existId = await repository.QuerySingleOrDefaultAsync( $"select id from n_balance_cashout_tasks where sourceId={orderId} and sourceType={(int)BalanceCashoutTaskSourceType.C2C订单分账打款}", null, conn, trans); if (existId == 0) { await repository.QueryAsync(@"insert into n_balance_cashout_tasks( id, userId, sourceId, sourceType, amount, transAmount, title, uName, platform, loginName, taxRate, feeRate, feeMinAmount, status, createAt) values ( @id, @userId, @sourceId, @sourceType, @amount, @transAmount, @title, @uName, @platform, @loginName, @taxRate, @feeRate, @feeMinAmount, @status, @createAt)", new { id = cashoutTaskId, userId = sellerId, sourceId = orderId, sourceType = (int)BalanceCashoutTaskSourceType.C2C订单分账打款, amount = sellerFinalAmount, transAmount = sellerFinalAmount, title, uName = cashoutAccount?.uName ?? string.Empty, platform = cashoutAccount?.platform ?? string.Empty, loginName = cashoutAccount?.loginName ?? string.Empty, taxRate = 0, feeRate = 0, feeMinAmount = 0, status = 0, createAt = DateTime.Now }, conn, trans); } } await repository.QuerySingleOrDefaultAsync(@"insert into mall_bill_record( billId, orderId, userId, afterSaleId, billType, taskOrderId, realAmount, refundAmount, billPoints, pointsDeductionAmount, serviceAmount, billAmount, billState, payPlatform, platformBillNo, createAt) values ( @billId, @orderId, @userId, @afterSaleId, @billType, @taskOrderId, @realAmount, @refundAmount, @billPoints, @pointsDeductionAmount, @serviceAmount, @billAmount, @billState, @payPlatform, @platformBillNo, @createAt)", new { billId, orderId, userId = sellerId, afterSaleId = 0, billType = (int)MallBillRecordBillType.分账流水, taskOrderId = cashoutTaskId.ToString(), realAmount = sellerFinalAmount, refundAmount = totalAfterAmount, billPoints = 0, pointsDeductionAmount = 0, serviceAmount, billAmount = sellerFinalAmount, billState = (int)MallBillRecordBillState.待支付, payPlatform = 1, platformBillNo = string.Empty, createAt = DateTime.Now }, conn, trans); } trans.Commit(); return sellerFinalAmount; } catch { trans.Rollback(); throw; } } } } }