qinchaoyue há 4 semanas atrás
pai
commit
9c87beca34
44 ficheiros alterados com 2397 adições e 126 exclusões
  1. 4 4
      DataTransmission/App.config
  2. 3 1
      SnapshotWinFormsApp/App.config
  3. 13 7
      SnapshotWinFormsApp/Application/CommunityInfoApplication.cs
  4. 23 0
      SnapshotWinFormsApp/Application/Dtos/CreateInstanceInDto.cs
  5. 12 0
      SnapshotWinFormsApp/Application/Interfaces/IImportApplication.cs
  6. 67 0
      SnapshotWinFormsApp/Application/Interfaces/ImportApplicationBase.cs
  7. 96 0
      SnapshotWinFormsApp/Application/InviteApplication.cs
  8. 277 0
      SnapshotWinFormsApp/Application/OrderSnapshotApplication.cs
  9. 24 0
      SnapshotWinFormsApp/Application/PractitionerApplication.cs
  10. 24 16
      SnapshotWinFormsApp/Application/SnapshotUserInfoApplication.cs
  11. 19 0
      SnapshotWinFormsApp/Entities/NewHotline/ApiResponse.cs
  12. 114 0
      SnapshotWinFormsApp/Entities/NewHotline/Citizen.cs
  13. 118 0
      SnapshotWinFormsApp/Entities/NewHotline/File.cs
  14. 173 0
      SnapshotWinFormsApp/Entities/NewHotline/Industry.cs
  15. 51 0
      SnapshotWinFormsApp/Entities/NewHotline/InviteCode.cs
  16. 48 0
      SnapshotWinFormsApp/Entities/NewHotline/InviteCodeRecord.cs
  17. 19 0
      SnapshotWinFormsApp/Entities/NewHotline/Kv.cs
  18. 24 0
      SnapshotWinFormsApp/Entities/NewHotline/OldDataId.cs
  19. 395 0
      SnapshotWinFormsApp/Entities/NewHotline/OrderSnapshot.cs
  20. 48 0
      SnapshotWinFormsApp/Entities/NewHotline/Practitioner.cs
  21. 57 0
      SnapshotWinFormsApp/Entities/NewHotline/SystemDicData.cs
  22. 9 6
      SnapshotWinFormsApp/Entities/NewHotline/ThirdAccount.cs
  23. 79 0
      SnapshotWinFormsApp/Entities/NewHotline/User.cs
  24. 4 2
      SnapshotWinFormsApp/Entities/OldHotline/Flow03_PushContent.cs
  25. 98 0
      SnapshotWinFormsApp/Entities/OldHotline/Flow03_SearchEntity.cs
  26. 12 0
      SnapshotWinFormsApp/Entities/OldHotline/OldBaseEntity.cs
  27. 4 2
      SnapshotWinFormsApp/Entities/OldHotline/SSP_AreaEntity.cs
  28. 26 0
      SnapshotWinFormsApp/Entities/OldHotline/SSP_AreaUserEntity.cs
  29. 25 0
      SnapshotWinFormsApp/Entities/OldHotline/SSP_InviteEntity.cs
  30. 22 0
      SnapshotWinFormsApp/Entities/OldHotline/SSP_InviteLogEntity.cs
  31. 4 2
      SnapshotWinFormsApp/Entities/OldHotline/WeChatFollowUserEntity.cs
  32. 7 4
      SnapshotWinFormsApp/Entities/OldHotline/WeChatUserEntity.cs
  33. 55 51
      SnapshotWinFormsApp/MainForm.Designer.cs
  34. 116 16
      SnapshotWinFormsApp/MainForm.cs
  35. 43 2
      SnapshotWinFormsApp/Repository/BaseRepository.cs
  36. 19 0
      SnapshotWinFormsApp/Repository/Enum/EButtonStatusType.cs
  37. 19 0
      SnapshotWinFormsApp/Repository/Enum/ECompliantType.cs
  38. 52 0
      SnapshotWinFormsApp/Repository/Enum/EGuiderSystemReplyType.cs
  39. 28 0
      SnapshotWinFormsApp/Repository/Enum/EIndustryType.cs
  40. 10 2
      SnapshotWinFormsApp/Repository/Interfaces/IRepository.cs
  41. 19 8
      SnapshotWinFormsApp/Repository/Repository.cs
  42. 92 0
      SnapshotWinFormsApp/Tools/FileTools.cs
  43. 27 2
      SnapshotWinFormsApp/Tools/MapsterConfig.cs
  44. 18 1
      SnapshotWinFormsApp/Tools/MyExtensions.cs

+ 4 - 4
DataTransmission/App.config

@@ -7,12 +7,12 @@
     <!--<add key ="SQLServerDB" value="server=172.15.28.10,4666;database=CityHotline_Ver3;uid=CityHotlineUser;pwd=yb12345#@!;"/>
     <add key ="PGSQLDB" value="Server=100.122.1.9;Port=5432;UserId=fwkjyibin;Password=Fwkj2023##!!**;Database=hotline;"/>-->
     <!--自贡-->
-    <!--<add key ="SQLServerDB" value="server=61.157.186.3,4368;database=ZG_CityHotline_Ver3;uid=ZGCityHotlineUser;pwd=fway09!@ZG_15;"/>
-    <add key ="PGSQLDB" value="Server=110.188.24.182;Port=5432;UserId=dev;Password=fengwo11!!;Database=hotline_zg;"/>-->
+    <add key ="SQLServerDB" value="server=61.157.186.3,4368;database=ZG_CityHotline_Ver3;uid=ZGCityHotlineUser;pwd=fway09!@ZG_15;"/>
+    <add key ="PGSQLDB" value="Server=110.188.24.182;Port=5432;UserId=dev;Password=fengwo11!!;Database=hotline_zg;"/>
     <!--泸州-->
-    <add key ="SQLServerDB" value="server=172.20.200.11,4433;database=CityHotline_Ver3;uid=HotlineUser_Ver3;pwd=lzs12345aA!@#;"/>
+    <!--<add key ="SQLServerDB" value="server=172.20.200.11,4433;database=CityHotline_Ver3;uid=HotlineUser_Ver3;pwd=lzs12345aA!@#;"/>-->
     <!--<add key ="PGSQLDB" value="Server=10.4.117.50;Port=5432;UserId=fwkjluzhou;Password=Fwkj2024$$!Tgs*_;Database=hotline;"/>-->
-    <add key ="PGSQLDB" value="Server=110.188.24.182;Port=5432;UserId=dev;Password=fengwo11!!;Database=hotline_lz;"/>
+    <!--<add key ="PGSQLDB" value="Server=110.188.24.182;Port=5432;UserId=dev;Password=fengwo11!!;Database=hotline_lz;"/>-->
     <!--日志-->
     <add key ="LogLevel" value="10"/>
   </appSettings>

+ 3 - 1
SnapshotWinFormsApp/App.config

@@ -2,7 +2,9 @@
 <configuration>
 	<appSettings>
 		<!--日志-->
-		<add key ="LogLevel" value="10"/>
+		<add key ="LogLevel" value="10" />
+		<add key="FileServerUrl" value="http://110.188.24.28:50120" />
+		<add key="ZiGongFile" value="http://171.94.154.9:81" />
 	</appSettings>
 	<connectionStrings>
 		<add providerName="自贡" name ="SQLServerDB" connectionString="server=61.157.186.3,4368;database=ZG_CityHotline_Ver3;uid=ZGCityHotlineUser;pwd=fway09!@ZG_15;"  />

+ 13 - 7
SnapshotWinFormsApp/Application/CommunityInfoApplication.cs

@@ -1,32 +1,37 @@
 using Mapster;
+using SnapshotWinFormsApp.Application.Dtos;
+using SnapshotWinFormsApp.Application.Interfaces;
 using SnapshotWinFormsApp.Entities.NewHotline;
 using SnapshotWinFormsApp.Entities.OldHotline;
 using SnapshotWinFormsApp.Repository;
 using SnapshotWinFormsApp.Repository.Interfaces;
+using SnapshotWinFormsApp.Tools;
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 
 namespace SnapshotWinFormsApp.Application;
 
-public class CommunityInfoApplication
+[Description("导入社区信息")]
+public class CommunityInfoApplication : IImportApplication
 {
     private readonly IBaseRepository<CommunityInfo> _communityInfoRepo;
-    private readonly IRepository<SSP_AreaEntity> _areaRepo;
-    public CommunityInfoApplication(DbSqlServer sqlServerDB)
+    private readonly IRepository<SSP_AreaEntity, int> _areaRepo;
+    public CommunityInfoApplication(CreateInstanceInDto inDto)
     {
-        _communityInfoRepo = new BaseRepository<CommunityInfo>(sqlServerDB, "自贡");
-        _areaRepo = new Repository<SSP_AreaEntity>(sqlServerDB, "自贡");
+        _communityInfoRepo = new BaseRepository<CommunityInfo>(inDto);
+        _areaRepo = new Repository<SSP_AreaEntity, int>(inDto);
     }
 
-    public async Task ImportCommunityInfoAsync(Action<string> log, CancellationToken token)
+    public async Task ImportAsync(Action<string> log, CancellationToken token)
     {
         try
         {
             log($"正在查询旧数据...");
-            var items = await _areaRepo.GetAllAsync();
+            var items = await _areaRepo.GetAllAsync(token);
 
             log($"共查询到{items.Count}条数据");
             for (int i = 0;i < items.Count;i++)
@@ -36,6 +41,7 @@ public class CommunityInfoApplication
                 var has = await _communityInfoRepo.Queryable()
                     .AnyAsync(m => m.UniqueKey == communitInfo.UniqueKey, token);
                 if (has) continue;
+
                 await _communityInfoRepo.InsertAsync(communitInfo, token);
                 log($"{i}/{items.Count} 插入数据: {communitInfo.Id} {communitInfo.Name}");
             }

+ 23 - 0
SnapshotWinFormsApp/Application/Dtos/CreateInstanceInDto.cs

@@ -0,0 +1,23 @@
+using SnapshotWinFormsApp.Repository;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Application.Dtos;
+public class CreateInstanceInDto
+{
+    public CreateInstanceInDto(DbSqlServer dbSqlServer, string key, DateTime startTime, DateTime endTime)
+    { 
+        DbSqlServer = dbSqlServer;
+        Key = key;
+        StartTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 0, 0, 0);
+        EndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, 23, 59, 59);
+    }
+
+    public DbSqlServer DbSqlServer { get; set; }
+    public string Key { get; set; }
+    public DateTime StartTime { get; set; }
+    public DateTime EndTime { get; set; }
+}

+ 12 - 0
SnapshotWinFormsApp/Application/Interfaces/IImportApplication.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Application.Interfaces;
+
+public interface IImportApplication
+{
+    Task ImportAsync(Action<string> log, CancellationToken token);
+}

+ 67 - 0
SnapshotWinFormsApp/Application/Interfaces/ImportApplicationBase.cs

@@ -0,0 +1,67 @@
+using DataTransmission.Enum;
+using Mapster;
+using SnapshotWinFormsApp.Application.Dtos;
+using SnapshotWinFormsApp.Entities.NewHotline;
+using SnapshotWinFormsApp.Entities.OldHotline;
+using SnapshotWinFormsApp.Repository;
+using SnapshotWinFormsApp.Repository.Interfaces;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Application.Interfaces;
+public class ImportApplicationBase<TSource, TEntity, TKey> : IImportApplication
+    where TSource : OldBaseEntity<TKey>, new()
+    where TEntity : Entity, new() 
+{
+    private readonly IRepository<TSource, TKey> _sourceRepo;
+    private readonly IBaseRepository<TEntity> _targetRepo;
+    private readonly IBaseRepository<OldDataId> _oldDataIdRepo;
+    private readonly SqlSugarClient _sugarClient;
+    private readonly CreateInstanceInDto _instance;
+    public ImportApplicationBase(CreateInstanceInDto inDto)
+    {
+        _instance = inDto;
+        _sourceRepo = new Repository<TSource, TKey>(inDto);
+        _targetRepo = new BaseRepository<TEntity>(inDto);
+        _oldDataIdRepo = new BaseRepository<OldDataId>(inDto);
+    }
+
+    public async Task ImportAsync(Action<string> log, CancellationToken token)
+    {
+        log($"正在查询旧数据...");
+        var items = await GetSourceList(_instance).ToListAsync(token);
+        log($"共查询到{items.Count}条数据");
+        var tableName = typeof(TSource).GetCustomAttribute<SugarTable>()?.TableName ?? throw new ArgumentNullException("老数据表名不能为空, 设置[SugarTable()]");
+
+        for (int i = 0;i < items.Count;i++)
+        {
+            await Task.Run(() => MainForm._pauseEvent.WaitHandle.WaitOne(), token);
+            var item = items[i];
+            var has = HasOldData(tableName, item);
+            if (has) continue;
+            var target = item.Adapt<TEntity>();
+
+            await _targetRepo.db.Ado.BeginTranAsync();
+            target.Id = _targetRepo.InsertBulk(target, i + 1 == items.Count);
+            await _oldDataIdRepo.InsertAsync(new OldDataId { OldId = item.Id.ToString(), TableName = tableName, NewId = target.Id }, token);
+            await _targetRepo.db.Ado.CommitTranAsync();
+            log($"{i}/{items.Count} 插入数据: {item.Id} {target.Id}");
+        }
+    }
+
+    public virtual ISugarQueryable<TSource> GetSourceList(CreateInstanceInDto inDto)
+    {
+        return _sourceRepo.Queryable();
+    }
+
+    public virtual bool HasOldData(string tableName, TSource item)
+    {
+        return _oldDataIdRepo.Queryable().Any(m => m.TableName == tableName && item.Id.ToString() == m.OldId);
+    }
+
+}

+ 96 - 0
SnapshotWinFormsApp/Application/InviteApplication.cs

@@ -0,0 +1,96 @@
+using Abp.Collections.Extensions;
+using Hotline.Snapshot;
+using Mapster;
+using SnapshotWinFormsApp.Application.Dtos;
+using SnapshotWinFormsApp.Application.Interfaces;
+using SnapshotWinFormsApp.Entities.NewHotline;
+using SnapshotWinFormsApp.Entities.OldHotline;
+using SnapshotWinFormsApp.Repository;
+using SnapshotWinFormsApp.Repository.Interfaces;
+using SnapshotWinFormsApp.Tools;
+using System.ComponentModel;
+using System.Configuration;
+
+namespace SnapshotWinFormsApp.Application;
+
+[Description("邀请码")]
+public class InviteApplication : IImportApplication
+{
+    private readonly IRepository<SSP_InviteLogEntity, string> _inviteLogRepo;
+    private readonly IRepository<SSP_InviteEntity, int> _inviteRepo;
+    private readonly IBaseRepository<InviteCode> _newInviteCodeRepo;
+    private readonly IBaseRepository<InviteCodeRecord> _newInviteLogRepo;
+    private readonly IBaseRepository<SnapshotUserInfo> _userInfoRepo;
+    private readonly IBaseRepository<ThirdAccount> _thirdAccountRepo;
+    public InviteApplication(CreateInstanceInDto inDto)
+    {
+        _inviteLogRepo = new Repository<SSP_InviteLogEntity, string>(inDto);
+        _inviteRepo = new Repository<SSP_InviteEntity, int>(inDto);
+        _newInviteCodeRepo = new BaseRepository<InviteCode>(inDto);
+        _newInviteLogRepo = new BaseRepository<InviteCodeRecord>(inDto);
+        _userInfoRepo = new BaseRepository<SnapshotUserInfo>(inDto);
+        _thirdAccountRepo = new BaseRepository<ThirdAccount>(inDto);
+    }
+
+    public async Task ImportAsync(Action<string> log, CancellationToken token)
+    {
+        log($"正在查询旧数据...");
+        var items = await _inviteRepo.GetAllAsync(token);
+        log($"共查询到{items.Count}条数据");
+
+        for (int i = 0;i < items.Count;i++)
+        {
+            var inviteCode = items[i].Adapt<InviteCode>();
+            var has = await _newInviteCodeRepo.Queryable().AnyAsync(m => m.OrgName == inviteCode.OrgName, token);
+            if (has) continue;
+            var url = ConfigurationManager.AppSettings["ZiGongFile"] + inviteCode.QRCodeUrl;
+            var fileContent = await new FileTools().GetNetworkFileAsync(url, token);
+            inviteCode.QRCodeUrl = fileContent.Path;
+            await _newInviteCodeRepo.InsertAsync(inviteCode, token);
+            log($"{i + 1}/{items.Count} 插入数据: {inviteCode.Id} {inviteCode.OrgName}");
+        }
+
+        await ImportInivteLogAsync(log, token);
+    }
+
+    private async Task ImportInivteLogAsync(Action<string> log, CancellationToken token)
+    {
+        log($"正在查询旧数据...");
+        var items = await _inviteLogRepo.Queryable()
+            .LeftJoin<SSP_InviteEntity>((log, invite) => log.SSPI_CodeID == invite.SIC_Byte)
+            .LeftJoin<WeChatUserEntity>((log, invite, user) => user.WUR_Openid == log.SSPI_Openid)
+            .Select((log, invite, user) => new InviteCodeRecord
+            {
+                Id = log.Id,
+                Name = user.WUR_WebUserName,
+                OrgName = invite.SIC_BMName,
+                InviteCode = log.SSPI_Code,
+                WXOpenId = log.SSPI_Openid,
+                PhoneNumber = user.WUR_PhoneNum,
+            })
+            .ToListAsync(token);
+        log($"共查询到{items.Count}条数据");
+
+        var invities = await _newInviteCodeRepo.GetAllAsync(token);
+        var thirdAccounts = await _thirdAccountRepo.GetAllAsync(token);
+
+        for (int i = 0;i < items.Count;i++)
+        {
+            var inviteLog = items[i];
+            var has = await _newInviteLogRepo.Queryable().AnyAsync(m => m.Id == inviteLog.Id, token);
+            if (has) continue;
+            inviteLog.OrgId = invities.FirstOrDefault(m => m.OrgName == inviteLog.OrgName)?.Id;
+            await _newInviteLogRepo.InsertAsync(inviteLog, token);
+            log($"{i + 1}/{items.Count} 插入数据: {inviteLog.Id} {inviteLog.OrgName} {inviteLog.Name} {inviteLog.InviteCode}");
+            var userId = thirdAccounts
+                .Where(m => m.OpenId == inviteLog.WXOpenId).Select(m => m.ExternalId).FirstOrDefault();
+            if (userId.IsNullOrEmpty()) continue;
+
+            log($"更新用户邀请码: {userId} {inviteLog.InviteCode}");
+            await _userInfoRepo.Updateable()
+                .SetColumns(m => m.InvitationCode, inviteLog.InviteCode)
+                .Where(m => m.Id == userId)
+                .ExecuteCommandAsync(token);
+        }
+    }
+}

Diff do ficheiro suprimidas por serem muito extensas
+ 277 - 0
SnapshotWinFormsApp/Application/OrderSnapshotApplication.cs


+ 24 - 0
SnapshotWinFormsApp/Application/PractitionerApplication.cs

@@ -0,0 +1,24 @@
+using DataTransmission.Enum;
+using SnapshotWinFormsApp.Application.Dtos;
+using SnapshotWinFormsApp.Application.Interfaces;
+using SnapshotWinFormsApp.Entities.NewHotline;
+using SnapshotWinFormsApp.Entities.OldHotline;
+using SnapshotWinFormsApp.Repository;
+using SnapshotWinFormsApp.Repository.Interfaces;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Application;
+
+[Description("区域从业人员")]
+public class PractitionerApplication : ImportApplicationBase<SSP_AreaUserEntity, Practitioner, string>, IImportApplication
+{
+    public PractitionerApplication(CreateInstanceInDto inDto) : base(inDto)
+    {
+    }
+}

+ 24 - 16
SnapshotWinFormsApp/Application/SnapshotUserInfoApplication.cs

@@ -1,6 +1,8 @@
 using Abp.Extensions;
+using DataTransmission.Enum;
 using Mapster;
 using SnapshotWinFormsApp.Application.Dtos;
+using SnapshotWinFormsApp.Application.Interfaces;
 using SnapshotWinFormsApp.Entities.NewHotline;
 using SnapshotWinFormsApp.Entities.OldHotline;
 using SnapshotWinFormsApp.Repository;
@@ -8,6 +10,7 @@ using SnapshotWinFormsApp.Repository.Enum;
 using SnapshotWinFormsApp.Repository.Interfaces;
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Linq;
 using System.Reflection;
 using System.Text;
@@ -16,25 +19,27 @@ using System.Xml.Linq;
 
 namespace SnapshotWinFormsApp.Application;
 
-public class SnapshotUserInfoApplication
+[Description("导入用户信息")]
+public class SnapshotUserInfoApplication : IImportApplication
 {
     private readonly IBaseRepository<ThirdAccount> _thirdAccountRepo;
-    private readonly IRepository<WeChatUserEntity> _weChatRepo;
-    private readonly IRepository<WeChatFollowUserEntity> _weChatFlowRepo;
-    private readonly IBaseRepository<SnapshotUserInfo> _userRepo;
-    private readonly IRepository<Flow03_PushContent> _pushContentRepo;
+    private readonly IRepository<WeChatUserEntity, int> _weChatRepo;
+    private readonly IRepository<WeChatFollowUserEntity, int> _weChatFlowRepo;
+    private readonly IBaseRepository<Citizen> _userRepo;
+    private readonly IRepository<Flow03_PushContent, int> _pushContentRepo;
 
-    public SnapshotUserInfoApplication(DbSqlServer sqlServerDB)
+    public SnapshotUserInfoApplication(CreateInstanceInDto inDto)
     {
-        _thirdAccountRepo = new BaseRepository<ThirdAccount>(sqlServerDB, "自贡");
-        _weChatRepo = new Repository<WeChatUserEntity>(sqlServerDB, "自贡");
-        _weChatFlowRepo = new Repository<WeChatFollowUserEntity>(sqlServerDB, "自贡");
-        _userRepo = new BaseRepository<SnapshotUserInfo>(sqlServerDB, "自贡");
-        _pushContentRepo = new Repository<Flow03_PushContent>(sqlServerDB, "自贡");
+        _thirdAccountRepo = new BaseRepository<ThirdAccount>(inDto);
+        _weChatRepo = new Repository<WeChatUserEntity, int>(inDto);
+        _weChatFlowRepo = new Repository<WeChatFollowUserEntity, int>(inDto);
+        _userRepo = new BaseRepository<Citizen>(inDto);
+        _pushContentRepo = new Repository<Flow03_PushContent, int>(inDto);
     }
 
-    public async Task ImportGuiderInfoAsync(Action<string> log, CancellationToken token)
+    public async Task ImportAsync(Action<string> log, CancellationToken token)
     {
+        await ImportSnapshotUserInfoAsync(log, token);
         log($"正在查询旧数据...");
         var guiderOldItems = await _pushContentRepo.Queryable()
             .Where(m => m.MemberMobile != null && m.MemberName != null)
@@ -57,12 +62,13 @@ public class SnapshotUserInfoApplication
                 .FirstAsync(token);
             if (userId.IsNullOrEmpty())
             {
-                var userInfo = new SnapshotUserInfo
+                var userInfo = new Citizen
                 {
                     PhoneNumber = item.MemberMobile.Replace("\t", ""),
                     Name = item.MemberName.Replace("\t", ""),
                 };
                 userInfo.CitizenType = EReadPackUserType.Guider;
+                userInfo.IdentityType = EIdentityType.Citizen;
                 userId = await _userRepo.InsertAsync(userInfo, token);
                 log($"{i}/{guiderOldItems.Count} 插入用户信息: {userId}, {userInfo.Name}, {userInfo.PhoneNumber}");
             }
@@ -73,7 +79,7 @@ public class SnapshotUserInfoApplication
     {
         log($"正在查询旧数据...");
         var items = await _weChatRepo.Queryable()
-            .Select(m => new WeChatUserDto(), true)
+            .Where(m => m.WUR_UserType == "ssp")
             .ToListAsync(token);
         log($"共查询到{items.Count}条数据");
         var totalCount = items.Count;
@@ -92,12 +98,14 @@ public class SnapshotUserInfoApplication
                 .FirstAsync(token);
             if (userId.IsNullOrEmpty())
             {
-                var userInfo = item.Adapt<SnapshotUserInfo>();
+                var userInfo = item.Adapt<Citizen>();
+                userInfo.CitizenType = EReadPackUserType.Citizen;
+                userInfo.IdentityType = EIdentityType.Citizen;
                 userId = await _userRepo.InsertAsync(userInfo, token);
                 log($"{index}/{totalCount} 插入用户信息: {userId}, {userInfo.Name}, {userInfo.PhoneNumber}");
             }
             var thirdId = await _thirdAccountRepo.Queryable()
-                .Where(m => m.OpenId == item.openid && m.UnIonId == item.WUR_unionid)
+                .Where(m => m.OpenId == item.WUR_Openid && m.UnIonId == item.WUR_unionid)
                 .Select(m => m.Id)
                 .FirstAsync(token);
             if (thirdId.IsNullOrEmpty())

+ 19 - 0
SnapshotWinFormsApp/Entities/NewHotline/ApiResponse.cs

@@ -0,0 +1,19 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Entities.NewHotline;
+
+public class ApiResponse<T>
+{
+    public T Result { get; set; }
+
+    public int Code { get; set; }
+
+    public string? Message { get; set; }
+
+    public string? Error { get; set; }
+}

+ 114 - 0
SnapshotWinFormsApp/Entities/NewHotline/Citizen.cs

@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using DataTransmission.Enum;
+using SnapshotWinFormsApp.Repository.Enum;
+using SqlSugar;
+
+namespace SnapshotWinFormsApp.Entities.NewHotline
+{
+	[SugarTable("citizen")]
+	[Description("市民")]
+	public class Citizen : FullStateEntity
+	{
+		/// <summary>
+		/// 电话
+		/// </summary>
+		[SugarColumn(ColumnDescription = "电话")]
+		public string PhoneNumber { get; set; }
+
+		/// <summary>
+		/// 姓名
+		/// </summary>
+		[SugarColumn(ColumnDescription = "姓名")]
+		public string? Name { get; set; }
+
+		/// <summary>
+		/// 性别
+		/// </summary>
+		[SugarColumn(ColumnDescription = "性别")]
+		public EGender? Gender { get; set; }
+
+		/// <summary>
+		/// 市民身份
+		/// </summary>
+		[SugarColumn(ColumnDescription = "市民身份")]
+		public EIdentityType? IdentityType { get; set; }
+
+        /// <summary>
+        /// 证件类型
+        /// </summary>
+        [SugarColumn(ColumnDescription = "证件类型")]
+        public string? LicenceType { get; set; }
+
+		/// <summary>
+		/// 证件号码
+		/// </summary>
+		[SugarColumn(ColumnDescription = "证件号码")]
+		public string? LicenceNo { get; set; }
+
+		/// <summary>
+		/// 年龄段
+		/// </summary>
+		[SugarColumn(ColumnDescription = "年龄段")]
+		public string? AgeRange { get; set; }
+
+        /// <summary>
+        /// 联系电话
+        /// </summary>
+        [SugarColumn(ColumnDescription = "联系电话")]
+        public string? Contact { get; set; }
+
+        [SugarColumn(ColumnDescription = "联系电话脱敏")]
+        public string? ContactMask { get; set; }
+
+        /// <summary>
+        /// 市民标签
+        /// </summary>
+        [SugarColumn(ColumnDescription = "市民标签", ColumnDataType = "text")]
+        public string? Label { get; set; }
+
+		/// <summary>
+		/// 更新人
+		/// </summary>
+		[SugarColumn(ColumnDescription = "更新人")]
+		public string? LastModificationName { get; set; }
+
+		/// <summary>
+		/// 首次来电时间
+		/// </summary>
+		[SugarColumn(ColumnDescription = "首次来电时间")]
+		public DateTime? FirstCallTime { get; set; }
+
+        #region 随手拍
+        /// <summary>
+        /// 用户自己填的邀请码
+        /// </summary>
+        [SugarColumn(ColumnDescription = "用户自己填的邀请码")]
+        public string? InvitationCode { get; set; }
+
+        /// <summary>
+        /// 历史已经领取金额总和(单位:元)
+        /// </summary>
+        [SugarColumn(ColumnDescription = "历史已经领取金额总和(单位:元)")]
+        public double? TotalAmount { get; set; }
+
+        /// <summary>
+        /// 用户类型
+        /// 注册时根据手机号码判断是否是 网格员
+        /// </summary>
+        [SugarColumn(ColumnDescription = "用户类型")]
+        public EReadPackUserType? CitizenType { get; set; }
+
+		/// <summary>
+		/// 是否安全卫士
+		/// </summary>
+		[SugarColumn(ColumnDescription = "是否安全卫士")]
+        public bool? IsSecurityMax { get; set; }
+        #endregion
+
+    }
+}

+ 118 - 0
SnapshotWinFormsApp/Entities/NewHotline/File.cs

@@ -0,0 +1,118 @@
+using SqlSugar;
+using System.ComponentModel;
+
+namespace SnapshotWinFormsApp.Entities.NewHotline
+{
+    public class FileJson
+    {
+        public string Id { get; set; }
+
+        public string FileName { get; set; }
+
+        public string FileType { get; set; }
+
+        public string FileId { get; set; }
+
+        /// <summary>
+        /// 录音文件长度(秒)
+        /// </summary>
+        public long Duration { get; set; } = 0;
+
+        public string Path { get; set; }
+    }
+
+    [Description("附件")]
+	public class File : CreationSoftDeleteEntity
+	{
+		/// <summary>
+		/// 附件全称
+		/// </summary>
+		[SugarColumn(ColumnDescription = "附件全称")]
+		public string? FileName { get; set; }
+
+		/// <summary>
+		/// 附件名称
+		/// </summary>
+		[SugarColumn(ColumnDescription = "附件名称")]
+		public string? Name { get; set; }
+
+		/// <summary>
+		/// 附件KEY
+		/// 业务数据关联Id
+		/// </summary>
+		[SugarColumn(ColumnDescription = "附件Key")]
+		public string Key { get; set; }
+
+		/// <summary>
+		/// 附件流程KEY
+		/// </summary>
+		[SugarColumn(ColumnDescription = "附件流程KEY")]
+		public string? FlowKey { get; set; }
+
+		/// <summary>
+		/// 附件类型
+		/// </summary>
+		[SugarColumn(ColumnDescription = "附件类型")]
+		public string? Type { get; set; }
+
+		/// <summary>
+		/// 部门ID
+		/// </summary>
+		[SugarColumn(ColumnDescription = "部门ID")]
+		public string? OrgId { get; set; }
+
+		/// <summary>
+		/// 部门名称
+		/// </summary>
+		[SugarColumn(ColumnDescription = "部门名称")]
+		public string? OrgName { get; set; }
+
+		/// <summary>
+		/// 上传人Id
+		/// </summary>
+		[SugarColumn(ColumnDescription = "上传人Id")]
+		public string? UserId { get; set; }
+
+		/// <summary>
+		/// 上传人名称
+		/// </summary>
+		[SugarColumn(ColumnDescription = "上传人名称")]
+		public string? UserName { get; set; }
+
+		/// <summary>
+		/// 是否公开
+		/// </summary>
+		[SugarColumn(ColumnDescription = "是否公开   0 公开  1 不公开")]
+		public int? Publicity { get; set; }
+
+		/// <summary>
+		/// 附件分类
+		/// </summary>
+		[SugarColumn(ColumnDescription = "附件分类")]
+		public string? Classify { get; set; }
+
+		/// <summary>
+		/// 附件
+		/// </summary>
+		[SugarColumn(ColumnDescription = "附件")]
+		public string? Additions { get; set; }
+
+		/// <summary>
+		/// 附件路径
+		/// </summary>
+		[SugarColumn(ColumnDescription = "附件路径")]
+		public string? Path { get; set; }
+
+		/// <summary>
+		/// 完整附件路径
+		/// </summary>
+		[SugarColumn(ColumnDescription = "完整附件路径", ColumnDataType = "varchar(500)")]
+		public string? AllPath { get; set; }
+
+		/// <summary>
+		/// 时长(秒)
+		/// </summary>
+		[SugarColumn(ColumnDescription ="文件时长(秒)")]
+		public long? Duration { get; set; }
+	}
+}

+ 173 - 0
SnapshotWinFormsApp/Entities/NewHotline/Industry.cs

@@ -0,0 +1,173 @@
+using SnapshotWinFormsApp.Repository.Enum;
+using SqlSugar;
+using System.ComponentModel;
+
+namespace SnapshotWinFormsApp.Entities.NewHotline;
+
+/// <summary>
+/// 行业
+/// </summary>
+[SugarTable("industry")]
+[Description("行业")]
+public class Industry : CreationSoftDeleteEntity
+{
+    /// <summary>
+    /// 行业名称
+    /// </summary>
+    [SugarColumn(ColumnDescription = "行业名称")]
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 标题追加信息
+    /// </summary>
+    [SugarColumn(ColumnDescription = "标题追加信息")]
+    public string? TitleSuffix { get; set; }
+
+    /// <summary>
+    /// 审批部门Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "审批部门Id")]
+    public string? ApproveOrgId { get; set; }
+
+    /// <summary>
+    /// 审批部门名字
+    /// </summary>
+    [SugarColumn(ColumnDescription = "审批部门名字")]
+    public string? ApproveOrgName { get; set; }
+
+    /// <summary>
+    /// 受理类型
+    /// </summary>
+    [SugarColumn(ColumnDescription = "受理类型")]
+    public string? AcceptType { get; set; }
+
+    /// <summary>
+    /// 受理类型代码
+    /// </summary>
+    [SugarColumn(ColumnDescription = "受理类型代码")]
+    public string? AcceptTypeCode { get; set; }
+
+    /// <summary>
+    /// 市民发放红包金额(单位:元)
+    /// </summary>
+    [SugarColumn(ColumnDescription = "市民发放红包金额(单位:元)")]
+    public double CitizenReadPackAmount { get; set; }
+
+    /// <summary>
+    /// 网络员发放红包金额(单位:元)
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网络员发放红包金额(单位:元)")]
+    public double GuiderReadPackAmount { get; set; }
+
+    /// <summary>
+    /// 是否启用
+    /// </summary>
+    [SugarColumn(ColumnDescription = "是否启用")]
+    public bool IsEnable { get; set; }
+
+    /// <summary>
+    /// App是否启用
+    /// </summary>
+    [SugarColumn(ColumnDescription = "App是否启用")]
+    public bool IsAppEnable { get; set; }
+
+    /// <summary>
+    /// 帮助引导用语
+    /// </summary>
+    [SugarColumn(ColumnDescription = "帮助引导用语")]
+    public string? TxtHelpRemarks { get; set; }
+
+    /// <summary>
+    /// 宫格说明文本
+    /// </summary>
+    [SugarColumn(ColumnDescription = "宫格说明文本")]
+    public string? TxtRemarks { get; set; }
+
+    /// <summary>
+    /// 关怀说明
+    /// </summary>
+    [SugarColumn(ColumnDescription = "关怀说明")]
+    public string? TxtCareRemarks { get; set; }
+
+    /// <summary>
+    /// 排序
+    /// </summary>
+    [SugarColumn(ColumnDescription = "排序")]
+    public int DisplayOrder { get; set; }
+
+    /// <summary>
+    /// 阶段性回复间隔时间(小时)
+    /// </summary>
+    [SugarColumn(ColumnDescription = "阶段性回复间隔时间(小时)")]
+    public int IntervalTime { get; set; }
+
+    /// <summary>
+    /// 页面Url
+    /// </summary>
+    [SugarColumn(ColumnDescription = "页面Url")]
+    public string? PageUrl { get; set; }
+
+    /// <summary>
+    /// 关怀页面Url
+    /// </summary>
+    [SugarColumn(ColumnDescription = "关怀页面Url")]
+    public string? PageCareUrl { get; set; }
+
+    /// <summary>
+    /// 关联宣传学习
+    /// 从字典中取"公告类型"
+    /// </summary>
+    [SugarColumn(ColumnDescription = "关联宣传学习")]
+    public string? BulletinTypePublicityId { get; set; }
+
+    /// <summary>
+    /// 关联宣传学习
+    /// 从字典中取"公告类型"
+    /// </summary>
+    [SugarColumn(ColumnDescription = "关联宣传学习")]
+    public string? BulletinTypePublicityName { get; set; }
+
+    /// <summary>
+    /// 关联操作指引
+    /// 从字典中取"随手拍公告类型"
+    /// </summary>
+    [SugarColumn(ColumnDescription = "关联操作指引")]
+    public string? BulletinTypeGuideId { get; set; }
+
+    /// <summary>
+    /// 关联操作指引
+    /// 从字典中取"随手拍公告类型"
+    /// </summary>
+    [SugarColumn(ColumnDescription = "关联操作指引")]
+    public string? BulletinTypeGuideName { get; set; }
+
+    /// <summary>
+    /// 背景图片 url
+    /// </summary>
+    [SugarColumn(ColumnDescription = "背景图片 url")]
+    public string? BackgroundImgUrl { get; set; }
+
+    /// <summary>
+    /// Banner 图片 url
+    /// </summary>
+    [SugarColumn(ColumnDescription = "Banner 图片 url")]
+    public string? BannerImgUrl { get; set; }
+
+    /// <summary>
+    /// 宫格图
+    /// </summary>
+    [SugarColumn(ColumnDescription = "宫格图")]
+    public string? CellImgUrl { get; set; }
+
+    /// <summary>
+    /// 关怀宫格图
+    /// </summary>
+    [SugarColumn(ColumnDescription = "关怀宫格图")]
+    public string? CareCellImgUrl { get; set; }
+
+    /// <summary>
+    /// 行业类型
+    /// </summary>
+    [SugarColumn(ColumnDescription = "行业类型")]
+    public EIndustryType IndustryType { get; set; }
+}

+ 51 - 0
SnapshotWinFormsApp/Entities/NewHotline/InviteCode.cs

@@ -0,0 +1,51 @@
+using SnapshotWinFormsApp.Entities.NewHotline;
+using SqlSugar;
+using System.ComponentModel;
+
+namespace Hotline.Snapshot;
+
+/// <summary>
+/// 邀请码
+/// </summary>
+[SugarTable("invite_code")]
+[Description("邀请码")]
+public class InviteCode : CreationSoftDeleteEntity
+{
+    /// <summary>
+    /// 邀请码开始
+    /// 邀请码开始 -> 结束 范围内的邀请码都有效
+    /// </summary>
+    [SugarColumn(ColumnDescription = "邀请码开始")]
+    public int BeginCode { get; set; }
+
+    /// <summary>
+    /// 邀请码结束
+    /// 邀请码开始 -> 结束 范围内的邀请码都有效
+    /// </summary>
+    [SugarColumn(ColumnDescription = "邀请码结束")]
+    public int EndCode { get; set; }
+
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    [SugarColumn(ColumnDescription = "部门名称")]
+    public string OrgName { get; set; }
+
+    /// <summary>
+    /// 上级部门ID
+    /// </summary>
+    [SugarColumn(ColumnDescription = "上级部门ID")]
+    public string? ParentOrgId { get; set; }
+
+    /// <summary>
+    /// 邀请码Url
+    /// </summary>
+    [SugarColumn(ColumnDescription = "邀请码Url")]
+    public string? QRCodeUrl { get; set; }
+
+    /// <summary>
+    /// 上传附件Id
+    /// </summary>
+    [SugarColumn(ColumnDescription ="上传附件Id")]
+    public string? Additions { get; set; }
+}

+ 48 - 0
SnapshotWinFormsApp/Entities/NewHotline/InviteCodeRecord.cs

@@ -0,0 +1,48 @@
+using SqlSugar;
+using System.ComponentModel;
+
+namespace SnapshotWinFormsApp.Entities.NewHotline;
+
+/// <summary>
+/// 邀请记录
+/// </summary>
+[SugarTable("invite_code_record")]
+[Description("邀请记录")]
+public class InviteCodeRecord : CreationSoftDeleteEntity
+{
+    /// <summary>
+    /// 部门Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "部门Id")]
+    public string OrgId { get; set; }
+
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    [SugarColumn(ColumnDescription = "部门名称")]
+    public string OrgName { get; set; }
+
+    /// <summary>
+    /// 邀请码
+    /// </summary>
+    [SugarColumn(ColumnDescription = "邀请码")]
+    public string InviteCode { get; set; }
+
+    /// <summary>
+    /// 微信OpenId
+    /// </summary>
+    [SugarColumn(ColumnDescription = "微信OpenId")]
+    public string WXOpenId { get; set; }
+
+    /// <summary>
+    /// 电话
+    /// </summary>
+    [SugarColumn(ColumnDescription = "电话")]
+    public string PhoneNumber { get; set; }
+
+    /// <summary>
+    /// 姓名
+    /// </summary>
+    [SugarColumn(ColumnDescription = "姓名")]
+    public string? Name { get; set; }
+}

+ 19 - 0
SnapshotWinFormsApp/Entities/NewHotline/Kv.cs

@@ -0,0 +1,19 @@
+using System.Security.Cryptography.X509Certificates;
+
+namespace SnapshotWinFormsApp.Entities.NewHotline;
+
+public class Kv
+{
+    public Kv()
+    {
+    }
+
+    public Kv(string key, string value)
+    {
+        Key = key;
+        Value = value;
+    }
+
+    public string Key { get; set; }
+    public string Value { get; set; }
+}

+ 24 - 0
SnapshotWinFormsApp/Entities/NewHotline/OldDataId.cs

@@ -0,0 +1,24 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO.Pipes;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Entities.NewHotline;
+
+[Description("老数据Id")]
+[SugarTable("old_data_id")]
+public class OldDataId : SoftDeleteEntity
+{
+    [Description("旧数据Id")]
+    public string OldId { get; set; }
+
+    [Description("表明")]
+    public string TableName { get; set; }
+
+    [Description("新数据Id")]
+    public string NewId { get; set; }
+}

+ 395 - 0
SnapshotWinFormsApp/Entities/NewHotline/OrderSnapshot.cs

@@ -0,0 +1,395 @@
+using SnapshotWinFormsApp.Repository.Enum;
+using SqlSugar;
+using System.ComponentModel;
+
+namespace SnapshotWinFormsApp.Entities.NewHotline;
+
+/// <summary>
+/// 工单表扩展
+/// Id 和 Order.Id 相同
+/// </summary>
+[SugarTable("order_snapshot")]
+[Description("工单表扩展")]
+public class OrderSnapshot : CreationSoftDeleteEntity
+{
+    /// <summary>
+    /// 行业Id
+    /// <inheritdoc cref="Industry"/> 表的Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "行业Id")]
+    public string IndustryId { get; set; }
+
+    /// <summary>
+    /// 行业名称
+    /// <inheritdoc cref="Industry"/> 表的Name
+    /// </summary>
+    [SugarColumn(ColumnDescription = "行业名称")]
+    public string IndustryName { get; set; }
+
+    /// <summary>
+    /// 社区Id
+    /// <inheritdoc cref="CommunityInfo"/> 表的Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "社区Id")]
+    public string? CommunityId { get; set; }
+
+    /// <summary>
+    /// 社区名字
+    /// </summary>
+    [SugarColumn(ColumnDescription = "社区名字")]
+    public string? CommunityName { get; set; }
+
+    /// <summary>
+    /// 社区名字
+    /// </summary>
+    [SugarColumn(ColumnDescription = "社区名字")]
+    public string? CommunityFullName { get; set; }
+
+    /// <summary>
+    /// 作业类型
+    /// </summary>
+    [SugarColumn(ColumnDescription = "作业类型")]
+    public int? JobType { get; set; }
+
+    /// <summary>
+    /// 作业类型
+    /// </summary>
+    [SugarColumn(ColumnDescription ="作业类型")]
+    public string? JobTypeName { get; set; }
+
+    /// <summary>
+    /// 经营单位类别
+    /// </summary>
+    [SugarColumn(ColumnDescription = "经营单位类别")]
+    public string? BusinessUnitType { get; set; }
+
+    /// <summary>
+    /// 作业场所
+    /// </summary>
+    [SugarColumn(ColumnDescription = "作业场所")]
+    public string? Workplace { get; set; }
+
+    /// <summary>
+    /// 场所名称(多个场所使用 - 连接)
+    /// </summary>
+    [SugarColumn(ColumnDescription = "场所名称")]
+    public string? WorkplaceName { get; set; }
+
+    /// <summary>
+    /// 作业区域
+    /// </summary>
+    [SugarColumn(ColumnDescription = "作业区域")]
+    public string? WorkArea { get; set; }
+
+    /// <summary>
+    /// 作业区域Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "作业区域Id")]
+    public string? WorkAreaId { get; set; }
+
+    /// <summary>
+    /// 作业时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "作业时间")]
+    public DateTime? StartWorkTime { get; set; }
+
+    /// <summary>
+    /// 作业结束时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "作业时间")]
+    public DateTime? EndWorkTime { get; set; }
+
+    /// <summary>
+    /// 是否重点
+    /// </summary>
+    [SugarColumn(ColumnDescription = "是否重点")]
+    public bool? IsEmphasis { get; set; }
+
+    #region 标记工单是否安全生产字段
+
+    /// <summary>
+    /// 部门标记是否安全生产
+    /// </summary>
+    [SugarColumn(ColumnDescription = "部门标记是否安全生产")]
+    public bool? IsSafetyDepartment { get; set; }
+
+    /// <summary>
+    /// 标记人
+    /// </summary>
+    [SugarColumn(ColumnDescription = "标记人")]
+    public string? SignUserId { get; set; }
+
+    /// <summary>
+    /// 标记人
+    /// </summary>
+    [SugarColumn(ColumnDescription = "标记人")]
+    public string? SignUserName { get; set; }
+
+    /// <summary>
+    /// 标记时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "标记时间")]
+    public DateTime? SignTime { get; set; }
+
+    /// <summary>
+    /// 标记备注
+    /// </summary>
+    [SugarColumn(ColumnDescription = "标记备注")]
+    public string? SignRemark { get; set; }
+    #endregion
+
+    /// <summary>
+    /// 部门是否存在安全隐患
+    /// </summary>
+    [SugarColumn(ColumnDescription = "部门是否存在安全隐患")]
+    public bool? IsDangerDepartment { get; set; }
+
+    /// <summary>
+    /// 部门是否属实
+    /// </summary>
+    [SugarColumn(ColumnDescription = "部门是否属实")]
+    public bool? IsTruthDepartment { get; set; }
+
+    /// <summary>
+    /// 部门是否整改
+    /// </summary>
+    [SugarColumn(ColumnDescription = "部门是否整改")]
+    public bool? IsRectifyDepartment { get; set; }
+
+    /// <summary>
+    /// 线索分类Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "线索分类")]
+    public string? IndustryCase { get; set; }
+
+    /// <summary>
+    /// 小程序公开
+    /// </summary>
+    [SugarColumn(ColumnDescription = "小程序公开")]
+    public bool? IsAppOpened { get; set; }
+
+    /// <summary>
+    /// 合规类型
+    /// </summary>
+    [SugarColumn(ColumnDescription = "合规类型")]
+    public ECompliantType? CompliantType { get; set; }
+
+    /// <summary>
+    /// 发布工单时标记的工单标签
+    /// </summary>
+    [SugarColumn(ColumnDescription = "工单标签", ColumnDataType = "json", IsJson = true, IsNullable = true)]
+    public IList<Kv>? Labels { get; set; }
+
+    /// <summary>
+    /// 发布工单时标记的工单标签(多个使用 | 分隔)
+    /// </summary>
+    [SugarColumn(ColumnDescription = "工单标签")]
+    public string? LabelName { get; set; }
+
+    /// <summary>
+    /// 标签用户
+    /// </summary>
+    [SugarColumn(ColumnDescription = "标签用户")]
+    public string? LabelUserName { get; set; }
+
+    /// <summary>
+    /// 标签用户Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "标签用户Id")]
+    public string? LabelUserId { get; set; }
+
+    /// <summary>
+    /// 标签时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "标签时间")]
+    public DateTime? LabelTime { get; set; }
+
+    /// <summary>
+    /// 工单办理:
+    /// 是否申请追加奖励
+    /// </summary>
+    [SugarColumn(ColumnDescription = "是否申请追加奖励")]
+    public bool? IsAward { get; set; }
+
+    /// <summary>
+    /// 追加奖励人开户银行
+    /// </summary>
+    [SugarColumn(ColumnDescription = "追加奖励人开户银行")]
+    public string? AwardOpenBank { get; set; }
+
+    /// <summary>
+    /// 追加奖励人姓名
+    /// </summary>
+    [SugarColumn(ColumnDescription = "追加奖励人姓名")]
+    public string? AwardName { get; set; }
+
+    /// <summary>
+    /// 追加奖励人银行卡号
+    /// </summary>
+    [SugarColumn(ColumnDescription = "追加奖励人银行卡号")]
+    public string? AwardBankCardNo { get; set; }
+
+    /// <summary>
+    /// 追加奖励金额(元)
+    /// </summary>
+    [SugarColumn(ColumnDescription = "追加奖励金额(元)")]
+    public double? AwardAmount { get; set; }
+
+    /// <summary>
+    /// 补充奖励类型
+    /// </summary>
+    [SugarColumn(ColumnDescription = "补充奖励类型")]
+    public string? ReplenishTypeId { get; set; }
+
+    /// <summary>
+    /// 补充奖励类型
+    /// </summary>
+    [SugarColumn(ColumnDescription = "补充奖励类型")]
+    public string? ReplenishTypeName { get; set; }
+
+    /// <summary>
+    /// 核实方式
+    /// </summary>
+    [SugarColumn(ColumnDescription = "核实方式")]
+    public string? VerifyType { get; set; }
+
+    /// <summary>
+    /// 是否按清单检查
+    /// </summary>
+    [SugarColumn(ColumnDescription = "是否按清单检查")]
+    public bool? IsCheckList { get; set; }
+
+    #region 网格员回复
+
+    /// <summary>
+    /// 网格员系统交互日志
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网格员系统交互日志")]
+    public string? GuiderAccLog { get; set; }
+
+    /// <summary>
+    /// 网格员回复截止日期
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网格员回复截止日期")]
+    public DateTime? DeadLine { get; set; }
+
+    /// <summary>
+    /// 网格员是否办理
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网格员是否办理")]
+    public bool? IsDeal { get; set; }
+
+    /// <summary>
+    /// 网格E通编号
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网格E通编号")]
+    public string? NetworkENumber { get; set; }
+
+    /// <summary>
+    /// 网格员是否属实
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网格员是否属实")]
+    public bool? IsTruth { get; set; }
+
+    /// <summary>
+    /// 是否重复
+    /// </summary>
+    [SugarColumn(ColumnDescription = "是否重复")]
+    public bool? IsRepetition { get; set; }
+
+    /// <summary>
+    /// 是否隐患
+    /// </summary>
+    [SugarColumn(ColumnDescription = "是否隐患")]
+    public bool? IsDanger { get; set; }
+
+    /// <summary>
+    /// 网格员回复内容
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网格员回复内容", Length = 2048)]
+    public string? NetworkRemark { get; set; }
+
+    /// <summary>
+    /// 网格员办理时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网格员办理时间")]
+    public DateTime? ReplyDate { get; set; }
+
+    /// <summary>
+    /// 网格员姓名
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网格员姓名")]
+    public string? MemberName { get; set; }
+
+    /// <summary>
+    /// 网格员电话
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网格员电话")]
+    public string? MemberMobile { get; set; }
+
+    /// <summary>
+    /// 办理人账号
+    /// </summary>
+    [SugarColumn(ColumnDescription = "办理人账号")]
+    public string? ReplyUserName { get; set; }
+
+    /// <summary>
+    /// 办理部门
+    /// </summary>
+    [SugarColumn(ColumnDescription = "办理部门")]
+    public string? ReplyBMName { get; set; }
+
+    /// <summary>
+    /// 办理状态 1,7:流转 2:办结 3:退回 4:网格员签收 5:消息推送 6: 超时自动退单
+    /// </summary>
+    [SugarColumn(ColumnDescription ="网格员办理状态")]
+    public int? ReplyResultType { get; set; }
+
+    #endregion
+
+    /// <summary>
+    /// 购气单位/个人名称
+    /// </summary>
+    [SugarColumn(ColumnDescription = "购气单位/个人名称")]
+    public string? CompanyName { get; set; }
+
+    /// <summary>
+    /// 发送网格员系统时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "发送网格员系统时间")]
+    public DateTime? SendGuidSystemTime { get; set; }
+
+    /// <summary>
+    /// 网格员系统回调时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网格员系统回调时间")]
+    public DateTime? GuidSystemCallBackTime { get; set; }
+
+    /// <summary>
+    /// 网格员系统是否回调
+    /// </summary>
+    [SugarColumn(ColumnDescription = "网格员系统是否回调", DefaultValue = "f")]
+    public bool IsGuidSystemCallBack { get; set; }
+
+    #region 重办信息
+    /// <summary>
+    /// 重办原因Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "重办原因Id")]
+    public string? SpecialReasonId { get; set; }
+
+    /// <summary>
+    /// 重办原因
+    /// </summary>
+    [SugarColumn(ColumnDescription = "重办原因")]
+    public string? SpecialReasonName { get; set; }
+    #endregion
+
+    /// <summary>
+    /// 扩展字段
+    /// 如果别的系统希望通过界面收集某个字段, 然后我们系统不需要使用, 就可以放这里.
+    /// 第三方系统在获取我们系统工单时直接把这个字段数据返回即可
+    /// </summary>
+    [SugarColumn(ColumnDescription = "12345不使用的扩展字段,第三方系统使用")]
+    public string? Attach { get; set; }
+}

+ 48 - 0
SnapshotWinFormsApp/Entities/NewHotline/Practitioner.cs

@@ -0,0 +1,48 @@
+using DataTransmission.Enum;
+using SqlSugar;
+using System.ComponentModel;
+
+namespace SnapshotWinFormsApp.Entities.NewHotline;
+
+/// <summary>
+/// 区域从业人员
+/// </summary>
+[SugarTable("practitioner")]
+[Description("区域从业人员")]
+public class Practitioner : FullStateEntity
+{
+    /// <summary>
+    /// 名字
+    /// </summary>
+    [SugarColumn(ColumnDescription = "姓名")]
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 区域Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "区域Id")]
+    public string SystemAreaId { get; set; }
+
+    /// <summary>
+    /// 区域名称
+    /// </summary>
+    [SugarColumn(ColumnDescription = "区域名称")]
+    public string SystemAreaName { get; set; }
+
+    /// <summary>
+    /// 详细街道
+    /// </summary>
+    [SugarColumn(ColumnDescription = "街道")]
+    public string Street { get; set; }
+
+    /// <summary>
+    /// 电话
+    /// </summary>
+    [SugarColumn(ColumnDescription = "电话")]
+    public string PhoneNumber { get; set; }
+
+    /// <summary>
+    /// 性别
+    /// </summary>
+    public EGender Gender { get; set; }
+}

+ 57 - 0
SnapshotWinFormsApp/Entities/NewHotline/SystemDicData.cs

@@ -0,0 +1,57 @@
+using SqlSugar;
+using System.ComponentModel;
+
+namespace SnapshotWinFormsApp.Entities.NewHotline
+{
+    [SugarTable("system_dic_data")]
+    [Description("字典表")]
+    public class SystemDicData : FullStateEntity
+	{
+        /// <summary>
+        /// 字典类型Id
+        /// </summary>
+        public string DicTypeId { get; set; }
+
+        /// <summary>
+        /// 字典类型Code
+        /// </summary>
+        public string DicTypeCode { get; set; }
+
+        /// <summary>
+        /// 字典名称
+        /// </summary>
+        public string DicDataName { get; set; }
+
+        /// <summary>
+        /// 字典值
+        /// </summary>
+        public string DicDataValue { get; set; }
+
+        /// <summary>
+        /// 排序
+        /// </summary>
+        [SugarColumn(DefaultValue = "0")]
+        public int Sort { get; set; }
+
+        /// <summary>
+        /// 是否显示
+        /// </summary>
+        [SugarColumn(DefaultValue = "t")]
+		public bool IsShow { get; set; }
+
+		/// <summary>
+		/// 上级ID
+		/// </summary>
+		[SugarColumn(IsNullable = true)]
+        public string? ParentId { get; set; }
+
+        [SugarColumn(IsIgnore = true)]
+        public List<SystemDicData> Children { get; set; }
+
+		/// <summary>
+		/// 附加数据
+		///</summary>
+		[SugarColumn(ColumnDataType = "json", IsJson = true)]
+		public string? Attach { get; set; }        
+    }
+}

+ 9 - 6
SnapshotWinFormsApp/Entities/NewHotline/ThirdAccount.cs

@@ -14,52 +14,55 @@ public class ThirdAccount : CreationSoftDeleteEntity
     /// <summary>
     /// 外部业务唯一标识
     /// </summary>
+    [SugarColumn(ColumnDescription = "外部业务唯一标识")]
     public string? ExternalId { get; set; }
 
     /// <summary>
     /// 电话
     /// </summary>
+    [SugarColumn(ColumnDescription = "电话")]
     public string? PhoneNumber { get; set; }
 
     /// <summary>
     /// 第三方平台的Id
     /// 例如: 微信的OpenId
     /// </summary>
+    [SugarColumn(ColumnDescription = "第三方平台的Id")]
     public string OpenId { get; set; }
 
     /// <summary>
     /// 第三方平台的SessionKey
     /// 例如: 微信SessionKey
     /// </summary>
+    [SugarColumn(ColumnDescription = "第三方平台的SessionKey")]
     public string? SessionKey { get; set; }
 
     /// <summary>
     /// 账号类型
     /// </summary>
-    public EThirdType AccountType { get; set; }
+    public EThirdType AccountType { get; set; } = EThirdType.WeChat;
 
     /// <summary>
     /// 用户头像Url
     /// </summary>
+    [SugarColumn(ColumnDescription = "用户头像Url")]
     public string? HeadImgUrl { get; set; }
 
     /// <summary>
     /// 用户昵称
     /// </summary>
+    [SugarColumn(ColumnDescription = "用户昵称")]
     public string? UserName { get; set; }
 
     /// <summary>
     /// 用户在开放平台的唯一标识符。本字段在满足一定条件的情况下才返回。具体参看:https://mp.weixin.qq.com/debug/wxadoc/dev/api/uinionID.html
     /// </summary>
+    [SugarColumn(ColumnDescription = "用户在开放平台的唯一标识符")]
     public string? UnIonId { get; set; }
 
     /// <summary>
     /// 应用类型
     /// </summary>
+    [SugarColumn(ColumnDescription = "应用类型", DefaultValue = "1")]
     public EAppType AppType { get; set; } = EAppType.Snapshot;
-
-    /// <summary>
-    /// 创建时间
-    /// </summary>
-    public DateTime CreationTime { get; set; }
 }

+ 79 - 0
SnapshotWinFormsApp/Entities/NewHotline/User.cs

@@ -0,0 +1,79 @@
+using System.ComponentModel;
+using DataTransmission.Enum;
+using SqlSugar;
+
+namespace SnapshotWinFormsApp.Entities.NewHotline
+{
+    /// <summary>
+    /// 用户
+    /// </summary>
+    [SugarTable("user")]
+    [Description("用户")]
+    public class User : CreationSoftDeleteEntity
+    {
+        /// <summary>
+        /// 手机号(冗余)
+        /// </summary>
+        public string? PhoneNo { get; set; }
+
+        /// <summary>
+        /// 座机号码
+        /// </summary>
+        [SugarColumn(ColumnDescription = "座机号码", ColumnDataType = "varchar(50)")]
+        public string? LandlineNumber { get; set; }
+
+        /// <summary>
+        /// 展示名称(Identity.DisplayName)
+        /// </summary>
+        public string Name { get; set; }
+
+        public EGender Gender { get; set; }
+
+        /// <summary>
+        /// 工号
+        /// </summary>
+        public string? StaffNo { get; set; }
+
+        /// <summary>
+        /// 部门Id
+        /// </summary>
+        public string? OrgId { get; set; }
+
+        /// <summary>
+        /// 部门全称
+        /// </summary>
+        public string? FullOrgName { get; set; }
+
+        /// <summary>
+        /// 默认分机号
+        /// </summary>
+        public string? DefaultTelNo { get; set; }
+
+        /// <summary>
+        /// 默认分机组(技能组)
+        /// </summary>
+        public string? DefaultTelGroup { get; set; }
+
+        /// <summary>
+        /// 用户类型
+        /// </summary>
+        public EUserType UserType { get; set; }
+
+        /// <summary>
+        /// 旧系统用户id
+        /// </summary>
+        public int? OldUserId { get; set; }
+    }
+}
+
+public enum EUserType
+{
+    [Description("普通")]
+    Normal = 0,
+
+    /// <summary>
+    /// 坐席(统计需要)
+    /// </summary>
+    [Description("坐席")]
+    Seat = 1,
+}

+ 4 - 2
SnapshotWinFormsApp/Entities/OldHotline/Flow03_PushContent.cs

@@ -8,9 +8,11 @@ using System.Threading.Tasks;
 namespace SnapshotWinFormsApp.Entities.OldHotline;
 
 [SugarTable("ZG_CityHotline_Ver3.dbo.Flow03_PushContent")]
-public class Flow03_PushContent
+public class Flow03_PushContent : OldBaseEntity<int>
 {
-    public int FPC_ID { get; set; }
+    [SugarColumn(ColumnName = "FPC_ID")]
+    public override int Id { get => base.Id; set => base.Id = value; }
+    //public int FPC_ID { get; set; }
     public int FPC_FlowID { get; set; }
     public string? FPC_Code { get; set; }
     public string? FPC_Content { get; set; }

+ 98 - 0
SnapshotWinFormsApp/Entities/OldHotline/Flow03_SearchEntity.cs

@@ -0,0 +1,98 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Entities.OldHotline;
+
+[SugarTable("ZG_CityHotline_Ver3.dbo.Flow03_Search")]
+public class Flow03_SearchEntity : OldBaseEntity<int>
+{
+    [SugarColumn(ColumnName = "FSH_FlowID")]
+    public override int Id { get; set; }
+    //public int FSH_FlowID { get; set; }
+    public string FSH_ItemName { get; set; }
+    public string FSH_Code { get; set; }
+    public string FSH_FromName { get; set; }
+    public string FSH_AreaName { get; set; }
+    public string FSH_PurTypeName { get; set; }
+    public string FSH_ConTypeName { get; set; }
+    public string FSH_ServerName { get; set; }
+    public string FSH_Title { get; set; }
+    public string FSH_UserName { get; set; }
+    public string FSH_BMName { get; set; }
+    public DateTime FSH_AddDate { get; set; }
+    public DateTime? FSH_TTime { get; set; }
+    public DateTime? FSH_FiftyTTime { get; set; }
+    public DateTime? FSH_EightyTTime { get; set; }
+    public string FSH_AcceptUserName { get; set; }
+    public string FSH_AcceptName { get; set; }
+    public DateTime? FSH_AcceptDate { get; set; }
+    public DateTime? FSH_DisposeDate { get; set; }
+    public string FSH_LinkName { get; set; }
+    public string FSH_LinkTel { get; set; }
+    public string FSH_FromTel { get; set; }
+    public string FSH_StateFlagName { get; set; }
+    public int? FSH_PunishNum { get; set; }
+    public string FSH_Identify { get; set; }
+    public DateTime? FSH_IdtDate { get; set; }
+    public int? FSH_MeetingCount { get; set; }
+    public int? FSH_LeaderCount { get; set; }
+    public bool? FSH_SubFlag { get; set; }
+    public bool? FSH_InvFlag { get; set; }
+    public bool? FSH_StopFlag { get; set; }
+    public string FSH_EndUserName { get; set; }
+    public int? FSH_EndUserID { get; set; }
+    public int? FSH_EndBMID { get; set; }
+    public string FSH_ShowTitle { get; set; }
+    public string FSH_HotlineNum { get; set; }
+    public bool? FSH_Urgent { get; set; }
+    public int? FSH_AcceptBMID { get; set; }
+    public string FSH_ConTypeNameFull { get; set; }
+    public string FSH_Keyword { get; set; }
+    public int? FSH_RunID { get; set; }
+    public int? FSH_FromID { get; set; }
+    public int? FSH_AreaID { get; set; }
+    public int? FSH_PurTypeID { get; set; }
+    public int? FSH_ConTypeID { get; set; }
+    public int? FSH_ServerID { get; set; }
+    public int? FSH_CreateUserID { get; set; }
+    public int? FSH_CreateBMID { get; set; }
+    public int? FSH_SessionID { get; set; }
+    public DateTime? FSH_TempTTime { get; set; }
+    public string FSH_OrderType { get; set; }
+    public string FSH_PersonnelType { get; set; }
+    public string FSH_ProCode { get; set; }
+    public string FSH_Punish { get; set; }
+    public string FSH_ProCodeGeneral { get; set; }
+    public bool? FSH_ReplyIsTrue { get; set; }
+    public bool? FSH_ReplyIsBMTrue { get; set; }
+    public bool? FSH_IsRectification { get; set; }
+    public string FSH_PushType { get; set; }
+    public int? FSH_SubFlowID_SSP { get; set; }
+    public int? FSH_SubFlowID_SSPBM { get; set; }
+    public string FSH_SSPCode { get; set; }
+    public int? FSH_SSPAreaID { get; set; }
+    public int? FSH_AcceptBMID1 { get; set; }
+    public string FSH_AcceptName1 { get; set; }
+    public int? FSH_AcceptBMID2 { get; set; }
+    public string FSH_AcceptName2 { get; set; }
+    public int? FSH_AcceptBMID3 { get; set; }
+    public string FSH_AcceptName3 { get; set; }
+    public int? FSH_EnIndustryID { get; set; }
+    public string FSH_EnIndustryName { get; set; }
+    public int? FSH_EnMarketID { get; set; }
+    public string FSH_EnMarketName { get; set; }
+    public string FSH_CallMatch { get; set; }
+    public bool? FSH_End12315 { get; set; }
+    public bool? FSH_24End { get; set; }
+    public int? FSH_IndustryID { get; set; }
+    public string FSH_IndustryName { get; set; }
+    public string FSH_IndustryIDType { get; set; }
+    public string FSH_WorkVerify { get; set; }
+    public string FSH_Checklist { get; set; }
+    public string FSH_TagType { get; set; }
+    public string FSH_Compliance { get; set; }
+}

+ 12 - 0
SnapshotWinFormsApp/Entities/OldHotline/OldBaseEntity.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.IO.Pipes;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Entities.OldHotline;
+public abstract class OldBaseEntity<T>
+{
+    public virtual T Id { get; set; }
+}

+ 4 - 2
SnapshotWinFormsApp/Entities/OldHotline/SSP_AreaEntity.cs

@@ -8,9 +8,11 @@ using System.Threading.Tasks;
 namespace SnapshotWinFormsApp.Entities.OldHotline;
 
 [SugarTable("ZG_CityHotline_Ver3.dbo.SSP_Area")]
-public class SSP_AreaEntity
+public class SSP_AreaEntity :OldBaseEntity<int>
 {
-    public int S_ID { get; set; }
+    [SugarColumn(ColumnName = "S_ID")]
+    public override int Id {get;set;}
+    //public int S_ID { get; set; }
     public string Areaid { get; set; }
     public int Areapid { get; set; }
     public string? Areaname { get; set; }

+ 26 - 0
SnapshotWinFormsApp/Entities/OldHotline/SSP_AreaUserEntity.cs

@@ -0,0 +1,26 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Entities.OldHotline;
+
+[SugarTable("SSP_AreaUser")]
+public class SSP_AreaUserEntity : OldBaseEntity<string>
+{
+    [SugarColumn(ColumnName = "ID")]
+    public override string Id { get; set ; }
+
+    public string AreaID { get; set; }
+    public string AreaName { get; set; }
+    public string AreaTown { get; set; }
+    public string Name { get; set; }
+    public string Tel { get; set; }
+    public string Sex { get; set; }
+    public int Count { get; set; }
+    public string InsertTime { get; set; }
+    public int InsertUserID { get; set; }
+    public string InsertUserName { get; set; }
+}

+ 25 - 0
SnapshotWinFormsApp/Entities/OldHotline/SSP_InviteEntity.cs

@@ -0,0 +1,25 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Entities.OldHotline;
+
+[SugarTable("ZG_CityHotline_Ver3.dbo.SSP_InviteCode")]
+public class SSP_InviteEntity : OldBaseEntity<int>
+{
+    [SugarColumn(ColumnName = "SIC_ID")]
+    public override int Id { get; set; }
+    //public int SIC_ID { get; set; }
+    public int SIC_PID { get; set; }
+    public string SIC_BMName { get; set; }
+    public string SIC_Tel { get; set; }
+    public string SIC_Code { get; set; }
+    public string SIC_Code2 { get; set; }
+    public string SIC_imgUrl { get; set; }
+    public int SIC_OrderID { get; set; }
+    public string SIC_Codeold { get; set; }
+    public string SIC_Byte { get; internal set; }
+}

+ 22 - 0
SnapshotWinFormsApp/Entities/OldHotline/SSP_InviteLogEntity.cs

@@ -0,0 +1,22 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Entities.OldHotline;
+
+[SugarTable("ZG_CityHotline_Ver3.dbo.SSP_Invite")]
+public class SSP_InviteLogEntity: OldBaseEntity<string>
+{
+    [SugarColumn(ColumnName = "SSPI_ID")]
+    public override string Id { get => base.Id; set => base.Id = value; }
+    //public string SSPI_ID { get; set; }
+    public string SSPI_Openid { get; set; }
+    public DateTime SSPI_AddTime { get; set; }
+    public string SSPI_Code { get; set; }
+    public string SSPI_Remarks { get; set; }
+    public string SSPI_CodeID { get; set; }
+    public int SSPI_Type { get; set; }
+}

+ 4 - 2
SnapshotWinFormsApp/Entities/OldHotline/WeChatFollowUserEntity.cs

@@ -8,10 +8,12 @@ using System.Threading.Tasks;
 namespace SnapshotWinFormsApp.Entities.OldHotline;
 
 [SugarTable("ZG_CityHotline_Ver3.dbo.WeChat_FollowUsers")]
-public class WeChatFollowUserEntity
+public class WeChatFollowUserEntity : OldBaseEntity<int>
 {
     public string? openid { get; set; }
-    public int UserID { get; set; }
+    [SugarColumn(ColumnName = "UserID")]
+    public override int Id { get => base.Id; set => base.Id = value; }
+    //public int UserID { get; set; }
     public string appid { get; set; }
     public int subscribe { get; set; }
     public string unionid { get; set; }

+ 7 - 4
SnapshotWinFormsApp/Entities/OldHotline/WeChatUserEntity.cs

@@ -8,10 +8,13 @@ using System.Threading.Tasks;
 namespace SnapshotWinFormsApp.Entities.OldHotline;
 
 [SugarTable("ZG_CityHotline_Web.dbo.Web30_UserRegister")]
-public class WeChatUserEntity
+public class WeChatUserEntity : OldBaseEntity<int>
 {
     public string WUR_Openid { get; set; }
-    public int WUR_WebUserID { get; set; }
+
+    [SugarColumn(ColumnName = "WUR_WebUserID")]
+    public override int Id { get; set; }
+
     public string WUR_WebUserName { get; set; }
     public string WUR_WebLoginName { get; set; }
     public string WUR_PhoneNum { get; set; }
@@ -23,10 +26,10 @@ public class WeChatUserEntity
     public string WUR_Mail { get; set; }
     public string WUR_RegIP { get; set; }
     public DateTime WUR_RegDate { get; set; }
-    public int? WUR_StateFlag { get; set; }
+    public string? WUR_StateFlag { get; set; }
     public string WUR_LastIP { get; set; }
     public DateTime WUR_LastDate { get; set; }
-    public int WUR_SyncState { get; set; }
+    public string? WUR_SyncState { get; set; }
     public string WUR_unionid { get; set; }
     public string WUR_Img { get; set; }
     public string WUR_UserType { get; set; }

+ 55 - 51
SnapshotWinFormsApp/MainForm.Designer.cs

@@ -32,10 +32,10 @@ partial class MainForm
         CancelBtn = new Button();
         splitContainer1 = new SplitContainer();
         tableLayoutPanel1 = new TableLayoutPanel();
+        cityNameCbox = new ComboBox();
         OkBtn = new Button();
-        guiderCBox = new CheckBox();
-        thirdAccountCBox = new CheckBox();
-        communityInfoCBox = new CheckBox();
+        startTimePicker = new DateTimePicker();
+        endTimePicker = new DateTimePicker();
         ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
         splitContainer1.Panel1.SuspendLayout();
         splitContainer1.Panel2.SuspendLayout();
@@ -51,17 +51,20 @@ partial class MainForm
         logTxt.Font = new Font("Courier New", 12F, FontStyle.Bold, GraphicsUnit.Point);
         logTxt.ForeColor = Color.LimeGreen;
         logTxt.Location = new Point(0, 0);
+        logTxt.Margin = new Padding(3, 4, 3, 4);
         logTxt.Multiline = true;
         logTxt.Name = "logTxt";
         logTxt.ScrollBars = ScrollBars.Vertical;
-        logTxt.Size = new Size(739, 526);
+        logTxt.Size = new Size(823, 701);
         logTxt.TabIndex = 1;
         // 
         // CancelBtn
         // 
-        CancelBtn.Location = new Point(103, 3);
+        CancelBtn.Dock = DockStyle.Fill;
+        CancelBtn.Location = new Point(128, 482);
+        CancelBtn.Margin = new Padding(3, 4, 3, 4);
         CancelBtn.Name = "CancelBtn";
-        CancelBtn.Size = new Size(75, 23);
+        CancelBtn.Size = new Size(119, 215);
         CancelBtn.TabIndex = 0;
         CancelBtn.Text = "停止任务";
         CancelBtn.UseVisualStyleBackColor = true;
@@ -73,6 +76,7 @@ partial class MainForm
         splitContainer1.FixedPanel = FixedPanel.Panel1;
         splitContainer1.IsSplitterFixed = true;
         splitContainer1.Location = new Point(0, 0);
+        splitContainer1.Margin = new Padding(3, 4, 3, 4);
         splitContainer1.Name = "splitContainer1";
         // 
         // splitContainer1.Panel1
@@ -83,8 +87,9 @@ partial class MainForm
         // 
         splitContainer1.Panel2.Controls.Add(logTxt);
         splitContainer1.Panel2MinSize = 200;
-        splitContainer1.Size = new Size(943, 526);
-        splitContainer1.SplitterDistance = 200;
+        splitContainer1.Size = new Size(1078, 701);
+        splitContainer1.SplitterDistance = 250;
+        splitContainer1.SplitterWidth = 5;
         splitContainer1.TabIndex = 2;
         // 
         // tableLayoutPanel1
@@ -92,68 +97,68 @@ partial class MainForm
         tableLayoutPanel1.ColumnCount = 2;
         tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
         tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
-        tableLayoutPanel1.Controls.Add(communityInfoCBox, 0, 2);
-        tableLayoutPanel1.Controls.Add(OkBtn, 0, 0);
-        tableLayoutPanel1.Controls.Add(CancelBtn, 1, 0);
-        tableLayoutPanel1.Controls.Add(guiderCBox, 0, 1);
-        tableLayoutPanel1.Controls.Add(thirdAccountCBox, 1, 1);
+        tableLayoutPanel1.Controls.Add(cityNameCbox, 0, 0);
+        tableLayoutPanel1.Controls.Add(OkBtn, 0, 2);
+        tableLayoutPanel1.Controls.Add(CancelBtn, 1, 2);
+        tableLayoutPanel1.Controls.Add(startTimePicker, 0, 1);
+        tableLayoutPanel1.Controls.Add(endTimePicker, 1, 1);
         tableLayoutPanel1.Dock = DockStyle.Fill;
         tableLayoutPanel1.Location = new Point(0, 0);
+        tableLayoutPanel1.Margin = new Padding(3, 4, 3, 4);
         tableLayoutPanel1.Name = "tableLayoutPanel1";
         tableLayoutPanel1.RowCount = 3;
-        tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
-        tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
-        tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 175F));
-        tableLayoutPanel1.Size = new Size(200, 526);
+        tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 42.27848F));
+        tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 57.72152F));
+        tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 222F));
+        tableLayoutPanel1.Size = new Size(250, 701);
         tableLayoutPanel1.TabIndex = 1;
         // 
+        // cityNameCbox
+        // 
+        cityNameCbox.Dock = DockStyle.Fill;
+        cityNameCbox.DropDownStyle = ComboBoxStyle.DropDownList;
+        cityNameCbox.FormattingEnabled = true;
+        cityNameCbox.Location = new Point(3, 3);
+        cityNameCbox.Name = "cityNameCbox";
+        cityNameCbox.Size = new Size(119, 28);
+        cityNameCbox.TabIndex = 1;
+        // 
         // OkBtn
         // 
-        OkBtn.Location = new Point(3, 3);
+        OkBtn.Dock = DockStyle.Fill;
+        OkBtn.Location = new Point(3, 482);
+        OkBtn.Margin = new Padding(3, 4, 3, 4);
         OkBtn.Name = "OkBtn";
-        OkBtn.Size = new Size(75, 23);
+        OkBtn.Size = new Size(119, 215);
         OkBtn.TabIndex = 0;
         OkBtn.Text = "开始导入";
         OkBtn.UseVisualStyleBackColor = true;
         OkBtn.Click += OkBtn_Click;
         // 
-        // guiderCBox
-        // 
-        guiderCBox.AutoSize = true;
-        guiderCBox.Location = new Point(3, 178);
-        guiderCBox.Name = "guiderCBox";
-        guiderCBox.Size = new Size(91, 19);
-        guiderCBox.TabIndex = 1;
-        guiderCBox.Text = "导入网格员";
-        guiderCBox.UseVisualStyleBackColor = true;
-        // 
-        // thirdAccountCBox
+        // startTimePicker
         // 
-        thirdAccountCBox.AutoSize = true;
-        thirdAccountCBox.Location = new Point(103, 178);
-        thirdAccountCBox.Name = "thirdAccountCBox";
-        thirdAccountCBox.Size = new Size(94, 19);
-        thirdAccountCBox.TabIndex = 2;
-        thirdAccountCBox.Text = "导入微信账号";
-        thirdAccountCBox.UseVisualStyleBackColor = true;
+        startTimePicker.Dock = DockStyle.Fill;
+        startTimePicker.Location = new Point(3, 205);
+        startTimePicker.Name = "startTimePicker";
+        startTimePicker.Size = new Size(119, 27);
+        startTimePicker.TabIndex = 2;
         // 
-        // communityInfoCBox
+        // endTimePicker
         // 
-        communityInfoCBox.AutoSize = true;
-        communityInfoCBox.Location = new Point(3, 353);
-        communityInfoCBox.Name = "communityInfoCBox";
-        communityInfoCBox.Size = new Size(94, 19);
-        communityInfoCBox.TabIndex = 3;
-        communityInfoCBox.Text = "导入社区信息";
-        communityInfoCBox.UseVisualStyleBackColor = true;
+        endTimePicker.Dock = DockStyle.Fill;
+        endTimePicker.Location = new Point(128, 205);
+        endTimePicker.Name = "endTimePicker";
+        endTimePicker.Size = new Size(119, 27);
+        endTimePicker.TabIndex = 3;
         // 
         // MainForm
         // 
         AcceptButton = OkBtn;
-        AutoScaleDimensions = new SizeF(7F, 15F);
+        AutoScaleDimensions = new SizeF(8F, 20F);
         AutoScaleMode = AutoScaleMode.Font;
-        ClientSize = new Size(943, 526);
+        ClientSize = new Size(1078, 701);
         Controls.Add(splitContainer1);
+        Margin = new Padding(3, 4, 3, 4);
         Name = "MainForm";
         StartPosition = FormStartPosition.CenterScreen;
         Text = "随手拍数据导入";
@@ -163,7 +168,6 @@ partial class MainForm
         ((System.ComponentModel.ISupportInitialize)splitContainer1).EndInit();
         splitContainer1.ResumeLayout(false);
         tableLayoutPanel1.ResumeLayout(false);
-        tableLayoutPanel1.PerformLayout();
         ResumeLayout(false);
     }
 
@@ -172,8 +176,8 @@ partial class MainForm
     private Button CancelBtn;
     private SplitContainer splitContainer1;
     private TableLayoutPanel tableLayoutPanel1;
+    private ComboBox cityNameCbox;
     private Button OkBtn;
-    private CheckBox guiderCBox;
-    private CheckBox thirdAccountCBox;
-    private CheckBox communityInfoCBox;
+    private DateTimePicker startTimePicker;
+    private DateTimePicker endTimePicker;
 }

+ 116 - 16
SnapshotWinFormsApp/MainForm.cs

@@ -1,38 +1,138 @@
+using Microsoft.VisualBasic.Logging;
 using SnapshotWinFormsApp.Application;
+using SnapshotWinFormsApp.Application.Dtos;
+using SnapshotWinFormsApp.Application.Interfaces;
 using SnapshotWinFormsApp.Repository;
+using SnapshotWinFormsApp.Repository.Enum;
 using SnapshotWinFormsApp.Tools;
+using SqlSugar;
+using System.ComponentModel;
+using System.Configuration;
+using System.Reflection;
 
 namespace SnapshotWinFormsApp;
 
 public partial class MainForm : Form
 {
     private readonly DbSqlServer _sqlServerDB;
-    private readonly SnapshotUserInfoApplication _snapshotUserInfoApplication;
-    private readonly CommunityInfoApplication _communityInfoApplication;
     private CancellationTokenSource? _cts;
+    private EButtonStatusType _startButtonStatus;
+    public static ManualResetEventSlim _pauseEvent = new ManualResetEventSlim(true);
 
-    public MainForm(DbSqlServer sqlServerDB)
+    public MainForm(DbSqlServer dbSqlServer)
     {
-        _sqlServerDB = sqlServerDB;
-        _snapshotUserInfoApplication = new SnapshotUserInfoApplication(sqlServerDB);
-        _communityInfoApplication = new CommunityInfoApplication(sqlServerDB);
+        _startButtonStatus = EButtonStatusType.Start;
+        _sqlServerDB = dbSqlServer;
 
         InitializeComponent();
+        LoadCheckBox();
+        LoadCityName();
         logTxt.AppendText("初始化完成\r\n");
         logTxt.AppendText("日志文件夹:" + Logs.Path() + "\r\n");
     }
 
-    private void OkBtn_Click(object sender, EventArgs e)
+    private void LoadCityName()
     {
-        _cts?.Cancel();
-        _cts = new CancellationTokenSource();
-        var token = _cts.Token;
-        if (guiderCBox.Checked)
-            Task.Run(() => _snapshotUserInfoApplication.ImportGuiderInfoAsync(AddLog, token));
-        if (thirdAccountCBox.Checked)
-            Task.Run(() => _snapshotUserInfoApplication.ImportSnapshotUserInfoAsync(AddLog, token));
-        if (communityInfoCBox.Checked)
-            Task.Run(() => _communityInfoApplication.ImportCommunityInfoAsync(AddLog, token));
+        cityNameCbox.DataSource = ConfigurationManager.ConnectionStrings
+         .Cast<ConnectionStringSettings>()
+         .Where(setting => !string.IsNullOrEmpty(setting.ProviderName) && setting.ProviderName.Length < 8)
+         .Select(setting => setting.ProviderName)
+         .ToHashSet()
+         .ToList<string>();
+        cityNameCbox.DropDownStyle = ComboBoxStyle.DropDownList;
+    }
+
+    private void LoadCheckBox()
+    {
+        var types = Assembly.GetExecutingAssembly()
+                        .GetTypes()
+                        .Where(t => t.IsClass && t.Name.StartsWith("ImportApplicationBase") == false && !t.IsAbstract && typeof(IImportApplication).IsAssignableFrom(t))
+                        .ToList();
+
+        int rowIndex = 3; 
+        int colIndex = 0;
+
+        foreach (var type in types)
+        {
+            var descriptionAttr = type.GetCustomAttribute<DescriptionAttribute>();
+            string description = descriptionAttr?.Description ?? type.Name;
+
+            CheckBox checkBox = new CheckBox
+            {
+                Text = description,
+                Tag = type,
+                AutoSize = true
+            };
+
+            if (tableLayoutPanel1.RowCount <= rowIndex)
+            {
+                tableLayoutPanel1.RowCount = rowIndex + 1;
+                tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
+            }
+
+            tableLayoutPanel1.Controls.Add(checkBox, colIndex, rowIndex);
+
+            colIndex++;
+            if (colIndex > 1)
+            {
+                colIndex = 0;
+                rowIndex++;
+            }
+        }
+    }
+
+    private async void OkBtn_Click(object sender, EventArgs e)
+    {
+
+        if (_startButtonStatus == EButtonStatusType.Start)
+        {
+            _startButtonStatus = EButtonStatusType.Pause;
+            OkBtn.Text = "暂停";
+            _cts = new CancellationTokenSource();
+            var tasks = new List<Task>();
+
+            foreach (var control in tableLayoutPanel1.Controls)
+            {
+                if (control is CheckBox checkBox && checkBox.Checked)
+                {
+                    Type type = (Type)checkBox.Tag;
+                    if (Activator.CreateInstance(type, new CreateInstanceInDto(_sqlServerDB, cityNameCbox.SelectedItem.ToString(), startTimePicker.Value, endTimePicker.Value)) is IImportApplication instance)
+                    {
+                        tasks.Add(RunImport(instance, _cts.Token));
+                    }
+                }
+            }
+
+            try
+            {
+                await Task.WhenAll(tasks);
+                AddLog("所有任务完成");
+            }
+            catch (OperationCanceledException)
+            {
+                AddLog("任务已取消");
+            }
+            return;
+        }
+        if (_startButtonStatus == EButtonStatusType.Pause)
+        {
+            _startButtonStatus = EButtonStatusType.Wait;
+            OkBtn.Text = "继续";
+            _pauseEvent.Reset();
+            return;
+        }
+        if (_startButtonStatus == EButtonStatusType.Wait)
+        {
+            _startButtonStatus = EButtonStatusType.Pause;
+            OkBtn.Text = "暂停";
+            _pauseEvent.Set();
+            return;
+        }
+    }
+
+    private async Task RunImport(IImportApplication instance, CancellationToken token)
+    {
+        await instance.ImportAsync(AddLog, token);
     }
 
     private void AddLog(string msg)

+ 43 - 2
SnapshotWinFormsApp/Repository/BaseRepository.cs

@@ -1,22 +1,44 @@
 using Abp.Collections.Extensions;
+using SnapshotWinFormsApp.Application.Dtos;
 using SnapshotWinFormsApp.Entities.NewHotline;
 using SnapshotWinFormsApp.Repository.Interfaces;
 using SqlSugar;
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.Data;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 
 namespace SnapshotWinFormsApp.Repository;
 
+public class ConcurrentQueueRepository<TEntity> where TEntity : Entity, new()
+{
+    private ConcurrentQueue<TEntity> _queue = new ConcurrentQueue<TEntity>();
+
+    public void Insert(TEntity entity, ISqlSugarClient sugarClient, bool isEnd)
+    {
+        _queue.Enqueue(entity);
+        if (_queue.Count != 1000 && isEnd == false) return;
+        sugarClient.Fastest<TEntity>().BulkCopy(_queue.ToList());
+        _queue.Clear();
+    }
+}
+
+
 public class BaseRepository<T> : IBaseRepository<T> where T : Entity, new()
 {
     private readonly SqlSugarClient _db;
+    public readonly ConcurrentQueueRepository<T> _queue;
+
+    public SqlSugarClient db => this._db;
 
-    public BaseRepository(DbSqlServer context, string key)
+    public BaseRepository(CreateInstanceInDto inDto)
     {
-        _db = context.DbItems.GetValueOrDefault(key + "PGSQLDB");
+        var context = inDto.DbSqlServer;
+        _db = context.DbItems.GetValueOrDefault(inDto.Key + "PGSQLDB");
+        _queue = new ConcurrentQueueRepository<T>();
     }
 
     public async Task<List<T>> GetAllAsync(CancellationToken token)
@@ -46,4 +68,23 @@ public class BaseRepository<T> : IBaseRepository<T> where T : Entity, new()
     {
         _db.Updateable<T>(entity).ExecuteCommand();
     }
+
+    public IUpdateable<T> Updateable()
+        => _db.Updateable<T>();
+
+    public async Task<int> ExecuteSqlAsync(string sql)
+    {
+        return await _db.Ado.ExecuteCommandAsync(sql, new List<SugarParameter>());
+    }
+
+    public DataTable GetDataTable(string sql)
+        => _db.Ado.GetDataTable(sql);
+
+    public string InsertBulk(T entity, bool isEnd)
+    {
+        if (entity.Id.IsNullOrEmpty())
+            entity.InitId();
+        _queue.Insert(entity,_db, isEnd);
+        return entity.Id;
+    }
 }

+ 19 - 0
SnapshotWinFormsApp/Repository/Enum/EButtonStatusType.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Repository.Enum;
+public enum EButtonStatusType
+{
+    [Description("当前显示开始")]
+    Start = 0, 
+
+    [Description("当前显示暂停")]
+    Pause = 1,
+
+    [Description("当前显示继续")]
+    Wait = 2
+}

+ 19 - 0
SnapshotWinFormsApp/Repository/Enum/ECompliantType.cs

@@ -0,0 +1,19 @@
+using System.ComponentModel;
+
+namespace SnapshotWinFormsApp.Repository.Enum;
+
+/// <summary>
+/// 合规类型
+/// </summary>
+public enum ECompliantType
+{
+    //“首次检查合规”、“第二次检查合规”、“第三次及以上检查合规”、“不合规”
+    [Description("不合规")]
+    Not = 0,
+    [Description("首次检查合规")]
+    First = 1,
+    [Description("第二次检查合规")]
+    Second = 2,
+    [Description("第三次及以上检查合规")]
+    Third = 3,
+}

+ 52 - 0
SnapshotWinFormsApp/Repository/Enum/EGuiderSystemReplyType.cs

@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Repository.Enum;
+public enum EGuiderSystemReplyType
+{
+    /// <summary>
+    /// 流转
+    /// </summary>
+    [Description("流转")]
+    Circular = 1,
+
+    /// <summary>
+    /// 办结
+    /// </summary>
+    [Description("办结")]
+    Field = 2,
+
+    /// <summary>
+    /// 退回
+    /// </summary>
+    [Description("退回")]
+    Returned = 3,
+
+    /// <summary>
+    /// 签收
+    /// </summary>
+    [Description("签收")]
+    Sign = 4,
+
+    /// <summary>
+    /// 消息推送
+    /// </summary>
+    [Description("消息推送")]
+    SendMessage = 5,
+
+    /// <summary>
+    /// 超时自动退单
+    /// </summary>
+    [Description("超时自动退单")]
+    TimeoutBack = 6,
+
+    /// <summary>
+    /// 流转
+    /// </summary>
+    [Description("流转")]
+    Circulating = 7
+}

+ 28 - 0
SnapshotWinFormsApp/Repository/Enum/EIndustryType.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SnapshotWinFormsApp.Repository.Enum;
+
+/// <summary>
+/// 行业类型;
+/// 0: 作业申报;
+/// 1: 线索上报;
+/// </summary>
+public enum EIndustryType
+{
+    /// <summary>
+    /// 作业申报
+    /// </summary>
+    [Description("作业申报")]
+    Declare,
+
+    /// <summary>
+    /// 线索上报
+    /// </summary>
+    [Description("线索上报")]
+    Clue
+}

+ 10 - 2
SnapshotWinFormsApp/Repository/Interfaces/IRepository.cs

@@ -1,25 +1,33 @@
 using SnapshotWinFormsApp.Entities.NewHotline;
+using SnapshotWinFormsApp.Entities.OldHotline;
 using SqlSugar;
 using System;
 using System.Collections.Generic;
+using System.Data;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 
 namespace SnapshotWinFormsApp.Repository.Interfaces;
 
-public interface IRepository<T> where T : class, new()
+public interface IRepository<T, TKey> where T : OldBaseEntity<TKey>, new()
 {
     ISugarQueryable<T> Queryable();
     T GetById(int id);
-    Task<List<T>> GetAllAsync();
+    Task<List<T>> GetAllAsync(CancellationToken token);
+    DataTable GetDataTable(string sql, List<SugarParameter> parameters = null);
 }
 
 public interface IBaseRepository<T> where T : Entity, new()
 {
+    SqlSugarClient db { get; }
     ISugarQueryable<T> Queryable();
     T GetById(int id);
     Task<List<T>> GetAllAsync(CancellationToken token);
     Task<string> InsertAsync(T entity, CancellationToken token);
+    string InsertBulk(T entity, bool isEnd);
     void Update(T entity);
+    IUpdateable<T> Updateable();
+    Task<int> ExecuteSqlAsync(string sql);
+    DataTable GetDataTable(string sql);
 }

+ 19 - 8
SnapshotWinFormsApp/Repository/Repository.cs

@@ -1,20 +1,24 @@
-using SnapshotWinFormsApp.Repository.Interfaces;
+using SnapshotWinFormsApp.Application.Dtos;
+using SnapshotWinFormsApp.Entities.OldHotline;
+using SnapshotWinFormsApp.Repository.Interfaces;
 using SqlSugar;
 using System;
 using System.Collections.Generic;
+using System.Data;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 
 namespace SnapshotWinFormsApp.Repository;
 
-public class Repository<T> : IRepository<T> where T : class, new()
+public class Repository<T, TKey> : IRepository<T, TKey> where T : OldBaseEntity<TKey>, new()
 {
-    private readonly SqlSugarClient _db;
+    public SqlSugarClient _db { get; }
 
-    public Repository(DbSqlServer context, string key)
+    public Repository(CreateInstanceInDto inDto)
     {
-        _db = context.DbItems.GetValueOrDefault(key + "SQLServerDB");
+        var context = inDto.DbSqlServer;
+        _db = context.DbItems.GetValueOrDefault(inDto.Key + "SQLServerDB");
     }
 
     public T GetById(int id)
@@ -22,13 +26,14 @@ public class Repository<T> : IRepository<T> where T : class, new()
         return _db.Queryable<T>().InSingle(id);
     }
 
-    public async Task<List<T>> GetAllAsync()
+    public async Task<List<T>> GetAllAsync(CancellationToken token)
     {
+        var sql = string.Empty;
         try
         {
             var query = _db.Queryable<T>();
-            var sql = query.ToSqlString();
-            return await query.ToListAsync();
+            sql = query.ToSqlString();
+            return await query.ToListAsync(token);
 
         }
         catch (Exception e)
@@ -43,4 +48,10 @@ public class Repository<T> : IRepository<T> where T : class, new()
     {
         return _db.Queryable<T>();
     }
+
+    public DataTable GetDataTable(string sql, List<SugarParameter> parameters = null)
+    {
+        return _db.Ado.GetDataTable(sql, parameters);
+    }
+
 }

+ 92 - 0
SnapshotWinFormsApp/Tools/FileTools.cs

@@ -0,0 +1,92 @@
+using SnapshotWinFormsApp.Entities.NewHotline;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using File = SnapshotWinFormsApp.Entities.NewHotline.File;
+
+namespace SnapshotWinFormsApp.Tools;
+
+public class FileTools
+{
+    /// <summary>
+    /// 下载网络文件并上传到文件服务器, 返回 File.Id
+    /// </summary>
+    /// <param name="file"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<FileJson> GetNetworkFileAsync(string file, CancellationToken cancellationToken = default)
+    {
+        try
+        {
+            var fileBytes = await DownloadFileToMemoryAsync(file);
+            if (fileBytes is null) return new FileJson();
+
+            var uploadUrl = ConfigurationManager.AppSettings["FileServerUrl"] + "/file/upload?source=hotline";
+            var match = Regex.Match(file, "[^/]+\\.[a-zA-Z0-9]+$").Value;
+            var resultJson = await UploadFileFromMemoryAsync(fileBytes, match, uploadUrl);
+            var result = resultJson.FromJson<ApiResponse<FileJson>>();
+            var fileSplit = match.Split('.');
+            var entity = new File()
+            {
+                Additions = result.Result.Id,
+                FileName = result.Result.FileName,
+                Path = result.Result.Path,
+                AllPath = file,
+                Type = fileSplit[1],
+                Name = fileSplit[0],
+            };
+            return result.Result;
+        }
+        catch (Exception e)
+        {
+            var message = $"下载网络文件并上传到文件服务器失败: {e.Message}";
+        }
+        return new FileJson();
+    }
+
+    /// <summary>
+    /// 下载文件, 返回字节
+    /// </summary>
+    /// <param name="url"></param>
+    /// <returns></returns>
+    private async Task<byte[]> DownloadFileToMemoryAsync(string url)
+    {
+        try
+        {
+            using var client = new HttpClient();
+            HttpResponseMessage response = await client.GetAsync(url);
+            response.EnsureSuccessStatusCode();
+            return await response.Content.ReadAsByteArrayAsync();
+
+        }
+        catch (Exception e)
+        {
+            var msg = e.Message;
+        }
+        finally
+        {
+        }
+        return null;
+    }
+
+    public async Task<string> UploadFileFromMemoryAsync(byte[] fileBytes, string fileName, string uploadUrl)
+    {
+        using HttpClient client = new HttpClient();
+        using var multipartContent = new MultipartFormDataContent();
+        var fileContent = new ByteArrayContent(fileBytes);
+        fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
+
+        multipartContent.Add(fileContent, "fileData", fileName);
+
+        HttpResponseMessage response = await client.PostAsync(uploadUrl, multipartContent);
+        response.EnsureSuccessStatusCode();
+
+        var result = await response.Content.ReadAsStringAsync();
+        return result;
+    }
+}

+ 27 - 2
SnapshotWinFormsApp/Tools/MapsterConfig.cs

@@ -1,7 +1,10 @@
-using Mapster;
+using DataTransmission.Enum;
+using Hotline.Snapshot;
+using Mapster;
 using SnapshotWinFormsApp.Application.Dtos;
 using SnapshotWinFormsApp.Entities.NewHotline;
 using SnapshotWinFormsApp.Entities.OldHotline;
+using SqlSugar.Extensions;
 
 namespace SnapshotWinFormsApp.Tools;
 
@@ -9,7 +12,18 @@ public static class MapsterConfig
 {
     public static void RegisterMappings()
     {
-        TypeAdapterConfig<WeChatUserDto, SnapshotUserInfo>.NewConfig()
+        TypeAdapterConfig<SSP_AreaUserEntity, Practitioner>.NewConfig()
+            .Map(m => m.CreationTime, n => n.InsertTime.ObjToDate())
+            .Map(m => m.PhoneNumber, n => n.Tel)
+            .Map(m => m.Gender, n => n.Sex.Trim() == "男" ? EGender.Male : EGender.Female);
+
+        TypeAdapterConfig<WeChatUserEntity, ThirdAccount>.NewConfig()
+            .Map(m => m.UserName, n => n.WUR_WebUserName)
+            .Map(m => m.OpenId, n => n.WUR_Openid)
+            .Map(m => m.UnIonId, n => n.WUR_unionid)
+            .Map(m => m.CreationTime, n => n.WUR_RegDate);
+
+        TypeAdapterConfig<WeChatUserEntity, Citizen>.NewConfig()
             .Map(m => m.CreationTime, n => n.WUR_RegDate)
             .Map(m => m.PhoneNumber, n => n.WUR_PhoneNum)
             .Map(m => m.Name, n => n.WUR_WebUserName);
@@ -28,5 +42,16 @@ public static class MapsterConfig
             .Map(m => m.ParentCode, n => n.Areapid)
             .Map(m => m.DepartmentNo, n => n.Areadepartmentno)
             .Map(m => m.FullName, n => n.Areafullname);
+
+        TypeAdapterConfig<SSP_InviteEntity, InviteCode>.NewConfig()
+            .Map(m => m.BeginCode, n => n.SIC_Code)
+            .Map(m => m.EndCode, n => n.SIC_Code2)
+            .Map(m => m.OrgName, n => n.SIC_BMName)
+            .Map(m => m.QRCodeUrl, n => n.SIC_imgUrl);
+
+        TypeAdapterConfig<SSP_InviteLogEntity, InviteCodeRecord>.NewConfig()
+            .Map(m => m.WXOpenId, n => n.SSPI_Openid)
+            .Map(m => m.InviteCode, n => n.SSPI_Code)
+            .Map(m => m.CreationTime, n => n.SSPI_AddTime);
     }
 }

+ 18 - 1
SnapshotWinFormsApp/Tools/MyExtensions.cs

@@ -1,4 +1,6 @@
-using System.ComponentModel.DataAnnotations.Schema;
+using Abp.Extensions;
+using Newtonsoft.Json;
+using System.ComponentModel.DataAnnotations.Schema;
 using System.Data;
 using System.Reflection;
 using System.Security.Cryptography;
@@ -8,6 +10,16 @@ namespace SnapshotWinFormsApp.Tools;
 
 public static class MyExtensions
 {
+    public static bool IsNullOrEmpty(this string? str)
+    {
+        return string.IsNullOrEmpty(str);
+    }
+
+    public static bool NotNullOrEmpty(this string? str)
+    {
+        return !string.IsNullOrEmpty(str);
+    }
+
     /// <summary>
     /// 获取字符串的 md5 
     /// </summary>
@@ -21,6 +33,11 @@ public static class MyExtensions
         }
     }
 
+    public static T FromJson<T>(this string json)
+    {
+        return json.IsNullOrEmpty() ? default(T) : JsonConvert.DeserializeObject<T>(json);
+    }
+
     public static string GetTableName<T>(this T value) where T : class
     {
         var tableAttribute = typeof(T).GetCustomAttribute<TableAttribute>();

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff