123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621 |
- using Aliyun.Acs.Core.Logging;
- using JiaZhiQuan.Common.Hubs;
- using JiaZhiQuan.Common.Messaging;
- using JiaZhiQuan.Common.Messaging.Models;
- using JiaZhiQuan.Common.Response;
- using JiaZhiQuan.Common.Utils;
- using Newtonsoft.Json;
- using NLog;
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Linq;
- using System.Threading.Tasks;
- using JiaZhiQuan.Common.Models.IM;
- using Wicture.DbRESTFul;
- using Wicture.DbRESTFul.Infrastructure.Repository;
- using static JiaZhiQuan.Common.Models.MallGoodsModel.RefundModel;
- using System.Collections;
- namespace JiaZhiQuan.Common {
- public static partial class RepositoryExtension
- {
- public static void SendAfterSaleMsg(this DbRESTFulRepository repository,
- AfterSale refund, DealType dealType, Producer producer) {
- List<ImInfo> imInfos = GetImInfo(refund, dealType);
- if (imInfos.Count == 0) return;
- //写系统消息
- try {
- List<ImInfo> sysMsgs = imInfos.Where(x => x.senderId == (long)UserType.系统).ToList();
- sysMsgs.ForEach(x => _ = producer.ProduceAsync(NotificationModel.GetMsgKey(), new NotificationModel {
- Type = NotificationType.CommonWithAfterSale,
- Content = JsonConvert.SerializeObject(new AfterSaleSubModel {
- UserId = x.acceptId,
- Message = x.msg,
- AfterSaleId = x.afterSaleId,
- ActionLink = $"app://mall/afterSale?afterSaleId={x.afterSaleId}"
- })
- }));
- //发IM其他消息。
- List<ImInfo> chatMsgs = imInfos.Where(x => x.senderId != (long)UserType.系统).ToList();
- chatMsgs.ForEach(x => _ = producer.ProduceAsync(IMMessageModel.GetMsgKey(), new IMMessageModel {
- FromUserId = x.senderId,
- TargetUserId = x.acceptId,
- Content = new MessageContentDTO {
- Content = JsonConvert.SerializeObject(new AfterSalesRemindMessageStorageFormat { AfterSaleId = x.afterSaleId, Message = x.msg }),
- ContentType = MessageContentType.AfterSalesRemind
- }
- }));
- }catch (Exception ex) { LoggerManager.Logger.Error(ex, "发送售后单状态消息失败:" + ex.Message); }
- }
- private static List<ImInfo> GetImInfo(AfterSale refund, DealType dealType) {
- string amountStr = BuildYuan(refund.refundOrderAmount);
- string typeStr = BuildTypeDesc(refund.type);
- switch (dealType) {
- case DealType.买家申请退单:
- return new List<ImInfo>{new ImInfo {
- msg = $"【买家】我发起了{typeStr}申请,等待你处理",
- afterSaleId = refund.afterSaleId, senderId = refund.userId,
- acceptId = refund.sellerId,
- }, };
- case DealType.卖家同意退单:
- if (refund.type == 1 || refund.type == 2) {
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】卖家已同意退款{amountStr},钱款将原路退回",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- } };
- }
- return new List<ImInfo>{new ImInfo {
- msg = $"【卖家】我已发送退货地址,等待你寄回货物。",
- afterSaleId = refund.afterSaleId, senderId = refund.sellerId,
- acceptId = refund.userId,
- } };
- case DealType.卖家超时未处理:
- if (refund.type == 1 || refund.type == 2) {
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】系统已同意退款{amountStr},钱款将原路退回。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】您超时未处理退款,系统已退款{amountStr}给买家。",
- afterSaleId = refund.afterSaleId, senderId =(long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- }
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】您超时未处理退款,系统已同意退货退款申请,需买家寄回货物,请您尽快发送退货地址。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- },new ImInfo {
- msg = $"【买家】等待你发送退货地址",
- afterSaleId = refund.afterSaleId, senderId = refund.userId,
- acceptId = refund.sellerId,
- } };
- case DealType.卖家拒绝退单:
- return new List<ImInfo>{new ImInfo {
- msg = $"【卖家】我拒绝{typeStr},等待你处理",
- afterSaleId = refund.afterSaleId, senderId = refund.sellerId,
- acceptId = refund.userId,
- } };
- case DealType.买家撤销退单:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】买家已撤销{typeStr}。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.买家超时未申请维权:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】您超时未处理退款,系统关闭了您的{typeStr}申请。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】买家超时未处理退款,系统关闭了买家的{typeStr}申请。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.买家发起维权:
- return new List<ImInfo>{new ImInfo {
- msg = $"【买家】我已发起{typeStr}维权,双方提交证据中",
- afterSaleId = refund.afterSaleId, senderId = refund.userId,
- acceptId = refund.sellerId,
- },new ImInfo {
- msg = $"【系统】您发起了{typeStr}维权,双方补充中;" +
- $"举证结束后平台会介入处理。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】买家发起了{typeStr}维权," +
- $"双方补充中,请尽快提交证据,举证结束后平台会介入处理。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.买家退单维权补充证据:
- case DealType.买家货损维权补充证据:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】{refund.eventDesc}",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.卖家退单维权补充证据:
- case DealType.卖家货损维权补充证据:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】{refund.eventDesc}",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- } };
- case DealType.退单维权买家胜:
- return new List<ImInfo>{new ImInfo {
- msg = refund.type==2?$"【系统】平台判定您获胜,同意退款{amountStr},钱款退回中。":
- $"【系统】平台判定您获胜,同意{typeStr}" +
- $"{amountStr},需您寄回货物,请等待卖家发送退货地址。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = refund.type==2?$"【系统】平台判定买家获胜,已退款{amountStr}给买家。":
- $"【系统】平台判定买家获胜,已同意退货退款申请,需买家寄回货物,请您尽快发送退货地址。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.退单维权卖家胜:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】平台判定卖家获胜,系统关闭了您的{typeStr}申请。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】平台判定您获胜,系统关闭了买家的{typeStr}申请。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.卖家超时未发送退货地址:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】卖家超时未发生退货地址,系统退款" +
- $"{amountStr},钱款原路退回中。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】您超时未发生退货地址,系统已退款" +
- $"{amountStr}给买家。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.卖家发送退货地址:
- return new List<ImInfo>{new ImInfo {
- msg = $"【卖家】我已发送退货地址,等待你寄回货物。",
- afterSaleId = refund.afterSaleId, senderId = refund.sellerId,
- acceptId = refund.userId, } };
- case DealType.买家超时未寄出退货:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】您超时未寄回货物,系统关闭了您的退货退款申请。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】买家超时未寄回货物,系统关闭了买家的退货退款申请。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.买家寄出退货:
- return new List<ImInfo>{new ImInfo {
- msg = $"【买家】我已退货,等待你确认收货",
- afterSaleId = refund.afterSaleId, senderId = refund.userId,
- acceptId = refund.sellerId, } };
- case DealType.卖家确认收货:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】退货退款成功,退款{amountStr}原路退回中。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】退货退款成功,已退款{amountStr}给买家。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.卖家超时未确认收货:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】退货退款成功,退款{amountStr}原路退回中。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】您超时未确认收到退货,系统自动确认收到退货,已退款" +
- $"{amountStr}给买家。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.卖家申请货损:
- return new List<ImInfo>{new ImInfo {
- msg = $"【卖家】我发起了货物损失申请,等待你处理",
- afterSaleId = refund.afterSaleId, senderId = refund.sellerId,
- acceptId = refund.userId, } };
- case DealType.买家同意货损:
- return new List<ImInfo>{
- new ImInfo {
- msg = $"【系统】买家已同意货物损失" +
- $"{amountStr}",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.买家拒绝货损:
- return new List<ImInfo>{new ImInfo {
- msg = $"【买家】我拒绝货物损失,等待你处理",
- afterSaleId = refund.afterSaleId, senderId = refund.userId,
- acceptId = refund.sellerId, } };
- case DealType.买家超时未处理货损:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】您超时未处理货物损失,系统已同意卖家的货物损失申请。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】买家超时未处理货物损失,系统已同意您的货物损失申请。" +
- $"{amountStr}给买家。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.卖家撤销货损:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】卖家已撤销货物损失,退货退款将继续进行。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- } };
- case DealType.卖家超时未申请维权:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】卖家超时未处理货物损失,系统关闭了卖家的货物损失申请,退货退款将继续进行。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】您超时未处理货物损失,系统关闭了您的货物损失申请,退货退款将继续进行。" +
- $"{amountStr}给买家。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.卖家发起货损维权:
- return new List<ImInfo>{new ImInfo {
- msg = $"【卖家】我已发起货物损失维权,双方提交证据中",
- afterSaleId = refund.afterSaleId, senderId = refund.sellerId,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】卖家发起了货物损失维权,双方补充中,请尽快提交证据,举证结束后平台会介入处理。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】您发起了货物损失维权,双方补充中;举证结束后平台会介入处理。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.货损维权买家胜:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】平台判定您获胜,关闭了卖家的货物损失申请,退货退款将继续进行。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】平台判定买家获胜,关闭了您的货物损失申请,退货退款将继续进行。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- case DealType.货损维权卖家胜:
- return new List<ImInfo>{new ImInfo {
- msg = $"【系统】平台判定卖家获胜,同意货物损失{amountStr}。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.userId,
- },new ImInfo {
- msg = $"【系统】平台判定您获胜,同意货物损失{amountStr}。",
- afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- acceptId = refund.sellerId,
- } };
- //case DealType.买家退款失败:
- // return new List<ImInfo>{new ImInfo {
- // msg = $"【系统】退款{amountStr}原路退回失败!" +
- // $"请通过意见反馈或客服电话021-63333317(工作日早9~晚6)联系我们。",
- // afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- // acceptId = refund.userId,
- // } };
- //case DealType.买家退款成功:
- // return new List<ImInfo>{new ImInfo {
- // msg = $"【系统】您的退款{amountStr}已原路退回," +
- // $"可前往支付宝账户{refund.loginName}的账单中查看。",
- // afterSaleId = refund.afterSaleId, senderId = (long)UserType.系统,
- // acceptId = refund.userId,
- // } };
- case DealType.买家提醒卖家收货:
- return new List<ImInfo>{new ImInfo {
- msg = $"【买家】请在检查宝贝无误后,及时确认收货",
- afterSaleId = refund.afterSaleId, senderId = refund.userId,
- acceptId = refund.sellerId, } };
- default:
- return new List<ImInfo>();
- }
- }
- private static string BuildYuan(int amount) {
- var yuan = AmountUtils.ConvertCentToYuanStr(amount);
- return $"¥{yuan}";
- }
- private static string BuildTypeDesc(int type) {
- return type switch {
- 1 => "退款",
- 2 => "退款",
- 3 => "退货退款",
- _ => null
- };
- }
- //启用订单03计时器。
- public static async Task<OperateResult> EnableOrderTimer(this DbRESTFulRepository repository,
- long orderId, IDbConnection conn, IDbTransaction trans)
- {
- if (await HasRuningAfterSaleInOrder(repository, orderId, conn, trans))
- return new OperateResult { count = 1 };
- //无进行中的退单,则需要更新订单中的退单完成时间和订单的收货超时时间
- var orderCnt = await repository.QuerySingleOrDefaultAsync<int>(
- $@"update mall_order set refundCompleteAt=@now,receiveExpireAt=date_add(@now,
- interval TIMESTAMPDIFF(SECOND, refundCreateAt,receiveExpireAt) SECOND),
- sysRemindBuyerReceiptTime=date_add(receiveExpireAt,interval -1 day),
- aftersaleRunningState=0
- where orderId={orderId} and orderState=3;
- select row_count();", new { now = DateTime.Now }, conn, trans);
- return new OperateResult { count = orderCnt };
- }
- public static async Task<bool> HasRuningAfterSaleInOrder(this DbRESTFulRepository repository,
- long orderId, IDbConnection conn, IDbTransaction trans) {
- //查询进行中的退单个数
- return (await repository.QuerySingleOrDefaultAsync<long?>(
- $@"select afterSaleId from mall_after_sale where orderId={orderId}
- and state>0 and state<>5 limit 1", null, conn, trans) ?? 0) > 0;
- }
- public static async Task<OperateResult> ChangeUserPoints(this DbRESTFulRepository repository,
- long userId, int points, string way, string extra, string desc,
- IDbConnection conn = null, IDbTransaction trans = null)
- {
- var count = 0;
- if (points != 0)
- {
- var data = new { way, extra, desc };
- // 更新价值币总数
- count = await repository.QuerySingleOrDefaultAsync<int>(
- @$"update n_user_statistic set points=points+{points}
- where userId={userId};select row_count();", null, conn, trans);
- // 添加价值币变动记录
- await repository.QueryAsync<dynamic>(
- @$"insert into n_user_points_record (userId, points, `way`,
- extra, description, createAt, createAtDate) values({userId},
- {points}, @way, @extra, @desc, now(), now())", data, conn, trans);
- }
- return new OperateResult { count= count };
- }
- /// <summary>
- /// 卖家超时发货-订单行为
- /// </summary>
- /// <param name="param"></param>
- /// <returns></returns>
- public static async Task<OperateResult> SellerDeliveryExpire(this DbRESTFulRepository repository,
- long orderId, IDbConnection conn, IDbTransaction trans)
- {
- var count = await repository.QuerySingleOrDefaultAsync<int>(
- $@"update mall_after_sale set state=-1,closeAt=@now where type=1 and state=1
- [and orderId=@orderId ];select row_count();",
- new { now = DateTime.Now, orderId }, conn, trans);
- if (count > 0)
- {
- //插入退单事件
- await InsertAfterSaleEventByOrderId(repository, orderId, -1, "系统关闭交易,系统关闭", null, conn, trans);
- }
- return new OperateResult { count = count };
- }
- public static async Task<OperateResult> InsertAfterSaleEventByOrderId(this DbRESTFulRepository repository,
- long orderId, int eventType, string eventDesc, string resourceJson,
- IDbConnection conn = null, IDbTransaction trans = null)
- {
- var eventInfo = new
- {
- eventType, eventDesc,
- resources = resourceJson,
- createAt = DateTime.Now,
- };
- var count = await repository.QuerySingleOrDefaultAsync<int>(
- $@"insert into mall_after_sale_event (afterSaleId,orderId,
- orderDetailId,eventType,eventDesc,resources,createAt,)
- select afterSaleId,orderId,orderDetailId,@eventType,
- concat(@eventDesc,case when type=1 or type=2 then '退款' else '退货退款' end)
- ,@resources,@createAt from mall_after_sale
- where orderId={orderId} and state>0 and state<>5
- ;select row_count();", eventInfo, conn, trans);
- return new OperateResult { count = count };
- }
- // 退单成功,处理退单结果
- public static async Task<bool> DealAfterSaleSuccess(this DbRESTFulRepository repository,
- AfterSale refund, long newBillId) {
- var amount = CalRefundAmount(refund);
- using var conn = repository.ConnectionManager.GetConnection();
- conn.Open();
- var trans = conn.BeginTransaction();
- try {
- //插入流水表
- //判断是否存在
- var billId = await repository.QuerySingleOrDefaultAsync<long>(
- $@"select billId from mall_bill_record where afterSaleId={refund.afterSaleId}
- and billType={(int)BillType.退单流水} limit 1 ", null, conn, trans);
- if (billId > 0) return true;
- var cnt = await repository.InsertRefundBill(refund, (object)amount, newBillId, conn, trans);
- if (cnt.count <= 0) return false;
- //插入退款表
- await repository.InsertRefundTask(refund, (object)amount, conn, trans);
- string way = "AFTERSALE", extra = $"{refund.afterSaleId}",
- desc = $"交易退回-退款{refund.afterSaleId}";
- await repository.ChangeUserPoints((long)refund.userId, (int)amount.points,
- way, extra, desc, conn, trans);
- trans.Commit();
- return true;
- } catch (Exception ex) {
- trans.Rollback(); throw;
- }
- }
- //判断订单是否全额退货退款
- public static async Task<dynamic> RefundAllForSuccess(this DbRESTFulRepository repository,
- AfterSale refundInfo,long newBillId,long newCashoutId, IDbConnection conn, IDbTransaction trans) {
- var order = await repository.QuerySingleOrDefaultAsync<dynamic>(
- $@"select orderId,orderAmount,serviceAmount from mall_order where orderId={refundInfo.orderId}",
- null, conn, trans);
- List<dynamic> successRefunds = (await repository.QueryAsync<dynamic>(
- $@"select afterSaleId,refundOrderAmount,lossAmount from mall_after_sale
- where orderId={refundInfo.orderId} and state=5 ",
- null, conn, trans)).ToList();
- var now = DateTime.Now;
- //表示全额退,这里不能考虑货损
- var refundSum = successRefunds.Where(x => x.afterSaleId != refundInfo.afterSaleId)
- .Sum(x => x.refundOrderAmount);
- if (refundInfo.refundOrderAmount == order.orderAmount - refundSum) {
- var orderCnt = await repository.QuerySingleOrDefaultAsync<int>(
- $@"update mall_order set orderState=4,autoCompletedAt=@now,refundCompleteAt=@now,
- aftersaleRunningState=0
- where orderId={refundInfo.orderId} and orderState=3;
- select row_count();", new { now }, conn, trans);
- if (orderCnt <= 0) throw new Exception("订单异常,无法更新订单状态");
- await repository.MallOrderSellerSettlement((long)refundInfo.orderId, newBillId,
- newCashoutId);
- return new { count = orderCnt };
- }
- //部分退
- else if (refundInfo.refundOrderAmount < order.orderAmount - refundSum) {
- var count = await repository.EnableOrderTimer((long)refundInfo.orderId, conn, trans);
- if (count.count <= 0) throw new Exception("订单异常,无法启用定时器03");
- return count;
- } else {
- throw new Exception("退单总金额,超过订单总金额。");
- }
- }
- //判断订单是否全额退货退款
- public static async Task<dynamic> RefundAllForClose(this DbRESTFulRepository repository,
- AfterSale refundInfo, IDbConnection conn, IDbTransaction trans) {
- var order = await repository.QuerySingleOrDefaultAsync<dynamic>(
- $@"select orderId,orderAmount,serviceAmount from mall_order where orderId={refundInfo.orderId}",
- null, conn, trans);
- List<dynamic> successRefunds = (await repository.QueryAsync<dynamic>(
- $@"select afterSaleId,refundOrderAmount,lossAmount from mall_after_sale
- where orderId={refundInfo.orderId} and state=5 ",
- null, conn, trans)).ToList();
- var now = DateTime.Now;
- //表示全额退
- var refundSum = successRefunds.Where(x => x.afterSaleId != refundInfo.afterSaleId)
- .Sum(x => x.refundOrderAmount);
- if (refundInfo.refundOrderAmount == order.orderAmount - refundSum) {
- var orderCnt = await repository.QuerySingleOrDefaultAsync<int>(
- $@"update mall_order set orderState=-9,closeAt=@now,closeReasonType=4,refundCompleteAt=@now,
- aftersaleRunningState=0
- where orderId={refundInfo.orderId} and orderState=3;
- select row_count();", new { now }, conn, trans);
- if (orderCnt <= 0) throw new Exception("订单异常,无法更新订单状态");
- return new { count = orderCnt };
- }
- //部分退
- else if (refundInfo.refundOrderAmount < order.orderAmount - refundSum) {
- var count = await repository.EnableOrderTimer((long)refundInfo.orderId, conn, trans);
- if (count.count <= 0) throw new Exception("订单异常,无法启用定时器03");
- return count;
- } else {
- throw new Exception("退单总金额,超过订单总金额。");
- }
- }
- // 插入退单流水
- private static async Task<OperateResult> InsertRefundBill(this DbRESTFulRepository repository,
- AfterSale refund, dynamic amount, long newBillId, IDbConnection conn, IDbTransaction trans) {
- //插入退款流水。
- var count = await repository.SimpleInsert("mall_bill_record", new {
- billId = newBillId, refund.orderId, refund.userId,
- refund.afterSaleId, billType = (int)BillType.退单流水,
- taskOrderId= $"{refund.orderId}_{refund.afterSaleId}",
- amount.realAmount, billPoints = amount.points,
- pointsDeductionAmount = amount.totalAmount - amount.realAmount,
- billAmount = amount.totalAmount, billState = 1, createAt = DateTime.Now
- }, conn, trans);
- return new OperateResult { count = count.count };
- }
- // 插入退款任务表
- private static async Task<OperateResult> InsertRefundTask(this DbRESTFulRepository repository,
- AfterSale refund, dynamic amount, IDbConnection conn, IDbTransaction trans) {
- if (amount.realAmount <= 0) return new OperateResult { count = 1 };
- var payId = await repository.QuerySingleOrDefaultAsync<string>(
- $@"select payId from mall_order_pay_relation
- where orderId={refund.orderId}", null, conn, trans);
- if (string.IsNullOrWhiteSpace(payId)) throw new Exception("插入退款任务时,支付单号id不能为空");
- var count = await repository.SimpleInsert("mall_order_refund",
- new {
- id = $"{refund.orderId}_{refund.afterSaleId}", refund.userId, refund.orderId, payId,
- refund.afterSaleId, amount = amount.realAmount, state = 0, createAt = DateTime.Now
- }, conn, trans);
- return new OperateResult { count = count.count };
- }
- private static dynamic CalRefundAmount(AfterSale refund) {
- var totalAmount = refund.refundOrderAmount - refund.lossAmount;
- //这样计算比例会二次失真。不考虑失真问题,向下取分即可。
- var realAmount = (int)(totalAmount * ((double)refund.refundAmount / refund.refundOrderAmount));
- var points = (int)(totalAmount * ((double)refund.refundPoints / refund.refundOrderAmount));
- return new { totalAmount, realAmount, points };
- }
- //根据对象插入表
- public static async Task<InsertResult> SimpleInsert(this DbRESTFulRepository repository,
- string tableName, object insertInfo,
- IDbConnection conn = null, IDbTransaction trans = null)
- {
- var count = new InsertResult { count = 0 };
- if (string.IsNullOrWhiteSpace(tableName) || insertInfo == null) return count;
- if (insertInfo is IEnumerable<dynamic> insertList) {
- if (insertList.Count() == 0) return count;
- var first = insertList.First();
- IDictionary<string, object?> inSet = ExpandoUtils.ConvertToDynamic(first);
- if (inSet.Count == 0) return count;
- var insertSet = inSet.Where(x => x.Value != null);
- string fields = string.Join(",", insertSet.Select(x => x.Key)),
- valuesFields = string.Join(",", insertSet.Select(x => $"@{x.Key}"));
- string insert = $"({fields}) values({valuesFields})";
- //批量插入的id,获取的不准确。
- string sql = $"insert into {tableName} {insert} ";
- var cnt= await repository.QuerySingleOrDefaultAsync<int>(sql, insertList, conn, trans, false);
- return new InsertResult { count = cnt };
- } else {
- IDictionary<string, object?> inSet = ExpandoUtils.ConvertToDynamic(insertInfo);
- if (inSet.Count == 0) return count;
- var insertSet = inSet.Where(x => x.Value != null);
- string fields = string.Join(",", insertSet.Select(x => x.Key)),
- valuesFields = string.Join(",", insertSet.Select(x => $"@{x.Key}"));
- string insert = $"({fields}) values({valuesFields})";
- string sql = $"insert into {tableName} {insert} ;select row_count() count,LAST_INSERT_ID() insertId;";
- return await repository.QuerySingleOrDefaultAsync<InsertResult>(sql, insertInfo, conn, trans, false);
- }
- }
- public static async Task<OperateResult> SimpleUpdate(this DbRESTFulRepository repository,
- string tableName, object updateInfo, object condition,
- IDbConnection conn = null, IDbTransaction trans = null, bool updateNull = true) {
- var count = new OperateResult { count = 0 };
- if (string.IsNullOrWhiteSpace(tableName) ||
- updateInfo == null || condition == null) return count;
- IDictionary<string, object?> updateSet = ExpandoUtils.ConvertToDynamic(updateInfo);
- IDictionary<string, object?> conditionSet = ExpandoUtils.ConvertToDynamic(condition);
- if (updateSet.Count == 0 || conditionSet.Count == 0) return count;
- //updateNull为false时,表示不更新空值。
- string upContent = string.Join(",", updateSet.Where(x => updateNull || x.Value != null).
- Select(x => $"{x.Key}=@{x.Key}"));
- string conContent = string.Join(" and ", conditionSet.Select(x => !(x.Value is string)&& x.Value is IEnumerable ?
- $"{x.Key} in @c2{x.Key}" : $"{x.Key}=@c2{x.Key}"));
- string sql = $"update {tableName} set {upContent} where {conContent} ;select row_count();";
- var upObj = new Dictionary<string, object>(updateSet);
- conditionSet.ForEach(x => upObj.Add($"c2{x.Key}", x.Value));
- return new OperateResult { count = await repository.QuerySingleOrDefaultAsync<int>(sql, upObj, conn, trans, false) };
- }
- }
- }
|