sunpengfei
2025-11-19 3d67ad73e3e43acc97906ad82e46cffcf67cbaee
feat:平安转账开发
5个文件已修改
3个文件已添加
1690 ■■■■■ 已修改文件
ApiTools.Core/ApiTools.Core.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ApiTools.Core/Jobs/RefreshChannelWalletTransactionStatusJob.cs 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ApiTools.Core/Utils/ScheduleUtils/DbJobPersistence.cs 88 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ApiTools.Database.Migrations/Migrations/20251119014221_UpdateChannelWallet1119.Designer.cs 998 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ApiTools.Database.Migrations/Migrations/20251119014221_UpdateChannelWallet1119.cs 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ApiTools.Database.Migrations/Migrations/DefaultDbContextModelSnapshot.cs 347 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ApiTools.Database.Migrations/REDEME.MD 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ApiTools.Web.Entry/Startup.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ApiTools.Core/ApiTools.Core.xml
@@ -1973,6 +1973,16 @@
            编号
            </summary>
        </member>
        <member name="T:ApiTools.Core.RefreshChannelWalletTransactionStatusJob">
            <summary>
            刷新渠道钱包交易状态
            </summary>
        </member>
        <member name="M:ApiTools.Core.RefreshChannelWalletTransactionStatusJob.#ctor(ApiTools.Core.ChannelWalletRepository,ApiTools.Core.ChannelWalletTransactionRepository,ApiTools.Core.ChannelWalletService)">
            <summary>
            刷新渠道钱包交易状态
            </summary>
        </member>
        <member name="T:ApiTools.Core.ChangePhoneNumberCommand">
            <summary>
            更换手机号
ApiTools.Core/Jobs/RefreshChannelWalletTransactionStatusJob.cs
New file
@@ -0,0 +1,58 @@
using Furion;
using Furion.DatabaseAccessor;
using Furion.EventBus;
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;
namespace ApiTools.Core
{
    /// <summary>
    /// 刷新渠道钱包交易状态
    /// </summary>
    [JobDetail("RefreshChannelWalletTransactionStatusJob", Description = "刷新渠道钱包交易状态", Concurrent = false)]
    [PeriodMinutes(5)]
    public class RefreshChannelWalletTransactionStatusJob(
            ChannelWalletRepository channelWalletRepository,
            ChannelWalletTransactionRepository channelWalletTransactionRepository,
            ChannelWalletService channelWalletService
        ) : IJob
    {
        private readonly ChannelWalletRepository channelWalletRepository = channelWalletRepository;
        private readonly ChannelWalletTransactionRepository channelWalletTransactionRepository = channelWalletTransactionRepository;
        private readonly ChannelWalletService channelWalletService = channelWalletService;
        public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
        {
            var env = App.GetConfig<string>("Environment");
            if (env != "Local")
            {
                var transactions = await channelWalletTransactionRepository.GetQueryable(false)
                .Where(it =>
                    it.TransactionStatus == EnumWalletTransactionStatus.WaitPay
                    || it.TransactionStatus == EnumWalletTransactionStatus.Dealing)
                .ToListAsync();
                var walletIds = transactions.DistinctSelect(it => it.WalletId);
                var wallets = await channelWalletRepository.GetQueryable(false)
                    .Where(it => walletIds.Contains(it.Id))
                    .ToListAsync();
                foreach (var transaction in transactions)
                {
                    var wallet = wallets.FirstOrDefault(it => it.Id == transaction.WalletId);
                    if (wallet != null)
                    {
                        // 查询交易详情
                        await channelWalletService.GetTransactionDetail(wallet, transaction);
                        // 下载回单
                        await channelWalletService.DownloadEreceiptUrl(wallet, transaction);
                    }
                }
            }
        }
    }
}
ApiTools.Core/Utils/ScheduleUtils/DbJobPersistence.cs
@@ -16,21 +16,13 @@
    /// <summary>
    /// 作业持久化(数据库)
    /// </summary>
    public class DbJobPersistence : IJobPersistence, IDisposable
    public class DbJobPersistence : IJobPersistence
    {
        private readonly IServiceScope _serviceScope;
        private readonly IRepository<ScheduleJobDetail> repScheduleJobDetail;
        private readonly IRepository<ScheduleJobTrigger> repScheduleJobTrigger;
        private readonly IRepository<ScheduleJobTriggerTimeline, LogDbContextLocator> repScheduleJobTriggerTimeline;
        private readonly IServiceScopeFactory serviceScopeFactory;
        public DbJobPersistence(IServiceScopeFactory scopeFactory)
        public DbJobPersistence(IServiceScopeFactory serviceScopeFactory)
        {
            _serviceScope = scopeFactory.CreateScope();
            var services = _serviceScope.ServiceProvider;
            repScheduleJobDetail = services.GetService<IRepository<ScheduleJobDetail>>();
            repScheduleJobTrigger = services.GetService<IRepository<ScheduleJobTrigger>>();
            repScheduleJobTriggerTimeline = services.GetService<IRepository<ScheduleJobTriggerTimeline, LogDbContextLocator>>();
            this.serviceScopeFactory = serviceScopeFactory;
        }
        /// <summary>
@@ -44,78 +36,28 @@
        public Task<SchedulerBuilder> OnLoadingAsync(SchedulerBuilder builder, CancellationToken stoppingToken)
        {
            // 标记从其他地方更新,比如数据库
            return Task.FromResult(builder);
        }
        public async Task OnChangedAsync(PersistenceContext context)
        public Task OnChangedAsync(PersistenceContext context)
        {
            switch (context.Behavior)
            {
                case PersistenceBehavior.Appended:
                    var insertEntity = new ScheduleJobDetail();
                    context.JobDetail.Adapt(insertEntity);
                    await repScheduleJobDetail.InsertNowAsync(insertEntity);
                    break;
                case PersistenceBehavior.Updated:
                    var updateEntity = await repScheduleJobDetail.AsQueryable().FirstOrDefaultAsync(it => it.JobId == context.JobId);
                    if (updateEntity != null)
                    {
                        context.JobDetail.Adapt(updateEntity);
                        await repScheduleJobDetail.UpdateNowAsync(updateEntity);
                    }
                    break;
                case PersistenceBehavior.Removed:
                    var deleteEntity = await repScheduleJobDetail.AsQueryable().FirstOrDefaultAsync(it => it.JobId == context.JobId);
                    if (deleteEntity != null)
                    {
                        await repScheduleJobDetail.DeleteNowAsync(deleteEntity);
                    }
                    break;
                default:
                    break;
            }
            return Task.CompletedTask;
        }
        public async Task OnTriggerChangedAsync(PersistenceTriggerContext context)
        public Task OnTriggerChangedAsync(PersistenceTriggerContext context)
        {
            switch (context.Behavior)
            {
                case PersistenceBehavior.Appended:
                    var insertEntity = new ScheduleJobTrigger();
                    context.Trigger.Adapt(insertEntity);
                    await repScheduleJobTrigger.InsertNowAsync(insertEntity);
                    break;
                case PersistenceBehavior.Updated:
                    var updateEntity = await repScheduleJobTrigger.AsQueryable().FirstOrDefaultAsync(it => it.JobId == context.JobId && it.TriggerId == context.TriggerId);
                    if (updateEntity != null)
                    {
                        context.Trigger.Adapt(updateEntity);
                        await repScheduleJobTrigger.UpdateNowAsync(updateEntity);
                    }
                    break;
                case PersistenceBehavior.Removed:
                    var deleteEntity = await repScheduleJobTrigger.AsQueryable().FirstOrDefaultAsync(it => it.JobId == context.JobId && it.TriggerId == context.TriggerId);
                    if (deleteEntity != null)
                    {
                        await repScheduleJobTrigger.DeleteNowAsync(deleteEntity);
                    }
                    break;
                default:
                    break;
            }
            return Task.CompletedTask;
        }
        public async Task OnExecutionRecordAsync(PersistenceExecutionRecordContext context)
        {
            var entity = new ScheduleJobTriggerTimeline();
            context.Timeline.Adapt(entity);
            await repScheduleJobTriggerTimeline.InsertNowAsync(entity);
        }
        public void Dispose()
        {
            _serviceScope?.Dispose();
            using (var scope = serviceScopeFactory.CreateScope())
            {
                var rep = scope.ServiceProvider.GetRequiredService<IRepository<ScheduleJobTriggerTimeline, LogDbContextLocator>>();
                var entity = new ScheduleJobTriggerTimeline();
                context.Timeline.Adapt(entity);
                await rep.InsertNowAsync(entity);
            }
        }
    }
}
ApiTools.Database.Migrations/Migrations/20251119014221_UpdateChannelWallet1119.Designer.cs
New file
@@ -0,0 +1,998 @@
// <auto-generated />
using System;
using ApiTools.EntityFramework.Core;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace ApiTools.Database.Migrations.Migrations
{
    [DbContext(typeof(DefaultDbContext))]
    [Migration("20251119014221_UpdateChannelWallet1119")]
    partial class UpdateChannelWallet1119
    {
        /// <inheritdoc />
        protected override void BuildTargetModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("ProductVersion", "9.0.2")
                .HasAnnotation("Relational:MaxIdentifierLength", 128);
            SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
            modelBuilder.Entity("ApiTools.Core.Channel", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Code")
                        .HasColumnType("nvarchar(max)");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<bool>("IsDisabled")
                        .HasColumnType("bit");
                    b.Property<string>("Name")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.HasKey("Id");
                    b.ToTable("Channel");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWallet", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<int>("Access")
                        .HasColumnType("int");
                    b.Property<decimal>("Balance")
                        .HasColumnType("decimal(18,2)");
                    b.Property<string>("Bank")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("BankBranch")
                        .HasColumnType("nvarchar(max)");
                    b.Property<Guid?>("ChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Code")
                        .HasColumnType("nvarchar(max)");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("ErrorCode")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("FailReason")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("Identity")
                        .HasColumnType("nvarchar(max)");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<string>("Name")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("OutWalletId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("SignStatus")
                        .HasColumnType("int");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.HasKey("Id");
                    b.HasIndex("ChannelId");
                    b.ToTable("ChannelWallet");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<decimal>("AfterBalance")
                        .HasColumnType("decimal(18,2)");
                    b.Property<decimal>("Amount")
                        .HasColumnType("decimal(18,2)");
                    b.Property<decimal>("Balance")
                        .HasColumnType("decimal(18,2)");
                    b.Property<string>("Code")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ConcurrencyLock")
                        .HasColumnType("nvarchar(450)");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Currency")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("EreceiptDownloadOssUrl")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("EreceiptDownloadUrl")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("EreceiptErrorMessage")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("EreceiptFileId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int?>("EreceiptStatus")
                        .HasColumnType("int");
                    b.Property<string>("ErrorCode")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("FailReason")
                        .HasColumnType("nvarchar(max)");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<DateTime?>("OperatorTime")
                        .HasColumnType("datetime2");
                    b.Property<decimal?>("OrderFee")
                        .HasColumnType("decimal(18,2)");
                    b.Property<string>("OutCode")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("OutOperatorId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("OutReceiveId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("PayerAccount")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("PayerBank")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("PayerBankBranch")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("PayerName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("Purpose")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ReceiveAccount")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ReceiveBank")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ReceiveBankBranch")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ReceiveIdentity")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ReceiveName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("Remark")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTime?>("TransDate")
                        .HasColumnType("datetime2");
                    b.Property<int>("TransactionStatus")
                        .HasColumnType("int");
                    b.Property<int>("Type")
                        .HasColumnType("int");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<Guid>("WalletId")
                        .HasColumnType("uniqueidentifier");
                    b.HasKey("Id");
                    b.HasIndex("ConcurrencyLock")
                        .IsUnique()
                        .HasFilter("[ConcurrencyLock] IS NOT NULL");
                    b.HasIndex("WalletId");
                    b.ToTable("ChannelWalletTransaction");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWalletTransactionPingAnPay", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("AccountDate")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("BackRem")
                        .HasColumnType("nvarchar(max)");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("CstInnerFlowNo")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("Fee")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("FreezeNo")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("FrontLogNo")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("HostErrorCode")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("HostFlowNo")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("IsBack")
                        .HasColumnType("nvarchar(max)");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<string>("ProxyPayAcc")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ProxyPayBankName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ProxyPayName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("RemoveStopFailReason")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("RemoveStopStt")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<string>("StopFailReason")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("StopStt")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("SubmitTime")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("SysFlag")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ThirdVoucher")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("TransBsn")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Yhcljg")
                        .HasColumnType("nvarchar(max)");
                    b.HasKey("Id");
                    b.ToTable("ChannelWalletTransactionPingAnPay");
                });
            modelBuilder.Entity("ApiTools.Core.Resource", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("ActionName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ActionSummary")
                        .HasColumnType("nvarchar(max)");
                    b.Property<bool>("AllowAnonymous")
                        .HasColumnType("bit");
                    b.Property<string>("ApplicationName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("Code")
                        .IsRequired()
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ControllerName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ControllerSummary")
                        .HasColumnType("nvarchar(max)");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<bool>("CustomResponse")
                        .HasColumnType("bit");
                    b.Property<string>("DynamicAssemblyName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<bool>("FileUpload")
                        .HasColumnType("bit");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<bool>("IsExpired")
                        .HasColumnType("bit");
                    b.Property<bool>("IsFromForm")
                        .HasColumnType("bit");
                    b.Property<int>("Method")
                        .HasColumnType("int");
                    b.Property<string>("Name")
                        .IsRequired()
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("RequestTypeFullName")
                        .IsRequired()
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("RequestTypeName")
                        .IsRequired()
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ResponseTypeFullName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ResponseTypeName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("Route")
                        .IsRequired()
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("RouteArea")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ServiceName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.HasKey("Id");
                    b.ToTable("Resource");
                });
            modelBuilder.Entity("ApiTools.Core.ScheduleJobDetail", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("AssemblyName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<bool>("Concurrent")
                        .HasColumnType("bit");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Description")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("GroupName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<bool>("IncludeAnnotations")
                        .HasColumnType("bit");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<string>("JobId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("JobType")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("Properties")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.HasKey("Id");
                    b.ToTable("ScheduleJobDetail");
                });
            modelBuilder.Entity("ApiTools.Core.ScheduleJobTrigger", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Args")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("AssemblyName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Description")
                        .HasColumnType("nvarchar(max)");
                    b.Property<long>("ElapsedTime")
                        .HasColumnType("bigint");
                    b.Property<DateTime?>("EndTime")
                        .HasColumnType("datetime2");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<string>("JobId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTime?>("LastRunTime")
                        .HasColumnType("datetime2");
                    b.Property<long>("MaxNumberOfErrors")
                        .HasColumnType("bigint");
                    b.Property<long>("MaxNumberOfRuns")
                        .HasColumnType("bigint");
                    b.Property<DateTime?>("NextRunTime")
                        .HasColumnType("datetime2");
                    b.Property<long>("NumRetries")
                        .HasColumnType("bigint");
                    b.Property<long>("NumberOfErrors")
                        .HasColumnType("bigint");
                    b.Property<long>("NumberOfRuns")
                        .HasColumnType("bigint");
                    b.Property<bool>("ResetOnlyOnce")
                        .HasColumnType("bit");
                    b.Property<string>("Result")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("RetryTimeout")
                        .HasColumnType("int");
                    b.Property<bool>("RunOnStart")
                        .HasColumnType("bit");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<bool>("StartNow")
                        .HasColumnType("bit");
                    b.Property<DateTime?>("StartTime")
                        .HasColumnType("datetime2");
                    b.Property<long>("Status")
                        .HasColumnType("bigint");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("TriggerId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("TriggerType")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.HasKey("Id");
                    b.ToTable("ScheduleJobTrigger");
                });
            modelBuilder.Entity("ApiTools.Core.SmsLog", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<int>("Access")
                        .HasColumnType("int");
                    b.Property<Guid?>("ChannelCreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<Guid?>("ChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Code")
                        .HasColumnType("nvarchar(max)");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTime?>("Expiry")
                        .HasColumnType("datetime2");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<bool>("IsUsed")
                        .HasColumnType("bit");
                    b.Property<string>("Message")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("PhoneNumber")
                        .IsRequired()
                        .HasMaxLength(11)
                        .HasColumnType("nvarchar(11)");
                    b.Property<string>("RequestId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<int>("Status")
                        .HasColumnType("int");
                    b.Property<string>("TemplateCode")
                        .IsRequired()
                        .HasMaxLength(128)
                        .HasColumnType("nvarchar(128)");
                    b.Property<string>("TemplateParam")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.HasKey("Id");
                    b.HasIndex("ChannelId");
                    b.ToTable("SmsLog");
                });
            modelBuilder.Entity("ApiTools.Core.SmsSetting", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<Guid?>("ChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<int>("DailyMaxCount")
                        .HasColumnType("int");
                    b.Property<int>("HourlyMaxCount")
                        .HasColumnType("int");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<bool>("IsDisabled")
                        .HasColumnType("bit");
                    b.Property<int>("MinutelyMaxCount")
                        .HasColumnType("int");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<bool>("WithoutParams")
                        .HasColumnType("bit");
                    b.HasKey("Id");
                    b.HasIndex("ChannelId");
                    b.ToTable("SmsSetting");
                });
            modelBuilder.Entity("ApiTools.Core.SmsSettingAccess", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<int>("Access")
                        .HasColumnType("int");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<bool>("IsDisabled")
                        .HasColumnType("bit");
                    b.Property<Guid>("SettingId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("SignName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.HasKey("Id");
                    b.HasIndex("SettingId");
                    b.ToTable("SmsSettingAccess");
                });
            modelBuilder.Entity("ApiTools.Core.User", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Avatar")
                        .HasColumnType("nvarchar(max)");
                    b.Property<Guid?>("ChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<bool>("IsCheckPhoneNumber")
                        .HasColumnType("bit");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<int>("Level")
                        .HasColumnType("int");
                    b.Property<string>("Name")
                        .HasMaxLength(32)
                        .HasColumnType("nvarchar(32)");
                    b.Property<string>("Password")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("PhoneNumber")
                        .HasMaxLength(11)
                        .HasColumnType("nvarchar(11)");
                    b.Property<string>("Remark")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<int>("Status")
                        .HasColumnType("int");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("Type")
                        .HasColumnType("int");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("UserName")
                        .IsRequired()
                        .HasMaxLength(32)
                        .HasColumnType("nvarchar(32)");
                    b.HasKey("Id");
                    b.HasIndex("ChannelId");
                    b.ToTable("User");
                    b.HasData(
                        new
                        {
                            Id = new Guid("11111111-1111-1111-1111-111111111111"),
                            CreatedTime = new DateTimeOffset(new DateTime(2000, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 8, 0, 0, 0)),
                            IsCheckPhoneNumber = false,
                            IsDeleted = false,
                            Level = 999,
                            Name = "管理员",
                            Password = "iEYggKrMhQ3ASUGLobra1w==:fn/DsMJUbD9FGpvBvR3moMpMPptdxzZlourPVhU479I=",
                            Sort = 0,
                            Status = 10,
                            Type = 100,
                            UserName = "system"
                        });
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWallet", b =>
                {
                    b.HasOne("ApiTools.Core.Channel", "Channel")
                        .WithMany()
                        .HasForeignKey("ChannelId");
                    b.Navigation("Channel");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b =>
                {
                    b.HasOne("ApiTools.Core.ChannelWallet", "Wallet")
                        .WithMany()
                        .HasForeignKey("WalletId")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();
                    b.Navigation("Wallet");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWalletTransactionPingAnPay", b =>
                {
                    b.HasOne("ApiTools.Core.ChannelWalletTransaction", "Transaction")
                        .WithOne("PingAnPay")
                        .HasForeignKey("ApiTools.Core.ChannelWalletTransactionPingAnPay", "Id")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();
                    b.Navigation("Transaction");
                });
            modelBuilder.Entity("ApiTools.Core.SmsLog", b =>
                {
                    b.HasOne("ApiTools.Core.Channel", "Channel")
                        .WithMany()
                        .HasForeignKey("ChannelId");
                    b.Navigation("Channel");
                });
            modelBuilder.Entity("ApiTools.Core.SmsSetting", b =>
                {
                    b.HasOne("ApiTools.Core.Channel", "Channel")
                        .WithMany()
                        .HasForeignKey("ChannelId");
                    b.Navigation("Channel");
                });
            modelBuilder.Entity("ApiTools.Core.SmsSettingAccess", b =>
                {
                    b.HasOne("ApiTools.Core.SmsSetting", "Setting")
                        .WithMany("Accesses")
                        .HasForeignKey("SettingId")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();
                    b.Navigation("Setting");
                });
            modelBuilder.Entity("ApiTools.Core.User", b =>
                {
                    b.HasOne("ApiTools.Core.Channel", "Channel")
                        .WithMany()
                        .HasForeignKey("ChannelId");
                    b.Navigation("Channel");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b =>
                {
                    b.Navigation("PingAnPay");
                });
            modelBuilder.Entity("ApiTools.Core.SmsSetting", b =>
                {
                    b.Navigation("Accesses");
                });
#pragma warning restore 612, 618
        }
    }
}
ApiTools.Database.Migrations/Migrations/20251119014221_UpdateChannelWallet1119.cs
New file
@@ -0,0 +1,185 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ApiTools.Database.Migrations.Migrations
{
    /// <inheritdoc />
    public partial class UpdateChannelWallet1119 : Migration
    {
        /// <inheritdoc />
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "ChannelWallet",
                columns: table => new
                {
                    Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
                    ChannelId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                    OutWalletId = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Access = table.Column<int>(type: "int", nullable: false),
                    Code = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Bank = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    BankBranch = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Identity = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Balance = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
                    SignStatus = table.Column<int>(type: "int", nullable: false),
                    ErrorCode = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    FailReason = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Sort = table.Column<int>(type: "int", nullable: false),
                    TraceId = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    CreatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
                    CreatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                    CreatedChannelId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                    UpdatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true),
                    UpdatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                    IsDeleted = table.Column<bool>(type: "bit", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_ChannelWallet", x => x.Id);
                    table.ForeignKey(
                        name: "FK_ChannelWallet_Channel_ChannelId",
                        column: x => x.ChannelId,
                        principalTable: "Channel",
                        principalColumn: "Id");
                });
            migrationBuilder.CreateTable(
                name: "ChannelWalletTransaction",
                columns: table => new
                {
                    Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
                    WalletId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
                    Type = table.Column<int>(type: "int", nullable: false),
                    Code = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    OutCode = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ConcurrencyLock = table.Column<string>(type: "nvarchar(450)", nullable: true),
                    Amount = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
                    Balance = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
                    AfterBalance = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
                    OutOperatorId = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    OperatorTime = table.Column<DateTime>(type: "datetime2", nullable: true),
                    PayerAccount = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    PayerName = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    PayerBank = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    PayerBankBranch = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    OutReceiveId = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ReceiveName = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ReceiveIdentity = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ReceiveAccount = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ReceiveBank = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ReceiveBankBranch = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Currency = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Purpose = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Remark = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ErrorCode = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    FailReason = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    TransDate = table.Column<DateTime>(type: "datetime2", nullable: true),
                    OrderFee = table.Column<decimal>(type: "decimal(18,2)", nullable: true),
                    EreceiptFileId = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    EreceiptDownloadUrl = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    EreceiptDownloadOssUrl = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    EreceiptStatus = table.Column<int>(type: "int", nullable: true),
                    EreceiptErrorMessage = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    TransactionStatus = table.Column<int>(type: "int", nullable: false),
                    Sort = table.Column<int>(type: "int", nullable: false),
                    TraceId = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    CreatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
                    CreatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                    CreatedChannelId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                    UpdatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true),
                    UpdatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                    IsDeleted = table.Column<bool>(type: "bit", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_ChannelWalletTransaction", x => x.Id);
                    table.ForeignKey(
                        name: "FK_ChannelWalletTransaction_ChannelWallet_WalletId",
                        column: x => x.WalletId,
                        principalTable: "ChannelWallet",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                });
            migrationBuilder.CreateTable(
                name: "ChannelWalletTransactionPingAnPay",
                columns: table => new
                {
                    Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
                    FreezeNo = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    StopStt = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    StopFailReason = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    RemoveStopStt = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    RemoveStopFailReason = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ThirdVoucher = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    FrontLogNo = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    CstInnerFlowNo = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    IsBack = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    BackRem = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Yhcljg = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    SysFlag = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Fee = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    TransBsn = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    SubmitTime = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    AccountDate = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    HostFlowNo = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    HostErrorCode = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ProxyPayName = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ProxyPayAcc = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ProxyPayBankName = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Sort = table.Column<int>(type: "int", nullable: false),
                    TraceId = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    CreatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
                    CreatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                    CreatedChannelId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                    UpdatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true),
                    UpdatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                    IsDeleted = table.Column<bool>(type: "bit", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_ChannelWalletTransactionPingAnPay", x => x.Id);
                    table.ForeignKey(
                        name: "FK_ChannelWalletTransactionPingAnPay_ChannelWalletTransaction_Id",
                        column: x => x.Id,
                        principalTable: "ChannelWalletTransaction",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                });
            migrationBuilder.CreateIndex(
                name: "IX_ChannelWallet_ChannelId",
                table: "ChannelWallet",
                column: "ChannelId");
            migrationBuilder.CreateIndex(
                name: "IX_ChannelWalletTransaction_ConcurrencyLock",
                table: "ChannelWalletTransaction",
                column: "ConcurrencyLock",
                unique: true,
                filter: "[ConcurrencyLock] IS NOT NULL");
            migrationBuilder.CreateIndex(
                name: "IX_ChannelWalletTransaction_WalletId",
                table: "ChannelWalletTransaction",
                column: "WalletId");
        }
        /// <inheritdoc />
        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "ChannelWalletTransactionPingAnPay");
            migrationBuilder.DropTable(
                name: "ChannelWalletTransaction");
            migrationBuilder.DropTable(
                name: "ChannelWallet");
        }
    }
}
ApiTools.Database.Migrations/Migrations/DefaultDbContextModelSnapshot.cs
@@ -66,6 +66,317 @@
                    b.ToTable("Channel");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWallet", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<int>("Access")
                        .HasColumnType("int");
                    b.Property<decimal>("Balance")
                        .HasColumnType("decimal(18,2)");
                    b.Property<string>("Bank")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("BankBranch")
                        .HasColumnType("nvarchar(max)");
                    b.Property<Guid?>("ChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Code")
                        .HasColumnType("nvarchar(max)");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("ErrorCode")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("FailReason")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("Identity")
                        .HasColumnType("nvarchar(max)");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<string>("Name")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("OutWalletId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("SignStatus")
                        .HasColumnType("int");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.HasKey("Id");
                    b.HasIndex("ChannelId");
                    b.ToTable("ChannelWallet");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<decimal>("AfterBalance")
                        .HasColumnType("decimal(18,2)");
                    b.Property<decimal>("Amount")
                        .HasColumnType("decimal(18,2)");
                    b.Property<decimal>("Balance")
                        .HasColumnType("decimal(18,2)");
                    b.Property<string>("Code")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ConcurrencyLock")
                        .HasColumnType("nvarchar(450)");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Currency")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("EreceiptDownloadOssUrl")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("EreceiptDownloadUrl")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("EreceiptErrorMessage")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("EreceiptFileId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int?>("EreceiptStatus")
                        .HasColumnType("int");
                    b.Property<string>("ErrorCode")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("FailReason")
                        .HasColumnType("nvarchar(max)");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<DateTime?>("OperatorTime")
                        .HasColumnType("datetime2");
                    b.Property<decimal?>("OrderFee")
                        .HasColumnType("decimal(18,2)");
                    b.Property<string>("OutCode")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("OutOperatorId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("OutReceiveId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("PayerAccount")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("PayerBank")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("PayerBankBranch")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("PayerName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("Purpose")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ReceiveAccount")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ReceiveBank")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ReceiveBankBranch")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ReceiveIdentity")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ReceiveName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("Remark")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTime?>("TransDate")
                        .HasColumnType("datetime2");
                    b.Property<int>("TransactionStatus")
                        .HasColumnType("int");
                    b.Property<int>("Type")
                        .HasColumnType("int");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<Guid>("WalletId")
                        .HasColumnType("uniqueidentifier");
                    b.HasKey("Id");
                    b.HasIndex("ConcurrencyLock")
                        .IsUnique()
                        .HasFilter("[ConcurrencyLock] IS NOT NULL");
                    b.HasIndex("WalletId");
                    b.ToTable("ChannelWalletTransaction");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWalletTransactionPingAnPay", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("AccountDate")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("BackRem")
                        .HasColumnType("nvarchar(max)");
                    b.Property<Guid?>("CreatedChannelId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<DateTimeOffset>("CreatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("CreatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("CstInnerFlowNo")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("Fee")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("FreezeNo")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("FrontLogNo")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("HostErrorCode")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("HostFlowNo")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("IsBack")
                        .HasColumnType("nvarchar(max)");
                    b.Property<bool>("IsDeleted")
                        .HasColumnType("bit");
                    b.Property<string>("ProxyPayAcc")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ProxyPayBankName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ProxyPayName")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("RemoveStopFailReason")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("RemoveStopStt")
                        .HasColumnType("nvarchar(max)");
                    b.Property<int>("Sort")
                        .HasColumnType("int");
                    b.Property<string>("StopFailReason")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("StopStt")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("SubmitTime")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("SysFlag")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("ThirdVoucher")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("TraceId")
                        .HasColumnType("nvarchar(max)");
                    b.Property<string>("TransBsn")
                        .HasColumnType("nvarchar(max)");
                    b.Property<DateTimeOffset?>("UpdatedTime")
                        .HasColumnType("datetimeoffset");
                    b.Property<Guid?>("UpdatedUserId")
                        .HasColumnType("uniqueidentifier");
                    b.Property<string>("Yhcljg")
                        .HasColumnType("nvarchar(max)");
                    b.HasKey("Id");
                    b.ToTable("ChannelWalletTransactionPingAnPay");
                });
            modelBuilder.Entity("ApiTools.Core.Resource", b =>
                {
                    b.Property<Guid>("Id")
@@ -600,6 +911,37 @@
                        });
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWallet", b =>
                {
                    b.HasOne("ApiTools.Core.Channel", "Channel")
                        .WithMany()
                        .HasForeignKey("ChannelId");
                    b.Navigation("Channel");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b =>
                {
                    b.HasOne("ApiTools.Core.ChannelWallet", "Wallet")
                        .WithMany()
                        .HasForeignKey("WalletId")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();
                    b.Navigation("Wallet");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWalletTransactionPingAnPay", b =>
                {
                    b.HasOne("ApiTools.Core.ChannelWalletTransaction", "Transaction")
                        .WithOne("PingAnPay")
                        .HasForeignKey("ApiTools.Core.ChannelWalletTransactionPingAnPay", "Id")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();
                    b.Navigation("Transaction");
                });
            modelBuilder.Entity("ApiTools.Core.SmsLog", b =>
                {
                    b.HasOne("ApiTools.Core.Channel", "Channel")
@@ -638,6 +980,11 @@
                    b.Navigation("Channel");
                });
            modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b =>
                {
                    b.Navigation("PingAnPay");
                });
            modelBuilder.Entity("ApiTools.Core.SmsSetting", b =>
                {
                    b.Navigation("Accesses");
ApiTools.Database.Migrations/REDEME.MD
@@ -1,7 +1,7 @@
-------------------------------主数据库---------------------------------------
新增迁移文件
dotnet ef migrations add UpdateSmsSetting1009 -s "../ApiTools.Web.Entry" -c DefaultDbContext
dotnet ef migrations add UpdateChannelWallet1119 -s "../ApiTools.Web.Entry" -c DefaultDbContext
删除迁移文件
dotnet ef migrations remove -s "../ApiTools.Web.Entry" -c DefaultDbContext
ApiTools.Web.Entry/Startup.cs
@@ -60,7 +60,7 @@
            {
                options.BuildSqlType = SqlTypes.SqlServer;
                options.JobDetail.LogEnabled = true;
                //options.AddPersistence<DbJobPersistence>();
                options.AddPersistence<DbJobPersistence>();
            });
            services.AddSpecificationDocuments(options =>