sunpengfei
6 天以前 56af0f468f321d41db70343abf558d61cda58d31
FlexJobApi.FlexJobServer.Application/Tasks/Commands/TaskInfoCommandHandler.cs
@@ -1,4 +1,5 @@
using FlexJobApi.Core;
using Aop.Api.Domain;
using FlexJobApi.Core;
using Furion.DatabaseAccessor;
using Furion.DistributedIDGenerator;
using Furion.FriendlyException;
@@ -10,6 +11,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TaskInfo = FlexJobApi.Core.TaskInfo;
namespace FlexJobApi.FlexJobServer.Application
{
@@ -17,14 +19,21 @@
    /// 任务命令处理器
    /// </summary>
    public class TaskInfoCommandHandler(
            IRepository<TaskInfo> rep
            IRepository<TaskInfo> rep,
            IRepository<EnterpriseWallet> repEnterpriseWallet,
            AlipayUtils alipayUtils
        ) :
        IRequestHandler<SaveTaskInfoCommand, Guid>,
        IRequestHandler<SetTaskInfoReleaseStatusCommand, int>,
        IRequestHandler<SetTaskInfoRecommendStatusCommand, int>,
        IRequestHandler<DeleteTaskInfoCommand, int>
        IRequestHandler<DeleteTaskInfoCommand, int>,
        IRequestHandler<SureTaskSettlementOrderCommand, Guid>,
        IRequestHandler<RevokeTaskSettlementOrderCommand, Guid>,
        IRequestHandler<SureTaskSettlementCommand, Guid>
    {
        private readonly IRepository<TaskInfo> rep = rep;
        private readonly IRepository<EnterpriseWallet> repEnterpriseWallet = repEnterpriseWallet;
        private readonly AlipayUtils alipayUtils = alipayUtils;
        /// <summary>
        /// 保存任务
@@ -38,7 +47,7 @@
        {
            var logier = JwtUtils.GetCurrentLogier();
            if (logier.EnterpriseId == null) throw Oops.Oh(EnumErrorCodeType.s400, "当前登录用户必须为企业用户才可以创建任务");
            return await request.SaveData<TaskInfo, SaveTaskInfoCommand>(
            var entity = await request.SaveData<TaskInfo, SaveTaskInfoCommand>(
                 q =>
                 {
                     q = TaskInfoRepository.GetQueryable(rep, false)
@@ -72,6 +81,7 @@
                         .ToList();
                 },
                 cancellationToken);
            return entity.Id;
        }
        /// <summary>
@@ -102,13 +112,20 @@
        public async Task<int> Handle(SetTaskInfoRecommendStatusCommand request, CancellationToken cancellationToken)
        {
            var entities = await TaskInfoRepository.GetQueryable(rep, false)
                .Where(it => request.Ids.Contains(it.Id))
                .Where(it => request.Ids.Contains(it.Id) && it.RecommendStatus != request.RecommendStatus)
                .ToListAsync();
            foreach (var entity in entities)
            if (entities.IsNotNull())
            {
                entity.RecommendStatus = request.RecommendStatus;
                foreach (var entity in entities)
                {
                    entity.RecommendStatus = request.RecommendStatus;
                    if (entity.RecommendStatus == EnumTaskRecommendStatus.Yes)
                    {
                        entity.RecommendTime = DateTime.Now;
                    }
                }
                await rep.UpdateAsync(entities);
            }
            await rep.UpdateAsync(entities);
            return entities.Count;
        }
@@ -124,7 +141,7 @@
                q =>
                {
                    q = TaskInfoRepository.GetQueryable(rep, false);
                    if (q.AsNoTracking().Any(it => it.Status == EnumTaskStatus.Complete))
                    if (q.AsNoTracking().Any(it => request.Ids.Contains(it.Id) && it.Status == EnumTaskStatus.Complete))
                    {
                        throw Oops.Oh(EnumErrorCodeType.s510, "已安排的任务无法删除");
                    }
@@ -132,6 +149,145 @@
                }, cancellationToken);
        }
        /// <summary>
        /// 确认结算单
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<Guid> Handle(SureTaskSettlementOrderCommand request, CancellationToken cancellationToken)
        {
            var entity = await TaskInfoRepository.GetQueryable(rep, false)
                .Include(it => it.TaskInfoUsers).ThenInclude(it => it.EnterpriseEmployee)
                .Where(it => it.Id == request.TaskInfoId)
                .FirstOrDefaultAsync();
            if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "任务");
            if (entity.SettlementStatus == EnumTaskSettlementStatus.InProcess) throw Oops.Oh(EnumErrorCodeType.s510, "结算中不可修改,请先撤回");
            if (entity.SettlementStatus == EnumTaskSettlementStatus.Completed) throw Oops.Oh(EnumErrorCodeType.s510, "已结算不可修改");
            entity.SettlementOrderStatus = EnumTaskSettlementOrderStatus.Completed;
            entity.SettlementOrderUrl = request.SettlementOrderUrl;
            entity.SettlementOrderName = entity.SettlementOrderUrl.Substring(entity.SettlementOrderUrl.LastIndexOf("/") + 1);
            entity.SettlementOrderTime = DateTime.Now;
            entity.SettlementStatus = EnumTaskSettlementStatus.Wait;
            entity.SettlementUserCount = request.TaskInfoUsers.Count;
            entity.SettlementAmount = request.TaskInfoUsers.Sum(it => it.SettlementAmount ?? 0);
            entity.ActualSettlementAmount = request.TaskInfoUsers.Sum(it => it.ActualSettlementAmount ?? 0);
            foreach (var model in request.TaskInfoUsers)
            {
                var user = entity.TaskInfoUsers.FirstOrDefault(it => it.Id == model.Id);
                if (user == null) throw Oops.Oh(EnumErrorCodeType.s404, $"灵工{model.Name}");
                if (user.SettlementStatus == EnumTaskSettlementStatus.InProcess) throw Oops.Oh(EnumErrorCodeType.s510, $"{model.Name}结算中不可修改,请先撤回");
                if (user.SettlementStatus == EnumTaskSettlementStatus.Completed) throw Oops.Oh(EnumErrorCodeType.s510, $"{model.Name}已结算不可修改");
                if (user.CheckReceiveStatus != EnumTaskCheckReceiveStatus.Completed) throw Oops.Oh(EnumErrorCodeType.s510, $"{model.Name}未验收");
                if (model.SettlementAmount < 0) throw Oops.Oh(EnumErrorCodeType.s510, $"{model.Name}结算金额不可负数");
                if (model.ActualSettlementAmount < 0) throw Oops.Oh(EnumErrorCodeType.s510, $"{model.Name}实发金额不可负数");
                if (model.ActualSettlementAmount > 0 && model.ActualSettlementAmount < 1) throw Oops.Oh(EnumErrorCodeType.s510, $"{model.Name}实发金额不可小于1元");
                user.Bank = model.Bank;
                user.BankBranch = model.BankBranch;
                user.ReceiveName = user.EnterpriseEmployee.Name;
                user.ReceiveAccount = model.ReceiveAccount;
                user.SettlementAmount = model.SettlementAmount;
                user.ActualSettlementAmount = model.ActualSettlementAmount;
                user.SettlementStatus = EnumTaskSettlementStatus.Wait;
            }
            foreach (var user in entity.TaskInfoUsers)
            {
                var model = request.TaskInfoUsers.FirstOrDefault(it => it.Id == user.Id);
                if (model == null)
                {
                    user.SettlementStatus = null;
                }
            }
            await rep.UpdateAsync(entity);
            return entity.Id;
        }
        /// <summary>
        /// 撤回结算
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<Guid> Handle(RevokeTaskSettlementOrderCommand request, CancellationToken cancellationToken)
        {
            var entity = await TaskInfoRepository.GetQueryable(rep, false)
                .Include(it => it.TaskInfoUsers)
                .Where(it => it.Id == request.TaskInfoId)
                .FirstOrDefaultAsync();
            if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "任务");
            if (entity.SettlementStatus == EnumTaskSettlementStatus.Wait) throw Oops.Oh(EnumErrorCodeType.s510, "未开始结算,请先上传结算单并确认");
            if (entity.SettlementStatus == EnumTaskSettlementStatus.Completed) throw Oops.Oh(EnumErrorCodeType.s510, "已结算不可撤回");
            entity.SettlementStatus = EnumTaskSettlementStatus.Wait;
            foreach (var user in entity.TaskInfoUsers)
            {
                if (user.SettlementStatus == EnumTaskSettlementStatus.InProcess)
                {
                    user.SettlementStatus = EnumTaskSettlementStatus.Wait;
                }
            }
            await rep.UpdateAsync(entity);
            return entity.Id;
        }
        /// <summary>
        /// 确认结算
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<Guid> Handle(SureTaskSettlementCommand request, CancellationToken cancellationToken)
        {
            var logier = JwtUtils.GetCurrentLogier();
            var entity = await TaskInfoRepository.GetQueryable(rep, false, logier)
                .Include(it => it.TaskInfoUsers)
                .Where(it => it.Id == request.TaskInfoId)
                .FirstOrDefaultAsync();
            if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "任务");
            if (entity.SettlementOrderStatus != EnumTaskSettlementOrderStatus.Completed) throw Oops.Oh(EnumErrorCodeType.s510, "请先上传结算单并确认");
            if (entity.SettlementStatus == null) throw Oops.Oh(EnumErrorCodeType.s510, "未开始结算,请先上传结算单并确认");
            if (entity.SettlementStatus == EnumTaskSettlementStatus.Completed) throw Oops.Oh(EnumErrorCodeType.s510, "已结算");
            entity.SettlementStatus = EnumTaskSettlementStatus.InProcess;
            entity.SettlementStartTime = DateTime.Now;
            foreach (var user in entity.TaskInfoUsers)
            {
                if (user.SettlementStatus == EnumTaskSettlementStatus.Wait)
                {
                    user.SettlementStatus = EnumTaskSettlementStatus.InProcess;
                }
            }
            var wallet = await repEnterpriseWallet.AsQueryable()
                .Where(it => it.EnterpriseId == entity.EnterpriseId && it.Access == EnumEnterpriseWalletAccess.Alipay)
                .FirstOrDefaultAsync();
            if (wallet == null) throw Oops.Oh(EnumErrorCodeType.s404, "企业钱包");
            if (wallet.SignStatus != EnumEnterpriseWalletSignStatus.Normal) throw Oops.Oh(EnumErrorCodeType.s404, "企业钱包未签约");
            if (wallet.AccountBookStatus != EnumEnterpriseWalletAccountBookStatus.Normal) throw Oops.Oh(EnumErrorCodeType.s404, "企业钱包记账本未开通");
            var response = alipayUtils.FundAccountbookQuery(new AlipayFundAccountbookQueryModel
            {
                AccountBookId = wallet.AccountBookId,
                SceneCode = "SATF_FUND_BOOK",
                MerchantUserId = wallet.Code,
            });
            if (response.IsError) throw Oops.Oh(EnumErrorCodeType.s510, response.SubMsg ?? response.Msg);
            wallet.Balance = response.AvailableAmount.ToDecimal() ?? 0;
            await repEnterpriseWallet.UpdateAsync(wallet);
            var amount = await TaskInfoRepository.GetQueryable(rep, false, logier)
                .Where(it =>
                    it.EnterpriseId == entity.EnterpriseId
                    && it.Id != request.TaskInfoId
                    && it.SettlementStatus == EnumTaskSettlementStatus.InProcess
                    && it.ActualSettlementAmount.HasValue)
                .SumAsync(it => it.ActualSettlementAmount!.Value);
            amount += entity.ActualSettlementAmount!.Value;
            if (wallet.Balance < amount)
                throw Oops.Oh(EnumErrorCodeType.s510, "企业钱包余额不足");
            await rep.UpdateAsync(entity);
            return entity.Id;
        }
        private async Task BuildCode(TaskInfo entity)
        {
            entity.Code = $"{DateTime.Now:yyyyMMddHHmm}{new Random(IDGen.NextID().GetHashCode()).Next(1000, 9999)}";