修改登录授权方式,增加zctoken登录方案,增加分布式消息队列
| | |
| | | /DocumentFile.Service/obj |
| | | /DocumentServiceAPI.Services/bin |
| | | /DocumentServiceAPI.Services/obj |
| | | ZcPayCore/obj/ |
| | | DocumentServiceApi.InitQMessage/obj/ |
| | |
| | | using DocumentServiceAPI.Utility; |
| | | using Furion.DynamicApiController; |
| | | using Furion.JsonSerialization; |
| | | using Microsoft.AspNetCore.Http; |
| | | using Microsoft.IdentityModel.Tokens; |
| | | using NetTaste; |
| | | using Newtonsoft.Json.Linq; |
| | | using Swashbuckle.AspNetCore.Annotations; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.IdentityModel.Tokens.Jwt; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | |
| | | } |
| | | /// <summary> |
| | | /// 登录 1 输入员工账户或者租户账户,2 选择租户账户,3 选择公司 |
| | | /// 当密码为空时,带入用户中心token即可实现登录 |
| | | /// </summary> |
| | | /// <returns>登录信息</returns> |
| | | [HttpPost("LogoIn")] |
| | | public async Task<RetLoginVM> LogoIn (LoginPsWordIN Parma) |
| | | public async Task<RetLoginVM> LogoIn ( LoginPsWordIN Parma) |
| | | { |
| | | bool needtoken=false; |
| | | if (Parma.TenantId==null) |
| | | //zctok校验成功是否标志 |
| | | bool IsTokenPass=false; |
| | | |
| | | if(string.IsNullOrEmpty(Parma.PassWord)) |
| | | { |
| | | //如果还没确定租户ID 需要先确定租户ID |
| | | List<TenderVM>Tender = await _userService.GetUserTenderList(Parma.ITCode); |
| | | |
| | | switch (Tender.Count) |
| | | |
| | | var Request = App.HttpContext.Request; |
| | | string stoken = Request.Headers["Authorization"]; |
| | | if (stoken == null) |
| | | throw Oops.Oh("没有输入密码"); |
| | | stoken = stoken.Replace("Bearer ", ""); |
| | | |
| | | var isvale = _tokenService.CheckJwt(stoken, out SecurityToken securityToken); |
| | | JwtSecurityToken jwtToken = securityToken as JwtSecurityToken; |
| | | string itcode = jwtToken.Claims.FirstOrDefault(claim => claim.Type == "sub")?.Value; |
| | | if (isvale == false) |
| | | throw Oops.Oh("登录信息出错"); |
| | | if(Parma.ITCode!= itcode) |
| | | throw Oops.Oh("用户名错误"); |
| | | |
| | | |
| | | } |
| | | |
| | | bool needtoken = false; |
| | | |
| | | if (Parma.TenantId == null) |
| | | { |
| | | case 0: |
| | | throw Oops.Oh($"账户或者密码错误"); |
| | | case 1: |
| | | needtoken = await _userService.CheckPsw(Tender[0].TenderId, Tender[0].EmployeeID,Parma.PassWord); |
| | | |
| | | if(!needtoken) |
| | | //如果还没确定租户ID 需要先确定租户ID |
| | | List<TenderVM> Tender = await _userService.GetUserTenderList(Parma.ITCode); |
| | | |
| | | switch (Tender.Count) |
| | | { |
| | | case 0: |
| | | throw Oops.Oh($"账户或者密码错误"); |
| | | |
| | | Parma.TenantId = Tender[0].TenderId; |
| | | Parma.employeeID = Tender[0].EmployeeID; |
| | | if (Parma.UnitID == null) |
| | | case 1: |
| | | if (!needtoken) |
| | | { |
| | | |
| | | List<UnitVM> Units = await _userService.GetUserUnitList(Parma.TenantId ?? 0); |
| | | if (Units.Count == 0) |
| | | { |
| | | //没有公司 |
| | | needtoken = true; |
| | | } |
| | | else if (Units.Count == 1) |
| | | { |
| | | Parma.UnitID = Units[0].UnitID; |
| | | needtoken = true; |
| | | } |
| | | else |
| | | { |
| | | //其他需要用户选择租户 |
| | | return new RetLoginVM |
| | | { |
| | | NeedNext = true, |
| | | Units = Units, |
| | | needtoken = await _userService.CheckPsw(Tender[0].TenderId, Tender[0].EmployeeID, Parma.PassWord); |
| | | |
| | | }; |
| | | } |
| | | if (!needtoken) |
| | | throw Oops.Oh($"账户或者密码错误"); |
| | | } |
| | | |
| | | break; |
| | | |
| | | default: |
| | | |
| | | |
| | | Parma.TenantId = Tender[0].TenderId; |
| | | Parma.employeeID = Tender[0].EmployeeID; |
| | | if (Parma.UnitID == null) |
| | | { |
| | | |
| | | List<UnitVM> Units = await _userService.GetUserUnitList(Parma.TenantId ?? 0); |
| | | if (Units.Count == 0) |
| | | { |
| | | //没有公司 |
| | | needtoken = true; |
| | | } |
| | | else if (Units.Count == 1) |
| | | { |
| | | Parma.UnitID = Units[0].UnitID; |
| | | needtoken = true; |
| | | } |
| | | else |
| | | { |
| | | //其他需要用户选择租户 |
| | | return new RetLoginVM |
| | | { |
| | | NeedNext = true, |
| | | Units = Units, |
| | | |
| | | }; |
| | | } |
| | | } |
| | | |
| | | break; |
| | | |
| | | default: |
| | | //其他需要用户选择租户 |
| | | return new RetLoginVM |
| | | { |
| | | NeedNext = true, |
| | | Tenants = Tender, |
| | | |
| | | }; |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | else if (Parma.UnitID == null) |
| | | { |
| | | |
| | | var Units = await _userService.GetUserUnitList(Parma.TenantId ?? 0); |
| | | if (Units.Count == 0) |
| | | { |
| | | //没有公司 |
| | | needtoken = true; |
| | | } |
| | | else if (Units.Count == 1) { |
| | | Parma.UnitID = Units[0].UnitID; |
| | | needtoken = true; |
| | | } |
| | | else |
| | | { |
| | | //其他需要用户选择租户 |
| | | return new RetLoginVM |
| | | { |
| | | NeedNext = true, |
| | | Tenants = Tender, |
| | | Units = Units, |
| | | |
| | | }; |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | else if(Parma.UnitID==null) |
| | | { |
| | | |
| | | var Units = await _userService.GetUserUnitList(Parma.TenantId??0); |
| | | if(Units.Count==0) |
| | | if (needtoken || Parma.UnitID != null) |
| | | { |
| | | //没有公司 |
| | | needtoken = true; |
| | | } |
| | | else if (Units.Count==1) { |
| | | Parma.UnitID= Units[0].UnitID; |
| | | needtoken = true; |
| | | } |
| | | else |
| | | |
| | | TenderVM Tender = (await _userService.GetUserTenderList(Parma.ITCode)).Where(x => x.TenderId == Parma.TenantId && x.EmployeeID == Parma.employeeID).SingleOrDefault(); |
| | | if (Tender == null) |
| | | { |
| | | throw Oops.Oh($"账户密码或者租户选择错误"); |
| | | } |
| | | if (!IsTokenPass) |
| | | { |
| | | //其他需要用户选择租户 |
| | | needtoken = await _userService.CheckPsw(Tender.TenderId, Tender.EmployeeID, Parma.PassWord); |
| | | |
| | | if (!needtoken) |
| | | throw Oops.Oh($"账户或者密码错误"); |
| | | } |
| | | var token = _tokenService.CreateToken(new Model.JwtInfo |
| | | { |
| | | EID = Tender.EmployeeID, |
| | | LogInSource = Parma.Form, |
| | | TEID = Tender.TenderId, |
| | | UID = Parma.UnitID, |
| | | }); |
| | | return new RetLoginVM |
| | | { |
| | | NeedNext = true, |
| | | Units = Units, |
| | | NeedNext = false, |
| | | Token = token, |
| | | |
| | | }; |
| | | } |
| | | |
| | | } |
| | | |
| | | if(needtoken|| Parma.UnitID!=null) |
| | | { |
| | | |
| | | TenderVM Tender = (await _userService.GetUserTenderList(Parma.ITCode)).Where(x=>x.TenderId==Parma.TenantId&&x.EmployeeID==Parma.employeeID).SingleOrDefault(); |
| | | if(Tender==null) |
| | | { |
| | | throw Oops.Oh($"账户密码或者租户选择错误"); |
| | | } |
| | | needtoken = await _userService.CheckPsw(Tender. TenderId, Tender.EmployeeID, Parma.PassWord); |
| | | |
| | | if (!needtoken) |
| | | throw Oops.Oh($"账户或者密码错误"); |
| | | var token= _tokenService.CreateToken(new Model.JwtInfo |
| | | { |
| | | EID = Tender.EmployeeID, |
| | | LogInSource = Parma.Form, |
| | | TEID = Tender.TenderId, |
| | | UID = Parma.UnitID, |
| | | }); |
| | | return new RetLoginVM |
| | | { |
| | | NeedNext = false, |
| | | Token = token, |
| | | |
| | | }; |
| | | } |
| | | throw Oops.Oh($"参数错误"); |
| | | throw Oops.Oh($"参数错误"); |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 获取公司列表 |
| | |
| | | using Furion.Authorization; |
| | | using Furion.DistributedIDGenerator; |
| | | using Furion.JsonSerialization; |
| | | using Furion.Logging.Extensions; |
| | | using Microsoft.IdentityModel.Tokens; |
| | | using NetTaste; |
| | | using SqlSugar.Extensions; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.IdentityModel.Tokens.Jwt; |
| | | using System.Linq; |
| | | using System.Reflection; |
| | | using System.Security.Claims; |
| | |
| | | /// <summary> |
| | | /// token服务类 |
| | | /// </summary> |
| | | public class TokenService: IScoped |
| | | public class TokenService : IScoped |
| | | { |
| | | /// <summary> |
| | | /// Token是啥 |
| | |
| | | private ISqlSugarClient _db; |
| | | private UserService _UserService; |
| | | private IRedisCacheService _RedisCase; |
| | | public TokenService(ISqlSugarClient db, UserService UserInfoService, IRedisCacheService RedisCase ) { |
| | | public TokenService(ISqlSugarClient db, UserService UserInfoService, IRedisCacheService RedisCase) { |
| | | _db = db; |
| | | _UserService = UserInfoService; |
| | | _RedisCase = RedisCase; |
| | |
| | | /// 新建一个TOken |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public string CreateToken(JwtInfo jwt) |
| | | public string CreateToken(JwtInfo jwt) |
| | | { |
| | | string TokenKey=TokenKeys+ getTokenKey(jwt); |
| | | string TokenKey = TokenKeys + getTokenKey(jwt); |
| | | IDictionary<string, object> propertyDictionary = new Dictionary<string, object>(); |
| | | |
| | | PropertyInfo[] properties = jwt.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); |
| | |
| | | propertyDictionary.Add(propertyName.ToLower(), propertyValue); |
| | | } |
| | | var ID = IDGen.NextID(); |
| | | jwt.JID = ID; |
| | | var token= JWTEncryption.Encrypt(propertyDictionary, App.GetConfig<JWTSettingsOptions>("JWTSettings").ExpiredTime ?? 3600); |
| | | if(jwt.LogInSource==LogInFrom.PC) |
| | | _RedisCase.Add<string>(TokenKey, ID.ToString(), expireSeconds: (int )(App.GetConfig<JWTSettingsOptions>("JWTSettings").ExpiredTime??3600)); |
| | | jwt.JID = ID; |
| | | var token = JWTEncryption.Encrypt(propertyDictionary, App.GetConfig<JWTSettingsOptions>("JWTSettings").ExpiredTime ?? 3600); |
| | | if (jwt.LogInSource == LogInFrom.PC) |
| | | _RedisCase.Add<string>(TokenKey, ID.ToString(), expireSeconds: (int)(App.GetConfig<JWTSettingsOptions>("JWTSettings").ExpiredTime ?? 3600)); |
| | | return token; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 校验token 的有效性 |
| | | /// </summary> |
| | | /// <param name="Token"> Token校验</param> |
| | | /// <param name="validationParameters"></param> |
| | | /// <param name="securityToken"></param> |
| | | /// <returns></returns> |
| | | public bool CheckJwt(string Token, out SecurityToken? securityToken) |
| | | { |
| | | var configuration = App.Configuration; |
| | | // var value = configuration["xxx:xxx"]; |
| | | |
| | | string secretKey = configuration["ZCUserInfoJwtOP:SecurityKey"]; |
| | | if (secretKey == null) |
| | | { |
| | | "没有配置用户中心的安全秘钥 ZCUserInfoJwtOP:SecurityKey 找不到".LogInformation<TokenService>(); |
| | | throw Oops.Oh("配置错误,联系管理员"); |
| | | } |
| | | |
| | | JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); |
| | | //JwtSecurityToken jwt = tokenHandler.ReadJwtToken(Token); |
| | | |
| | | // 验证 JWT 签名并检查有效期 |
| | | TokenValidationParameters validationParameters = new TokenValidationParameters |
| | | { |
| | | ValidateIssuerSigningKey = true, |
| | | IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)), |
| | | ValidateIssuer = false, |
| | | ValidateAudience = false, |
| | | ClockSkew = TimeSpan.Zero // 禁用时间偏移量 |
| | | }; |
| | | try |
| | | { |
| | | ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(Token, validationParameters, out SecurityToken validatedToken); |
| | | |
| | | securityToken = validatedToken; |
| | | return true; |
| | | } |
| | | catch (SecurityTokenException) |
| | | { |
| | | securityToken=null; |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | |
| | | string TokenKey = TokenKeys + jwt.EID?.ToString() + jwt.UID?.ToString() + jwt.TEID?.ToString(); |
| | | return TokenKey; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | } |
| | |
| | | "KeepVerb": true,//保持版本号一致 |
| | | "LowercaseRoute": false |
| | | }, |
| | | |
| | | |
| | | "CorsAccessorSettings": { |
| | | "WithExposedHeaders": [ |
| | | "access-token", |
| | | "x-access-token", |
| | | "environment" |
| | | ] |
| | | }, |
| | | "ZCUserInfoJwtOP": { //zc用户中心jwt配置 用于解析zc的token |
| | | |
| | | "Issuer": "http://zc", |
| | | "Audience": "http://zc", |
| | | "Expires": 86400, |
| | | "weixinExpires": 1296000, // 86400, |
| | | "SecurityKey": "superSecretKey@345", |
| | | "RefreshTokenExpires": 86400, |
| | | "LoginPath": "/_Framework/Redirect401" |
| | | |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | using DocumentServiceAPI.Enum; |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.ComponentModel.DataAnnotations; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | |
| | | /// <summary> |
| | | /// 租户权限 |
| | | /// </summary> |
| | | public class TenantPermissions |
| | | public class TenantPermissions: BaseModel |
| | | { |
| | | /// <summary> |
| | | /// id |
| | | /// </summary> |
| | | [Display(Name = "id ")] |
| | | [SugarColumn(ColumnDescription = "id ")] |
| | | public int Id { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 租户ID |
| | | /// </summary> |
| | | [Display(Name = "租户ID ")] |
| | | [SugarColumn(ColumnDescription = "租户ID ")] |
| | | public int TenantId { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 最大企业个数 |
| | | /// </summary> |
| | | [Display(Name = "最大企业个数 ")] |
| | | [SugarColumn(ColumnDescription = "最大企业个数 ")] |
| | | public int UnitMaxCount { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 最大员工数量 |
| | | /// </summary> |
| | | [Display(Name = "最大员工数量 ")] |
| | | [SugarColumn(ColumnDescription = "最大员工数量 ")] |
| | | public int EmployeeMaxCount { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 到期时间 |
| | | /// </summary> |
| | | [Display(Name = "到期时间 ")] |
| | | [SugarColumn(ColumnDescription = "到期时间 ")] |
| | | public DateTime OverTime { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 描述 |
| | | /// </summary> |
| | | [Display(Name = "描述 ")] |
| | | [SugarColumn(ColumnDescription = "描述 ")] |
| | | public string? Description { get; set; } |
| | | } |
| | | } |
| | |
| | | using Furion.Authorization; |
| | | using Furion.DataEncryption; |
| | | using Microsoft.AspNetCore.Authorization; |
| | | |
| | | namespace DocumentServiceAPI.Web.Entry |
| | |
| | | /// </summary> |
| | | public class AuthorizeHandler:AppAuthorizeHandler |
| | | { |
| | | |
| | | /// <summary> |
| | | /// 请求管道 |
| | | /// </summary> |
| | |
| | | public override Task<bool> PipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext) |
| | | { |
| | | // 此处已经自动验证 Jwt token的有效性了,无需手动验证 |
| | | |
| | | |
| | | // 检查权限,如果方法是异步的就不用 Task.FromResult 包裹,直接使用 async/await 即可 |
| | | return Task.FromResult(CheckAuthorzie(httpContext)); |
| | | } |
| | |
| | | { |
| | | |
| | | "ConfigId": "default", //多库配置ID |
| | | "ConnectionString": "Server=.;Database=doc_new;User ID=sa;Password=123456;", |
| | | //"ConnectionString": "Server=.;Database=doc_new;User ID=sa;Password=123456;", |
| | | "ConnectionString": "Server=localhost\\SQLEXPRESS;Database=CY_DocumentSystemOnline;User ID=sa;Password=123456;", |
| | | "DbType": "SqlServer", |
| | | "IsAutoCloseConnection": true |
| | | |
| | |
| | | |
| | | }, |
| | | |
| | | //消息队列配置 为了独立部署,这里单独配置 |
| | | "InitQRedisConfig": { |
| | | // 如果采用容器化部署Service 要写成redis的服务名,否则写地址 |
| | | "ConnectionString": "127.0.0.1:6379,password=,connectTimeout=30000,responseTimeout=30000,abortConnect=false,connectRetry=1,syncTimeout=10000,DefaultDatabase=10" //redis数据库连接字符串 |
| | | |
| | | }, |
| | | |
| | | |
| | | "JWTSettings": { |
| | |
| | | EndProject |
| | | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DocumentServiceAPI.Services", "DocumentServiceAPI.Services\DocumentServiceAPI.Services.csproj", "{3369F102-ABB2-42A4-B216-58D530AEE8BE}" |
| | | EndProject |
| | | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZcPayCore", "ZcPayCore\ZcPayCore.csproj", "{76BFAB65-B7AC-4534-A595-363551111129}" |
| | | EndProject |
| | | Global |
| | | GlobalSection(SolutionConfigurationPlatforms) = preSolution |
| | | Debug|Any CPU = Debug|Any CPU |
| | |
| | | {3369F102-ABB2-42A4-B216-58D530AEE8BE}.Debug|Any CPU.Build.0 = Debug|Any CPU |
| | | {3369F102-ABB2-42A4-B216-58D530AEE8BE}.Release|Any CPU.ActiveCfg = Release|Any CPU |
| | | {3369F102-ABB2-42A4-B216-58D530AEE8BE}.Release|Any CPU.Build.0 = Release|Any CPU |
| | | {76BFAB65-B7AC-4534-A595-363551111129}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
| | | {76BFAB65-B7AC-4534-A595-363551111129}.Debug|Any CPU.Build.0 = Debug|Any CPU |
| | | {76BFAB65-B7AC-4534-A595-363551111129}.Release|Any CPU.ActiveCfg = Release|Any CPU |
| | | {76BFAB65-B7AC-4534-A595-363551111129}.Release|Any CPU.Build.0 = Release|Any CPU |
| | | EndGlobalSection |
| | | GlobalSection(SolutionProperties) = preSolution |
| | | HideSolutionNode = FALSE |
New file |
| | |
| | | <Project Sdk="Microsoft.NET.Sdk"> |
| | | |
| | | <PropertyGroup> |
| | | <TargetFramework>net6.0</TargetFramework> |
| | | <ImplicitUsings>enable</ImplicitUsings> |
| | | <Nullable>enable</Nullable> |
| | | </PropertyGroup> |
| | | |
| | | </Project> |
New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace DocumentServiceApi.InitQMessage |
| | | { |
| | | /// <summary> |
| | | /// 消息结构定义 |
| | | /// </summary> |
| | | public static class INITQMessageDefine |
| | | { |
| | | /// <summary> |
| | | /// 购入Oder消息 |
| | | /// </summary> |
| | | public const string InitTentOder = "DocumentServiceAPI_OderINIT"; |
| | | } |
| | | } |
New file |
| | |
| | | using CSRedis; |
| | | using Furion; |
| | | using InitQ; |
| | | using Mapster; |
| | | using Microsoft.AspNetCore.Builder; |
| | | using Microsoft.AspNetCore.Hosting; |
| | | using Microsoft.Extensions.Configuration; |
| | | using Microsoft.Extensions.DependencyInjection; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Reflection; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace DocumentServiceApi.InitQMessage |
| | | { |
| | | /// <summary> |
| | | /// 注册 INITQ |
| | | /// </summary> |
| | | public class DocServiceApiStartup : AppStartup |
| | | { |
| | | public void ConfigureServices(IServiceCollection services) { |
| | | |
| | | |
| | | var readisconnectionstring = App.Configuration["InitQRedisConfig:ConnectionString"]; |
| | | if (readisconnectionstring != null) |
| | | //初始化redi配置 |
| | | { |
| | | services.AddInitQ((op) => |
| | | { |
| | | op.SuspendTime = 500; |
| | | op.IntervalTime = 500; |
| | | op.ConnectionString = readisconnectionstring; |
| | | op.ListSubscribe = new List<Type>() { typeof(MessageReceive) }; |
| | | op.ShowLog = false; |
| | | }); |
| | | } |
| | | |
| | | } |
| | | |
| | | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) |
| | | { |
| | | |
| | | |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | using InitQ.Abstractions; |
| | | using InitQ.Attributes; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace DocumentServiceApi.InitQMessage |
| | | { |
| | | /// <summary> |
| | | /// 消息接收处理函数 |
| | | /// </summary> |
| | | public class MessageReceive: IRedisSubscribe |
| | | { |
| | | /// <summary> |
| | | /// 初始化订单处理 |
| | | /// </summary> |
| | | /// <param name="msg"></param> |
| | | /// <returns></returns> |
| | | |
| | | [Subscribe(INITQMessageDefine.InitTentOder)] |
| | | private async Task InitTenantOder(string msg) |
| | | { |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace DocumentServiceApi.InitQMessage |
| | | { |
| | | /// <summary> |
| | | /// 订单详情 |
| | | /// </summary> |
| | | public class TenantOderInfo |
| | | { |
| | | } |
| | | } |
New file |
| | |
| | | using DocumentServiceAPI.Enum; |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.ComponentModel.DataAnnotations; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace ZcPayCore.Model |
| | | { |
| | | /// <summary> |
| | | /// 通用订单类 |
| | | /// </summary> |
| | | [Display(Name = "通用订单类 ")] |
| | | [SugarTable(TableName = "Oder", TableDescription = "通用订单类")] |
| | | public class Oder : BaseModel |
| | | { |
| | | /// <summary> |
| | | /// Id |
| | | /// </summary> |
| | | [Display(Name = "Id ")] |
| | | [SugarColumn(ColumnDescription = "Id ",IsIdentity =true,IsPrimaryKey =true)] |
| | | public int Id { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 用户ID 也可能是租户ID |
| | | /// </summary> |
| | | [Display(Name = "用户ID 也可能是租户ID ")] |
| | | [SugarColumn(ColumnDescription = "用户ID 也可能是租户ID ")] |
| | | public int UserID { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 订单详情描述 |
| | | /// </summary> |
| | | [Display(Name = "订单详情描述 ")] |
| | | [SugarColumn(ColumnDescription = "订单详情描述 ")] |
| | | public string? Description { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 其他参数 |
| | | /// </summary> |
| | | [Display(Name = "其他参数 ")] |
| | | [SugarColumn(ColumnDescription = "其他参数 ")] |
| | | public string? Param { get; set; } |
| | | |
| | | /// <summary> |
| | | /// PropertyDecName |
| | | /// </summary> |
| | | [Display(Name = "PropertyDecName ")] |
| | | [SugarColumn(ColumnDescription = "PropertyDecName ")] |
| | | public int Property { get; set; } |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | <Project Sdk="Microsoft.NET.Sdk"> |
| | | |
| | | <PropertyGroup> |
| | | <TargetFramework>net6.0</TargetFramework> |
| | | <ImplicitUsings>enable</ImplicitUsings> |
| | | <Nullable>enable</Nullable> |
| | | </PropertyGroup> |
| | | |
| | | <ItemGroup> |
| | | <PackageReference Include="Essensoft.Paylink.Alipay" Version="4.1.2" /> |
| | | <PackageReference Include="Essensoft.Paylink.Security" Version="4.1.2" /> |
| | | <PackageReference Include="Essensoft.Paylink.WeChatPay" Version="4.1.2" /> |
| | | <PackageReference Include="SqlSugarCore" Version="5.1.4.99" /> |
| | | </ItemGroup> |
| | | |
| | | <ItemGroup> |
| | | <ProjectReference Include="..\DocumentServiceAPI.Enum\DocumentServiceAPI.Enum.csproj" /> |
| | | </ItemGroup> |
| | | |
| | | </Project> |