FlexJobApi.Core/Entities/FlexJobServer/Tasks/TaskInfo.cs
@@ -167,16 +167,61 @@ public DateTime? LastCheckReceiveTime { get; set; } /// <summary> /// 结算单状态 /// </summary> public EnumTaskSettlementOrderStatus? SettlementOrderStatus { get; set; } /// <summary> /// 结算单名称 /// </summary> public string SettlementOrderName { get; set; } /// <summary> /// 结算单地址 /// </summary> public string SettlementOrderUrl { get; set; } /// <summary> /// 结算单上传时间 /// </summary> public DateTime? SettlementOrderTime { get; set; } /// <summary> /// 结算状态 /// </summary> public EnumTaskSettlementStatus? SettlementStatus { get; set; } /// <summary> /// 结算金额 /// </summary> public decimal? SettlementAmount { get; set; } /// <summary> /// 实发金额 /// </summary> public decimal? ActualSettlementAmount { get; set; } /// <summary> /// 结算人数 /// </summary> public int SettlementUserCount { get; set; } /// <summary> /// 结算开始时间 /// </summary> public DateTime? SettlementStartTime { get; set; } /// <summary> /// 结算时间 /// </summary> public DateTime? SettlementTime { get; set; } /// <summary> /// 结算备注 /// </summary> public string SettlementRemark { get; set; } /// <summary> /// 推荐状态 /// </summary> public EnumTaskRecommendStatus RecommendStatus { get; set; } FlexJobApi.Core/Entities/FlexJobServer/Tasks/TaskInfoUser.cs
@@ -80,6 +80,51 @@ public DateTime? LastCheckReceiveTime { get; set; } /// <summary> /// 所属银行 /// </summary> public string Bank { get; set; } /// <summary> /// 开户支行名称 /// </summary> public string BankBranch { get; set; } /// <summary> /// 收款人姓名 /// </summary> public string ReceiveName { get; set; } /// <summary> /// 收款账户 /// </summary> public string ReceiveAccount { get; set; } /// <summary> /// 结算金额 /// </summary> public decimal? SettlementAmount { get; set; } /// <summary> /// 实发金额 /// </summary> public decimal? ActualSettlementAmount { get; set; } /// <summary> /// 结算状态 /// </summary> public EnumTaskSettlementStatus? SettlementStatus { get; set; } /// <summary> /// 结算时间 /// </summary> public DateTime? SettlementTime { get; set; } /// <summary> /// 结算备注 /// </summary> public string SettlementRemark { get; set; } /// <summary> /// 提交 /// </summary> public List<TaskInfoUserSubmit> Submits { get; set; } FlexJobApi.Core/Entities/UserServer/Users/UserBankCard.cs
@@ -26,21 +26,32 @@ /// 银行卡号 /// </summary> [MaxLength(32)] [Required] public string Code { get; set; } /// <summary> /// 开户行 /// 所属银行 /// </summary> [MaxLength(128)] [Required] public string Bank { get; set; } /// <summary> /// 所属支行 /// </summary> public string BankBranch { get; set; } /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 身份证 /// </summary> public string Identity { get; set; } /// <summary> /// 银行预留手机号 /// </summary> [MaxLength(11)] [Required] public string PhoneNumber { get; set; } } } FlexJobApi.Core/Enums/Tasks/EnumTaskSettlementOrderStatus.cs
New file @@ -0,0 +1,23 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.Core { /// <summary> /// 任务结算单状态 /// </summary> public enum EnumTaskSettlementOrderStatus { /// <summary> /// 待上传 /// </summary> Wait = 10, /// <summary> /// 已上传 /// </summary> Completed = 20 } } FlexJobApi.Core/Enums/Tasks/EnumTaskSettlementStatus.cs
@@ -16,6 +16,10 @@ /// </summary> Wait = 10, /// <summary> /// 结算中 /// </summary> InProcess = 20, /// <summary> /// 已结算 /// </summary> Completed = 30, FlexJobApi.Core/Enums/Tasks/EnumTaskUserSettlementStatus.cs
File was deleted FlexJobApi.Core/FlexJobApi.Core.xml
@@ -884,14 +884,59 @@ 最近验收时间 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.SettlementOrderStatus"> <summary> 结算单状态 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.SettlementOrderName"> <summary> 结算单名称 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.SettlementOrderUrl"> <summary> 结算单地址 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.SettlementOrderTime"> <summary> 结算单上传时间 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.SettlementStatus"> <summary> 结算状态 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.SettlementAmount"> <summary> 结算金额 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.ActualSettlementAmount"> <summary> 实发金额 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.SettlementUserCount"> <summary> 结算人数 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.SettlementStartTime"> <summary> 结算开始时间 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.SettlementTime"> <summary> 结算时间 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.SettlementRemark"> <summary> 结算备注 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfo.RecommendStatus"> @@ -1022,6 +1067,51 @@ <member name="P:FlexJobApi.Core.TaskInfoUser.LastCheckReceiveTime"> <summary> 最近验收时间 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfoUser.Bank"> <summary> 所属银行 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfoUser.BankBranch"> <summary> 开户支行名称 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfoUser.ReceiveName"> <summary> 收款人姓名 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfoUser.ReceiveAccount"> <summary> 收款账户 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfoUser.SettlementAmount"> <summary> 结算金额 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfoUser.ActualSettlementAmount"> <summary> 实发金额 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfoUser.SettlementStatus"> <summary> 结算状态 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfoUser.SettlementTime"> <summary> 结算时间 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfoUser.SettlementRemark"> <summary> 结算备注 </summary> </member> <member name="P:FlexJobApi.Core.TaskInfoUser.Submits"> @@ -3079,7 +3169,22 @@ </member> <member name="P:FlexJobApi.Core.UserBankCard.Bank"> <summary> 开户行 所属银行 </summary> </member> <member name="P:FlexJobApi.Core.UserBankCard.BankBranch"> <summary> 所属支行 </summary> </member> <member name="P:FlexJobApi.Core.UserBankCard.Name"> <summary> 姓名 </summary> </member> <member name="P:FlexJobApi.Core.UserBankCard.Identity"> <summary> 身份证 </summary> </member> <member name="P:FlexJobApi.Core.UserBankCard.PhoneNumber"> @@ -3702,6 +3807,21 @@ 已停止 </summary> </member> <member name="T:FlexJobApi.Core.EnumTaskSettlementOrderStatus"> <summary> 任务结算单状态 </summary> </member> <member name="F:FlexJobApi.Core.EnumTaskSettlementOrderStatus.Wait"> <summary> 待上传 </summary> </member> <member name="F:FlexJobApi.Core.EnumTaskSettlementOrderStatus.Completed"> <summary> 已上传 </summary> </member> <member name="T:FlexJobApi.Core.EnumTaskSettlementStatus"> <summary> 任务结算状态 @@ -3710,6 +3830,11 @@ <member name="F:FlexJobApi.Core.EnumTaskSettlementStatus.Wait"> <summary> 待结算 </summary> </member> <member name="F:FlexJobApi.Core.EnumTaskSettlementStatus.InProcess"> <summary> 结算中 </summary> </member> <member name="F:FlexJobApi.Core.EnumTaskSettlementStatus.Completed"> @@ -3765,31 +3890,6 @@ <member name="F:FlexJobApi.Core.EnumTaskUserHireStatus.Refuse"> <summary> 已谢绝 </summary> </member> <member name="T:FlexJobApi.Core.EnumTaskUserSettlementStatus"> <summary> 任务用户结算状态 </summary> </member> <member name="F:FlexJobApi.Core.EnumTaskUserSettlementStatus.Wait"> <summary> 待结算 </summary> </member> <member name="F:FlexJobApi.Core.EnumTaskUserSettlementStatus.InProcess"> <summary> 结算中 </summary> </member> <member name="F:FlexJobApi.Core.EnumTaskUserSettlementStatus.Completed"> <summary> 已结算 </summary> </member> <member name="F:FlexJobApi.Core.EnumTaskUserSettlementStatus.Fail"> <summary> 结算失败 </summary> </member> <member name="T:FlexJobApi.Core.EnumTaskUserSignContractStatus"> @@ -4476,6 +4576,16 @@ <member name="M:FlexJobApi.Core.CalcUserAgeByIdCardJob.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.User})"> <summary> 定时根据身份证计算用户年龄 </summary> </member> <member name="T:FlexJobApi.Core.CompleteTaskSettlementT1Job"> <summary> 完成任务结算T+1 </summary> </member> <member name="M:FlexJobApi.Core.CompleteTaskSettlementT1Job.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.TaskInfo},Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.TaskInfoUser},Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.EnterpriseWallet},Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.EnterpriseWalletTransaction},FlexJobApi.Core.AlipayUtils)"> <summary> 完成任务结算T+1 </summary> </member> <member name="T:FlexJobApi.Core.DeleteDictionaryCategoryCommand"> @@ -6666,6 +6776,16 @@ 删除任务 </summary> </member> <member name="T:FlexJobApi.Core.RevokeTaskSettlementOrderCommand"> <summary> 撤回结算 </summary> </member> <member name="P:FlexJobApi.Core.RevokeTaskSettlementOrderCommand.TaskInfoId"> <summary> 任务Id </summary> </member> <member name="T:FlexJobApi.Core.SaveTaskInfoCommand"> <summary> 保存任务 @@ -6784,6 +6904,76 @@ <member name="P:FlexJobApi.Core.SetTaskInfoReleaseStatusCommand.ReleaseStatus"> <summary> 发布状态 </summary> </member> <member name="T:FlexJobApi.Core.SureTaskSettlementCommand"> <summary> 确认结算 </summary> </member> <member name="P:FlexJobApi.Core.SureTaskSettlementCommand.TaskInfoId"> <summary> 任务Id </summary> </member> <member name="T:FlexJobApi.Core.SureTaskSettlementOrderCommand"> <summary> 确认结算单 </summary> </member> <member name="P:FlexJobApi.Core.SureTaskSettlementOrderCommand.TaskInfoId"> <summary> 任务Id </summary> </member> <member name="P:FlexJobApi.Core.SureTaskSettlementOrderCommand.SettlementOrderUrl"> <summary> 结算单地址 </summary> </member> <member name="P:FlexJobApi.Core.SureTaskSettlementOrderCommand.TaskInfoUsers"> <summary> 结算名单 </summary> </member> <member name="T:FlexJobApi.Core.SureTaskSettlementOrderCommandUser"> <summary> 确认结算单 </summary> </member> <member name="P:FlexJobApi.Core.SureTaskSettlementOrderCommandUser.Id"> <summary> 任务用户Id </summary> </member> <member name="P:FlexJobApi.Core.SureTaskSettlementOrderCommandUser.Name"> <summary> 姓名 </summary> </member> <member name="P:FlexJobApi.Core.SureTaskSettlementOrderCommandUser.Bank"> <summary> 所属银行 </summary> </member> <member name="P:FlexJobApi.Core.SureTaskSettlementOrderCommandUser.BankBranch"> <summary> 开户支行名称 </summary> </member> <member name="P:FlexJobApi.Core.SureTaskSettlementOrderCommandUser.ReceiveAccount"> <summary> 收款账户 </summary> </member> <member name="P:FlexJobApi.Core.SureTaskSettlementOrderCommandUser.SettlementAmount"> <summary> 结算金额 </summary> </member> <member name="P:FlexJobApi.Core.SureTaskSettlementOrderCommandUser.ActualSettlementAmount"> <summary> 实发金额 </summary> </member> <member name="T:FlexJobApi.Core.GetOpenTaskInfosQuery"> @@ -7074,6 +7264,166 @@ <member name="F:FlexJobApi.Core.GetPersonalHireTaskInfosQueryStatus.Completed"> <summary> 已完成 </summary> </member> <member name="T:FlexJobApi.Core.GetSettlementTaskQuery"> <summary> 查询结算单详情 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQuery.Id"> <summary> Id </summary> </member> <member name="T:FlexJobApi.Core.GetSettlementTaskQueryResult"> <summary> 查询结算单详情-结果 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQueryResult.Id"> <summary> Id </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQueryResult.Name"> <summary> 任务名称 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQueryResult.Code"> <summary> 任务单号 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQueryResult.SettlementOrderStatus"> <summary> 结算单状态 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQueryResult.SettlementOrderName"> <summary> 结算单名称 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQueryResult.SettlementOrderTime"> <summary> 上传时间 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQueryResult.ActualSettlementAmount"> <summary> 实发金额 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQueryResult.SettlementAmount"> <summary> 结算金额 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQueryResult.SettlementStatus"> <summary> 结算状态 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQueryResult.SettlementTime"> <summary> 结算时间 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskQueryResult.SettlementRemark"> <summary> 备注 </summary> </member> <member name="T:FlexJobApi.Core.GetSettlementTasksQuery"> <summary> 查询结算任务分页列表数据 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQuery.Keywords"> <summary> 关键字 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQuery.SettlementOrderStatus"> <summary> 结算单状态 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQuery.SettlementStatus"> <summary> 结算状态 </summary> </member> <member name="T:FlexJobApi.Core.GetSettlementTasksQueryResult"> <summary> 查询结算任务分页列表数据 </summary> </member> <member name="T:FlexJobApi.Core.GetSettlementTasksQueryResultItem"> <summary> 查询结算任务分页列表数据 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.Id"> <summary> 任务Id </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.Name"> <summary> 任务名称 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.Code"> <summary> 任务单号 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.SettlementOrderStatus"> <summary> 结算单状态 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.SettlementOrderName"> <summary> 结算单名称 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.SettlementOrderTime"> <summary> 上传时间 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.ActualSettlementAmount"> <summary> 实发金额 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.SettlementAmount"> <summary> 结算金额 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.SettlementStatus"> <summary> 结算状态 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.SettlementTime"> <summary> 结算时间 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.SettlementRemark"> <summary> 备注 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTasksQueryResultItem.SettlementUserCount"> <summary> 结算人数 </summary> </member> <member name="T:FlexJobApi.Core.GetTaskEnterpriseQuery"> @@ -7839,6 +8189,152 @@ <member name="P:FlexJobApi.Core.GetArrangeTaskUsersQueryResultItem.ArrangeStatus"> <summary> 安排状态 </summary> </member> <member name="T:FlexJobApi.Core.GetSettlementTaskUsersQuery"> <summary> 查询结算名单分页列表数据 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQuery.TaskInfoId"> <summary> 任务Id </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQuery.Keywords"> <summary> 关键字 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQuery.SettlementOrderUrl"> <summary> 结算单地址 </summary> </member> <member name="T:FlexJobApi.Core.GetSettlementTaskUsersQueryResult"> <summary> 查询结算任务分页列表数据 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResult.Errors"> <summary> 错误信息 </summary> </member> <member name="T:FlexJobApi.Core.GetSettlementTaskUsersQueryResultError"> <summary> 查询结算任务分页列表数据 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultError.ErrorMessage"> <summary> 错误信息 </summary> </member> <member name="T:FlexJobApi.Core.GetSettlementTaskUsersQueryResultExcelRow"> <summary> 查询结算任务分页列表数据 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultExcelRow.Name"> <summary> 姓名 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultExcelRow.Identity"> <summary> 身份证号 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultExcelRow.SettlementAmount"> <summary> 结算金额 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultExcelRow.ActualSettlementAmount"> <summary> 实发金额 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultExcelRow.ReceiveAccount"> <summary> 收款账户 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultExcelRow.Bank"> <summary> 所属银行 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultExcelRow.BankBranch"> <summary> 开户支行名称 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultExcelRow.TaskName"> <summary> 任务名称 </summary> </member> <member name="T:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem"> <summary> 查询结算任务分页列表数据 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem.Id"> <summary> 任务用户Id </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem.Name"> <summary> 姓名 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem.Identity"> <summary> 身份证号 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem.ContactPhoneNumber"> <summary> 手机号 </summary> <remarks>联系电话</remarks> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem.CheckReceiveStatus"> <summary> 验收状态 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem.Bank"> <summary> 所属银行 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem.BankBranch"> <summary> 开户支行名称 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem.ReceiveAccount"> <summary> 收款账户 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem.SettlementAmount"> <summary> 结算金额 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem.ActualSettlementAmount"> <summary> 实发金额 </summary> </member> <member name="P:FlexJobApi.Core.GetSettlementTaskUsersQueryResultItem.SettlementTime"> <summary> 结算时间 </summary> </member> <member name="T:FlexJobApi.Core.GetTaskUserHireStatusQuery"> @@ -10022,6 +10518,11 @@ 关闭企业钱包 </summary> </member> <member name="P:FlexJobApi.Core.CloseEnterpriseWalletCommand.EnterpriseId"> <summary> 企业Id </summary> </member> <member name="P:FlexJobApi.Core.CloseEnterpriseWalletCommand.Access"> <summary> 通道 @@ -10122,6 +10623,11 @@ 开通企业钱包 </summary> </member> <member name="P:FlexJobApi.Core.OpenEnterpriseWalletCommand.EnterpriseId"> <summary> 企业Id </summary> </member> <member name="P:FlexJobApi.Core.OpenEnterpriseWalletCommand.Access"> <summary> 通道 @@ -10142,6 +10648,11 @@ 企业钱包充值 </summary> </member> <member name="P:FlexJobApi.Core.RechargeEnterpriseWalletCommand.EnterpriseId"> <summary> 企业Id </summary> </member> <member name="P:FlexJobApi.Core.RechargeEnterpriseWalletCommand.Access"> <summary> 通道 FlexJobApi.Core/Jobs/CompleteTaskSettlementT1Job.cs
New file @@ -0,0 +1,164 @@ using Aop.Api.Domain; using Furion; using Furion.DatabaseAccessor; using Furion.DistributedIDGenerator; using Furion.FriendlyException; using Furion.Schedule; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using static Microsoft.AspNetCore.Razor.Language.TagHelperMetadata; namespace FlexJobApi.Core { /// <summary> /// 完成任务结算T+1 /// </summary> public class CompleteTaskSettlementT1Job( IRepository<TaskInfo> rep, IRepository<TaskInfoUser> repTaskInfoUser, IRepository<EnterpriseWallet> repEnterpriseWallet, IRepository<EnterpriseWalletTransaction> repEnterpriseWalletTransaction, AlipayUtils alipayUtils ) : IJob { private readonly IRepository<TaskInfo> rep = rep; private readonly IRepository<TaskInfoUser> repTaskInfoUser = repTaskInfoUser; private readonly IRepository<EnterpriseWallet> repEnterpriseWallet = repEnterpriseWallet; private readonly AlipayUtils alipayUtils = alipayUtils; [UnitOfWork(false)] public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken) { var now = DateTime.Now; var env = App.GetConfig<string>("Environment"); var q = rep.AsQueryable() .Where(it => it.SettlementStatus == EnumTaskSettlementStatus.InProcess); var minTime = env == "Local" ? now.AddMinutes(-1) : env == "Test" ? now.AddMinutes(-5) : now.AddDays(-1); q = q.Where(it => it.SettlementStartTime.HasValue && it.SettlementStartTime < minTime); var tasks = await q.ToListAsync(); var enterpriseIds = tasks.DistinctSelect(it => it.EnterpriseId); var taskIds = tasks.DistinctSelect(it => it.Id); var taskUsers = await repTaskInfoUser .Where(it => taskIds.Contains(it.TaskInfoId) && it.SettlementStatus == EnumTaskSettlementStatus.InProcess) .ToListAsync(); var wallets = await repEnterpriseWallet.AsQueryable() .Where(it => enterpriseIds.Contains(it.EnterpriseId) && it.Access == EnumEnterpriseWalletAccess.Alipay) .ToListAsync(); foreach (var wallet in wallets) { 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.UpdateNowAsync(wallet); } if (tasks.IsNotNull()) { foreach (var task in tasks) { var wallet = wallets.FirstOrDefault(it => it.EnterpriseId == task.EnterpriseId); task.SettlementStatus = EnumTaskSettlementStatus.Completed; task.SettlementTime = DateTime.Now; await rep.UpdateNowAsync(task); var users = taskUsers.Where(it => it.TaskInfoId == task.Id).ToList(); foreach (var user in users) { user.SettlementStatus = EnumTaskSettlementStatus.Completed; user.SettlementTime = DateTime.Now; await repTaskInfoUser.UpdateNowAsync(user); var order = new EnterpriseWalletTransaction(); order.Type = EnumEnterpriseWalletTransactionType.Recharge; order.WalletId = wallet.Id; order.Amount = user.ActualSettlementAmount ?? 0; order.Remark = user.SettlementRemark; order.ProductCode = "SINGLE_TRANSFER_NO_PWD"; order.BizScene = "ENTRUST_TRANSFER"; order.TransactionStatus = EnumEnterpriseWalletTransactionStatus.WaitSubmit; order.Balance = wallet.Balance; await SetCode(order); await repEnterpriseWalletTransaction.InsertNowAsync(order); var response = alipayUtils.FundTransUniTransfer(new AlipayFundTransUniTransferModel { OutBizNo = order.Code, TransAmount = order.Amount.ToString(), ProductCode = order.ProductCode, BizScene = order.BizScene, PayeeInfo = new Participant { IdentityType = "ALIPAY_LOGON_ID", Identity = user.ReceiveAccount, Name = user.ReceiveName, }, PayerInfo = new Participant { IdentityType = "ACCOUNT_BOOK_ID", Identity = wallet.AccountBookId, ExtInfo = new { agreement_no = wallet.AgreementNo, }.ToJson(), }, OrderTitle = order.Remark, Remark = order.Remark, BusinessParams = new { withdraw_timeliness = "T0" }.ToJson() }, "/api/user/enterpriseWallet/alipayFundTransOrderChangedNotify"); if (response.IsError) { order.ErrorCode = response.Code; order.FailReason = response.SubMsg ?? response.Msg; } else { order.OrderId = response.OrderId; order.PayFundOrderId = response.PayFundOrderId; order.SettleSerialNo = response.SettleSerialNo; order.TransDate = response.TransDate.ToDateTime(); order.Link = response.Link; order.Status = response.Status; order.SubStatus = response.SubStatus; order.TransactionStatus = response.Status == "SUCCESS" ? EnumEnterpriseWalletTransactionStatus.Success : response.Status == "DEALING" ? EnumEnterpriseWalletTransactionStatus.Dealing : response.Status == "REFUND" ? EnumEnterpriseWalletTransactionStatus.Refund : EnumEnterpriseWalletTransactionStatus.Fail; await repEnterpriseWalletTransaction.UpdateNowAsync(order); } } } } } private async Task SetCode(EnterpriseWalletTransaction entity) { entity.Code = $"{DateTime.Now:yyyyMMddHHmmss}{new Random(IDGen.NextID().GetHashCode()).Next(1000, 9999)}"; var exist = await repEnterpriseWalletTransaction.AsQueryable().AsNoTracking() .AnyAsync(it => it.Code == entity.Code); if (exist) { await SetCode(entity); } } } } FlexJobApi.Core/Models/FlexJobServer/TaskUsers/Queries/GetSettlementTaskUsersQuery.cs
New file @@ -0,0 +1,164 @@ using MediatR; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.Core { /// <summary> /// 查询结算名单分页列表数据 /// </summary> [Resource([EnumResourceController.FlexJobServerTaskUser])] public class GetSettlementTaskUsersQuery : PagedListQuery<GetSettlementTaskUsersQueryResult, GetSettlementTaskUsersQueryResultItem> { /// <summary> /// 任务Id /// </summary> public Guid TaskInfoId { get; set; } /// <summary> /// 关键字 /// </summary> public string Keywords { get; set; } /// <summary> /// 结算单地址 /// </summary> public string SettlementOrderUrl { get; set; } } /// <summary> /// 查询结算任务分页列表数据 /// </summary> public class GetSettlementTaskUsersQueryResult : PagedListQueryResult<GetSettlementTaskUsersQueryResultItem> { /// <summary> /// 错误信息 /// </summary> public List<GetSettlementTaskUsersQueryResultError> Errors { get; set; } } /// <summary> /// 查询结算任务分页列表数据 /// </summary> public class GetSettlementTaskUsersQueryResultError : GetSettlementTaskUsersQueryResultExcelRow { /// <summary> /// 错误信息 /// </summary> public string ErrorMessage { get; set; } } /// <summary> /// 查询结算任务分页列表数据 /// </summary> public class GetSettlementTaskUsersQueryResultExcelRow { /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 身份证号 /// </summary> public string Identity { get; set; } /// <summary> /// 结算金额 /// </summary> public decimal? SettlementAmount { get; set; } /// <summary> /// 实发金额 /// </summary> public decimal? ActualSettlementAmount { get; set; } /// <summary> /// 收款账户 /// </summary> public string ReceiveAccount { get; set; } /// <summary> /// 所属银行 /// </summary> public string Bank { get; set; } /// <summary> /// 开户支行名称 /// </summary> public string BankBranch { get; set; } /// <summary> /// 任务名称 /// </summary> public string TaskName { get; set; } } /// <summary> /// 查询结算任务分页列表数据 /// </summary> public class GetSettlementTaskUsersQueryResultItem { /// <summary> /// 任务用户Id /// </summary> public Guid Id { get; set; } /// <summary> /// 姓名 /// </summary> [MaxLength(32)] public string Name { get; set; } /// <summary> /// 身份证号 /// </summary> public string Identity { get; set; } /// <summary> /// 手机号 /// </summary> /// <remarks>联系电话</remarks> [MaxLength(11)] public string ContactPhoneNumber { get; set; } /// <summary> /// 验收状态 /// </summary> public EnumTaskCheckReceiveStatus? CheckReceiveStatus { get; set; } /// <summary> /// 所属银行 /// </summary> public string Bank { get; set; } /// <summary> /// 开户支行名称 /// </summary> public string BankBranch { get; set; } /// <summary> /// 收款账户 /// </summary> public string ReceiveAccount { get; set; } /// <summary> /// 结算金额 /// </summary> public decimal? SettlementAmount { get; set; } /// <summary> /// 实发金额 /// </summary> public decimal? ActualSettlementAmount { get; set; } /// <summary> /// 结算时间 /// </summary> public DateTime? SettlementTime { get; set; } } } FlexJobApi.Core/Models/FlexJobServer/Tasks/Commands/RevokeTaskSettlementOrderCommand.cs
New file @@ -0,0 +1,21 @@ using MediatR; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.Core { /// <summary> /// 撤回结算 /// </summary> [Resource([EnumResourceController.FlexJobServerTask])] public class RevokeTaskSettlementOrderCommand : IRequest<Guid> { /// <summary> /// 任务Id /// </summary> public Guid TaskInfoId { get; set; } } } FlexJobApi.Core/Models/FlexJobServer/Tasks/Commands/SureTaskSettlementCommand.cs
New file @@ -0,0 +1,21 @@ using MediatR; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.Core { /// <summary> /// 确认结算 /// </summary> [Resource([EnumResourceController.FlexJobServerTask])] public class SureTaskSettlementCommand : IRequest<Guid> { /// <summary> /// 任务Id /// </summary> public Guid TaskInfoId { get; set; } } } FlexJobApi.Core/Models/FlexJobServer/Tasks/Commands/SureTaskSettlementOrderCommand.cs
New file @@ -0,0 +1,76 @@ using MediatR; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.Core { /// <summary> /// 确认结算单 /// </summary> [Resource([EnumResourceController.FlexJobServerTask])] public class SureTaskSettlementOrderCommand : IRequest<Guid> { /// <summary> /// 任务Id /// </summary> public Guid TaskInfoId { get; set; } /// <summary> /// 结算单地址 /// </summary> public string SettlementOrderUrl { get; set; } /// <summary> /// 结算名单 /// </summary> public List<SureTaskSettlementOrderCommandUser> TaskInfoUsers { get; set; } } /// <summary> /// 确认结算单 /// </summary> public class SureTaskSettlementOrderCommandUser { /// <summary> /// 任务用户Id /// </summary> public Guid Id { get; set; } /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 所属银行 /// </summary> public string Bank { get; set; } /// <summary> /// 开户支行名称 /// </summary> public string BankBranch { get; set; } /// <summary> /// 收款账户 /// </summary> [Required] public string ReceiveAccount { get; set; } /// <summary> /// 结算金额 /// </summary> [Required] public decimal? SettlementAmount { get; set; } /// <summary> /// 实发金额 /// </summary> [Required] public decimal? ActualSettlementAmount { get; set; } } } FlexJobApi.Core/Models/FlexJobServer/Tasks/Queries/GetSettlementTaskQuery.cs
New file @@ -0,0 +1,82 @@ using MediatR; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.Core { /// <summary> /// 查询结算单详情 /// </summary> [Resource([EnumResourceController.FlexJobServerTask])] public class GetSettlementTaskQuery : IRequest<GetSettlementTaskQueryResult> { /// <summary> /// Id /// </summary> public Guid Id { get; set; } } /// <summary> /// 查询结算单详情-结果 /// </summary> public class GetSettlementTaskQueryResult { /// <summary> /// Id /// </summary> public Guid Id { get; set; } /// <summary> /// 任务名称 /// </summary> public string Name { get; set; } /// <summary> /// 任务单号 /// </summary> public string Code { get; set; } /// <summary> /// 结算单状态 /// </summary> public EnumTaskSettlementOrderStatus? SettlementOrderStatus { get; set; } /// <summary> /// 结算单名称 /// </summary> public string SettlementOrderName { get; set; } /// <summary> /// 上传时间 /// </summary> public DateTime? SettlementOrderTime { get; set; } /// <summary> /// 实发金额 /// </summary> public decimal? ActualSettlementAmount { get; set; } /// <summary> /// 结算金额 /// </summary> public decimal? SettlementAmount { get; set; } /// <summary> /// 结算状态 /// </summary> public EnumTaskSettlementStatus? SettlementStatus { get; set; } /// <summary> /// 结算时间 /// </summary> public DateTime? SettlementTime { get; set; } /// <summary> /// 备注 /// </summary> public string SettlementRemark { get; set; } } } FlexJobApi.Core/Models/FlexJobServer/Tasks/Queries/GetSettlementTasksQuery.cs
New file @@ -0,0 +1,108 @@ using MediatR; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.Core { /// <summary> /// 查询结算任务分页列表数据 /// </summary> [Resource([EnumResourceController.FlexJobServerTask])] public class GetSettlementTasksQuery : PagedListQuery<GetSettlementTasksQueryResult, GetSettlementTasksQueryResultItem> { /// <summary> /// 关键字 /// </summary> public string Keywords { get; set; } /// <summary> /// 结算单状态 /// </summary> public EnumTaskSettlementOrderStatus? SettlementOrderStatus { get; set; } /// <summary> /// 结算状态 /// </summary> public EnumTaskSettlementStatus? SettlementStatus { get; set; } } /// <summary> /// 查询结算任务分页列表数据 /// </summary> public class GetSettlementTasksQueryResult : PagedListQueryResult<GetSettlementTasksQueryResultItem> { } /// <summary> /// 查询结算任务分页列表数据 /// </summary> public class GetSettlementTasksQueryResultItem { /// <summary> /// 任务Id /// </summary> public Guid Id { get; set; } /// <summary> /// 任务名称 /// </summary> public string Name { get; set; } /// <summary> /// 任务单号 /// </summary> public string Code { get; set; } /// <summary> /// 结算单状态 /// </summary> public EnumTaskSettlementOrderStatus? SettlementOrderStatus { get; set; } /// <summary> /// 结算单名称 /// </summary> public string SettlementOrderName { get; set; } /// <summary> /// 上传时间 /// </summary> public DateTime? SettlementOrderTime { get; set; } /// <summary> /// 实发金额 /// </summary> public decimal? ActualSettlementAmount { get; set; } /// <summary> /// 结算金额 /// </summary> public decimal? SettlementAmount { get; set; } /// <summary> /// 结算状态 /// </summary> public EnumTaskSettlementStatus? SettlementStatus { get; set; } /// <summary> /// 结算时间 /// </summary> public DateTime? SettlementTime { get; set; } /// <summary> /// 备注 /// </summary> public string SettlementRemark { get; set; } /// <summary> /// 结算人数 /// </summary> public int SettlementUserCount { get; set; } } } FlexJobApi.Core/Models/UserServer/EnterpriseWallets/Commands/CloseEnterpriseWalletCommand.cs
@@ -14,6 +14,10 @@ public class CloseEnterpriseWalletCommand : IRequest<Guid> { /// <summary> /// 企业Id /// </summary> public Guid? EnterpriseId { get; set; } /// <summary> /// 通道 /// </summary> public EnumEnterpriseWalletAccess Access { get; set; } FlexJobApi.Core/Models/UserServer/EnterpriseWallets/Commands/OpenEnterpriseWalletCommand.cs
@@ -14,6 +14,10 @@ public class OpenEnterpriseWalletCommand : IRequest<OpenEnterpriseWalletCommandResult> { /// <summary> /// 企业Id /// </summary> public Guid? EnterpriseId { get; set; } /// <summary> /// 通道 /// </summary> public EnumEnterpriseWalletAccess Access { get; set; } FlexJobApi.Core/Models/UserServer/EnterpriseWallets/Commands/RechargeEnterpriseWalletCommand.cs
@@ -14,6 +14,10 @@ public class RechargeEnterpriseWalletCommand : IRequest<RechargeEnterpriseWalletCommandResult> { /// <summary> /// 企业Id /// </summary> public Guid? EnterpriseId { get; set; } /// <summary> /// 通道 /// </summary> public EnumEnterpriseWalletAccess Access { get; set; } FlexJobApi.FlexJobServer.Application/FlexJobApi.FlexJobServer.Application.xml
@@ -85,7 +85,7 @@ 任务命令处理器 </summary> </member> <member name="M:FlexJobApi.FlexJobServer.Application.TaskInfoCommandHandler.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.TaskInfo})"> <member name="M:FlexJobApi.FlexJobServer.Application.TaskInfoCommandHandler.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.TaskInfo},Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.EnterpriseWallet},FlexJobApi.Core.AlipayUtils)"> <summary> 任务命令处理器 </summary> @@ -118,6 +118,30 @@ <member name="M:FlexJobApi.FlexJobServer.Application.TaskInfoCommandHandler.Handle(FlexJobApi.Core.DeleteTaskInfoCommand,System.Threading.CancellationToken)"> <summary> 删除任务 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:FlexJobApi.FlexJobServer.Application.TaskInfoCommandHandler.Handle(FlexJobApi.Core.SureTaskSettlementOrderCommand,System.Threading.CancellationToken)"> <summary> 确认结算单 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:FlexJobApi.FlexJobServer.Application.TaskInfoCommandHandler.Handle(FlexJobApi.Core.RevokeTaskSettlementOrderCommand,System.Threading.CancellationToken)"> <summary> 撤回结算 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:FlexJobApi.FlexJobServer.Application.TaskInfoCommandHandler.Handle(FlexJobApi.Core.SureTaskSettlementCommand,System.Threading.CancellationToken)"> <summary> 确认结算 </summary> <param name="request"></param> <param name="cancellationToken"></param> @@ -194,6 +218,22 @@ <member name="M:FlexJobApi.FlexJobServer.Application.TaskInfoQueryHandler.Handle(FlexJobApi.Core.GetPersonalCancelTaskInfosQuery,System.Threading.CancellationToken)"> <summary> 我的已取消分页列表 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:FlexJobApi.FlexJobServer.Application.TaskInfoQueryHandler.Handle(FlexJobApi.Core.GetSettlementTasksQuery,System.Threading.CancellationToken)"> <summary> 查询结算任务分页列表数据 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:FlexJobApi.FlexJobServer.Application.TaskInfoQueryHandler.Handle(FlexJobApi.Core.GetSettlementTaskQuery,System.Threading.CancellationToken)"> <summary> 查询结算单详情 </summary> <param name="request"></param> <param name="cancellationToken"></param> @@ -293,5 +333,13 @@ <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:FlexJobApi.FlexJobServer.Application.TaskUserQueryHandler.Handle(FlexJobApi.Core.GetSettlementTaskUsersQuery,System.Threading.CancellationToken)"> <summary> 查询结算名单分页列表数据 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> </members> </doc> FlexJobApi.FlexJobServer.Application/TaskCheckReceives/Commands/TaskCheckReceiveCommandHandler.cs
@@ -148,13 +148,15 @@ var taskUserCheckReceiveStatuses = await repTaskInfoUser.AsQueryable().AsNoTracking() .Where(it => it.TaskInfoId == task.Id && it.Id != taskUser.Id) && it.Id != taskUser.Id && it.ArrangeStatus == EnumTaskUserArrangeStatus.Complete) .Select(it => it.CheckReceiveStatus) .ToListAsync(); taskUserCheckReceiveStatuses.Add(EnumTaskCheckReceiveStatus.Completed); if (taskUserCheckReceiveStatuses.All(it => it == EnumTaskCheckReceiveStatus.Completed)) { task.CheckReceiveStatus = EnumTaskCheckReceiveStatus.Completed; task.SettlementOrderStatus = EnumTaskSettlementOrderStatus.Wait; } await repTaskInfoUserSubmit.UpdateAsync(submit); FlexJobApi.FlexJobServer.Application/TaskUsers/Queries/TaskUserQueryHandler.cs
@@ -1,6 +1,9 @@ using FlexJobApi.Core; using Aop.Api.Domain; using FlexJobApi.Core; using Furion.DatabaseAccessor; using Furion.DataValidation; using Furion.FriendlyException; using Mapster; using MediatR; using Microsoft.EntityFrameworkCore; using System; @@ -18,7 +21,8 @@ IRepository<TaskInfoUser> rep) : IRequestHandler<GetTaskUsersQuery, GetTaskUsersQueryResult>, IRequestHandler<GetArrangeTaskUsersQuery, GetArrangeTaskUsersQueryResult>, IRequestHandler<GetTaskUserHireStatusQuery, GetTaskUserHireStatusQueryResult> IRequestHandler<GetTaskUserHireStatusQuery, GetTaskUserHireStatusQueryResult>, IRequestHandler<GetSettlementTaskUsersQuery, GetSettlementTaskUsersQueryResult> { private readonly IRepository<TaskInfoUser> rep = rep; @@ -145,14 +149,137 @@ { q = q.Where(it => it.EnterpriseEmployee.UserId == request.UserId); } var model = await q .Select(it => new GetTaskUserHireStatusQueryResult { HireStatus = it.HireStatus }) .FirstOrDefaultAsync(cancellationToken); var model = await q .Select(it => new GetTaskUserHireStatusQueryResult { HireStatus = it.HireStatus }) .FirstOrDefaultAsync(cancellationToken); if (model == null) throw Oops.Oh(EnumErrorCodeType.s404, "报名信息"); return model; } /// <summary> /// 查询结算名单分页列表数据 /// </summary> /// <param name="request"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<GetSettlementTaskUsersQueryResult> Handle(GetSettlementTaskUsersQuery request, CancellationToken cancellationToken) { var logier = JwtUtils.GetCurrentLogier(); var q = rep.AsQueryable().AsNoTracking() .Where(it => it.TaskInfoId == request.TaskInfoId); var s = q .Select(it => new GetSettlementTaskUsersQueryResultItem { Id = it.Id, Name = it.EnterpriseEmployee.Name, Identity = it.EnterpriseEmployee.Identity, ContactPhoneNumber = it.EnterpriseEmployee.ContactPhoneNumber, CheckReceiveStatus = it.CheckReceiveStatus, Bank = it.Bank, BankBranch = it.BankBranch, ReceiveAccount = it.ReceiveAccount, SettlementAmount = it.SettlementAmount, ActualSettlementAmount = it.ActualSettlementAmount, SettlementTime = it.SettlementTime }); var list = await request.PageModel.GetPagedListAsync<GetSettlementTaskUsersQueryResult, GetSettlementTaskUsersQueryResultItem>(s, cancellationToken); var successList = new List<GetSettlementTaskUsersQueryResultExcelRow>(); if (request.SettlementOrderUrl.IsNotNull()) { var models = await ExcelUtils.ImportExcelFromOSS<GetSettlementTaskUsersQueryResultExcelRow>(request.SettlementOrderUrl); foreach (var model in models) { var errors = new List<string>(); if (model.Name.IsNull()) { errors.Add("请填写姓名"); } if (model.Identity.IsNull()) { errors.Add("请填写身份证号"); } else if (!model.Identity.TryValidate(EnumValidationTypes.ValiIdentity).IsValid) { errors.Add("身份证号格式不正确"); } else if (successList.Any(it => it.Identity == model.Identity)) { errors.Add("身份证号重复"); } if (model.Bank.IsNull()) { errors.Add("请填写所属银行"); } if (model.ReceiveAccount.IsNull()) { errors.Add("请填写收款账号"); } if (model.SettlementAmount == null) { errors.Add("请填写结算金额"); } else if (model.SettlementAmount < 0) { errors.Add("结算金额不可为负数"); } if (model.ActualSettlementAmount == null) { errors.Add("请填写实发金额"); } else if (model.ActualSettlementAmount < 0) { errors.Add("实发金额不可为负数"); } else if (model.ActualSettlementAmount > 0 && model.ActualSettlementAmount < 1) { errors.Add("实发金额不可小于1元"); } var item = list.Data.FirstOrDefault(it => it.Identity == model.Identity); if (item == null) { errors.Add("灵工不存在"); } else if (item.CheckReceiveStatus != EnumTaskCheckReceiveStatus.Completed) { errors.Add("未完成验收"); } else { item.SettlementAmount = model.SettlementAmount; item.ActualSettlementAmount = model.ActualSettlementAmount; item.ReceiveAccount = model.ReceiveAccount; item.Bank = model.Bank; item.BankBranch = model.BankBranch; } if (errors.IsNotNull()) { var error = model.Adapt<GetSettlementTaskUsersQueryResultError>(); error.ErrorMessage = errors.SplitJoin(","); list.Errors.Add(error); } else { successList.Add(model); } } } var pagedList = await list.Data .Where(it => successList.Any(s => s.Identity == it.Identity)) .AsQueryable() .ToPagedListAsync(request.PageModel.Page, request.PageModel.Rows, cancellationToken); list.PageModel = request.PageModel.Adapt<PagedListQueryResultPageModel>(); list.PageModel.TotalCount = pagedList.TotalCount; list.PageModel.TotalPage = pagedList.TotalPages; list.Data = pagedList.Items.ToList(); return list; } } } 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> /// 保存任务 @@ -140,6 +149,133 @@ }, 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) .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.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.ReceiveAccount = model.ReceiveAccount; user.SettlementAmount = model.SettlementAmount; user.ActualSettlementAmount = model.ActualSettlementAmount; 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(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 == EnumTaskSettlementStatus.Wait) 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)}"; FlexJobApi.FlexJobServer.Application/Tasks/Queries/TaskInfoQueryHandler.cs
@@ -24,7 +24,9 @@ IRequestHandler<GetTaskInfosQuery, GetTaskInfosQueryResult>, IRequestHandler<GetPersonalApplyTaskInfosQuery, GetPersonalApplyTaskInfosQueryResult>, IRequestHandler<GetPersonalHireTaskInfosQuery, GetPersonalHireTaskInfosQueryResult>, IRequestHandler<GetPersonalCancelTaskInfosQuery, GetPersonalCancelTaskInfosQueryResult> IRequestHandler<GetPersonalCancelTaskInfosQuery, GetPersonalCancelTaskInfosQueryResult>, IRequestHandler<GetSettlementTasksQuery, GetSettlementTasksQueryResult>, IRequestHandler<GetSettlementTaskQuery, GetSettlementTaskQueryResult> { private readonly IRepository<TaskInfo> rep = rep; @@ -381,5 +383,63 @@ return await request.PageModel.GetPagedListAsync<GetPersonalCancelTaskInfosQueryResult, GetPersonalCancelTaskInfosQueryResultItem>(s, cancellationToken); } /// <summary> /// 查询结算任务分页列表数据 /// </summary> /// <param name="request"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<GetSettlementTasksQueryResult> Handle(GetSettlementTasksQuery request, CancellationToken cancellationToken) { var logier = JwtUtils.GetCurrentLogier(); var q = TaskInfoRepository.GetQueryable(rep, true, logier) .Where(it => it.SettlementOrderStatus.HasValue && it.SettlementStatus.HasValue); if (request.Keywords.IsNotNull()) { q = q.Where(it => it.Name.Contains(request.Keywords) || it.Code.Contains(request.Keywords)); } if (request.SettlementOrderStatus.HasValue) { q = q.Where(it => it.SettlementOrderStatus == request.SettlementOrderStatus); } if (request.SettlementStatus.HasValue) { q = q.Where(it => it.SettlementStatus == request.SettlementStatus); } var s = q .Select(it=>new GetSettlementTasksQueryResultItem { Id = it.Id, Name = it.Name, Code = it.Code, SettlementOrderStatus = it.SettlementOrderStatus, SettlementOrderName = it.SettlementOrderName, SettlementOrderTime = it.SettlementOrderTime, ActualSettlementAmount = it.ActualSettlementAmount, SettlementAmount = it.SettlementAmount, SettlementStatus = it.SettlementStatus, SettlementTime = it.SettlementTime, SettlementRemark = it.SettlementRemark, SettlementUserCount = it.SettlementUserCount }); return await request.PageModel.GetPagedListAsync<GetSettlementTasksQueryResult, GetSettlementTasksQueryResultItem>(s, cancellationToken); } /// <summary> /// 查询结算单详情 /// </summary> /// <param name="request"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public Task<GetSettlementTaskQueryResult> Handle(GetSettlementTaskQuery request, CancellationToken cancellationToken) { var logier = JwtUtils.GetCurrentLogier(); var model = TaskInfoRepository.GetQueryable(rep, true, logier) .Where(it => it.Id == request.Id) .GetDetail<TaskInfo, GetSettlementTaskQueryResult>(); return model; } } } FlexJobApi.UserServer.Application/EnterpriseEmployees/Commands/EnterpriseEmployeesCommandHandler.cs
@@ -163,7 +163,7 @@ } } } if (errors.IsNotNull()) else { var error = model.Adapt<ImportEnterpriseEmployeesCommandResultError>(); error.ErrorMessage = errors.SplitJoin(","); FlexJobApi.UserServer.Application/EnterpriseWallets/Commands/EnterpriseWalletCommandHandler.cs
@@ -41,18 +41,23 @@ public async Task<OpenEnterpriseWalletCommandResult> Handle(OpenEnterpriseWalletCommand request, CancellationToken cancellationToken) { var logier = JwtUtils.GetCurrentLogier(); if (logier.Type == EnumUserType.Enterprise) { request.EnterpriseId = logier.EnterpriseId; } if (request.EnterpriseId == null) throw Oops.Oh(EnumErrorCodeType.s400, "请填写企业Id"); var enterprise = await repEnterprise.AsQueryable().AsNoTracking() .Where(it => it.Id == logier.EnterpriseId) .Where(it => it.Id == request.EnterpriseId) .FirstOrDefaultAsync(); if (enterprise == null) throw Oops.Oh(EnumErrorCodeType.s404, "企业"); if (!enterprise.IsReal) throw Oops.Oh(EnumErrorCodeType.s510, "请先实名"); var entity = await rep.AsQueryable() .Where(it => it.EnterpriseId == logier.EnterpriseId && it.Access == request.Access) .Where(it => it.EnterpriseId == request.EnterpriseId && it.Access == request.Access) .FirstOrDefaultAsync(); if (entity == null) { entity = new EnterpriseWallet(); entity.EnterpriseId = logier.EnterpriseId!.Value; entity.EnterpriseId = request.EnterpriseId!.Value; entity.Access = EnumEnterpriseWalletAccess.Alipay; entity.PersonalProductCode = "FUND_SAFT_SIGN_WITHHOLDING_P"; entity.SignScene = "INDUSTRY|SATF_ACC"; @@ -95,8 +100,13 @@ public async Task<Guid> Handle(CloseEnterpriseWalletCommand request, CancellationToken cancellationToken) { var logier = JwtUtils.GetCurrentLogier(); if (logier.Type == EnumUserType.Enterprise) { request.EnterpriseId = logier.EnterpriseId; } if (request.EnterpriseId == null) throw Oops.Oh(EnumErrorCodeType.s400, "请填写企业Id"); var entity = await rep.AsQueryable() .Where(it => it.EnterpriseId == logier.EnterpriseId && it.Access == request.Access) .Where(it => it.EnterpriseId == request.EnterpriseId && it.Access == request.Access) .FirstOrDefaultAsync(); if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "企业钱包"); if (entity.SignStatus != EnumEnterpriseWalletSignStatus.Normal) throw Oops.Oh(EnumErrorCodeType.s510, "未签约"); @@ -122,8 +132,13 @@ public async Task<RechargeEnterpriseWalletCommandResult> Handle(RechargeEnterpriseWalletCommand request, CancellationToken cancellationToken) { var logier = JwtUtils.GetCurrentLogier(); if (logier.Type == EnumUserType.Enterprise) { request.EnterpriseId = logier.EnterpriseId; } if (request.EnterpriseId == null) throw Oops.Oh(EnumErrorCodeType.s400, "请填写企业Id"); var entity = await rep.AsQueryable() .Where(it => it.EnterpriseId == logier.EnterpriseId && it.Access == request.Access) .Where(it => it.EnterpriseId == request.EnterpriseId && it.Access == request.Access) .FirstOrDefaultAsync(); if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "企业钱包"); if (entity.SignStatus != EnumEnterpriseWalletSignStatus.Normal) throw Oops.Oh(EnumErrorCodeType.s510, "未签约"); FlexJobApi.Web.Entry/Startup.cs
@@ -1,5 +1,6 @@ using Consul; using FlexJobApi.Core; using FlexJobApi.Core.Jobs; using Furion; using Furion.EventBus; using Furion.Schedule; @@ -60,6 +61,9 @@ //options.AddPersistence<DbJobPersistence>(); options.AddJob<CalcTaskSatusByDateJob>(Triggers.Hourly()); options.AddJob<CalcUserAgeByIdCardJob>(Triggers.Daily()); options.AddJob<RefreshEnterpriseWalletStatusJob>(Triggers.PeriodMinutes(5)); options.AddJob<RefreshEnterpriseWalletTransactionStatusJob>(Triggers.PeriodMinutes(2)); options.AddJob<CompleteTaskSettlementT1Job>(Triggers.PeriodMinutes(2)); }); services.AddSpecificationDocuments(options =>